A hands-on tutorial for versioning the Cheese App image dataset with DVC, Git, Docker, and Google Cloud Storage (GCS).
Youโll use Docker to run DVC in a consistent development environment, store the actual image files in GCS, and use Git tags to identify specific versions of the dataset.
The goal: create reproducible versions of a dataset.
You will do this in two rounds:
-
๐ ๏ธ Set up your own repository and cloud storage. Create a writable copy of the class repository, create a GCP service account, and prepare a GCS bucket.
-
๐ณ Start a DVC development container. Use Docker to run the tools and mount your GCS image folder inside the container.
-
๐ฆ Create the first dataset version. Track the original Cheese App dataset with DVC, push it to GCS, and tag it in Git as
dataset_v20. -
๐ Update the dataset and create a new version. Add images, update DVC tracking, and tag the new state as
dataset_v21.
By the end, you will be able to retrieve a specific version of the dataset instead of relying on whichever files happen to be in the bucket today.
Complete the following before starting:
- Install and start the latest version of Docker Desktop.
- Have a GCP account and project.
- Have access to a GCS bucket.
- Have Git and a GitHub account.
- Configure GitHub SSH access if you use the SSH commands below.
You need a GCP service-account key for this tutorial. Keep it private and never commit it to GitHub.
Four walkthroughs:
- Prepare Docker and create your repository
- Set up GCP storage and credentials
- Start the DVC container
- Create and view dataset versions
Step 1 of 4 โ prepare a clean local development environment. First, make sure Docker is ready. Then create your own GitHub repository, since the class repository only gives you read access.
-
Run:
docker container ls
-
Stop any container that is running.
-
Run:
docker system prune
-
Run:
docker image ls
๐ก Tip:
docker system pruneremoves unused Docker resources. Read the confirmation prompt before enteringy.
Clone the data-versioning-ac215 branch:
git clone -b data-versioning-ac215 git@github.com:dlops-io/data-versioning.git๐ก Tip: This command uses SSH. You need to add your public SSH key to GitHub first. Alternatively, you can clone with HTTPS.
Move into the project folder:
cd data-versioningRemove the existing Git metadata:
rm -rf .gitInitialize a new Git repository:
git init
โ ๏ธ Why remove.git? The cloned repository is connected to the original class repository. Removing.gitdisconnects it so you can connect the code to a repository that you own.
Create a new private repository on GitHub called data-versioning.
Do not add a README, license, or .gitignore when creating it because these files already exist locally.
Your repository URL should look like this:
git@github.com:YOUR_GITHUB_USERNAME/data-versioning.git
Connect your local project to the new repository and push it:
git branch -M main
git remote add origin git@github.com:YOUR_GITHUB_USERNAME/data-versioning.git
git add .
git commit -m "Initial commit"
git push -u origin mainStep 2 of 4 โ give the container secure access to cloud storage. You will create a service account and prepare two folders in your GCS bucket: one for dataset images and one for DVCโs versioned files.
Create a folder named secrets next to your data-versioning folder.
Your folder structure should look like this:
parent-folder/
โโโ data-versioning/
โโโ secrets/
๐ Important: Keeping
secretsoutside the repository helps prevent you from accidentally uploading credentials to GitHub.
-
Create a new service account in the GCP console named:
data-service-account -
For Service account permissions, choose:
Cloud Storage โ Storage Admin -
Click Continue, then Done.
-
In the service-account list, click the three dots (
โฎ) in the Actions column and select Manage keys. -
Select Add Key โ Create new key โ JSON.
-
Download the JSON key file.
-
Copy it into your
secretsfolder and rename it:data-service-account.json
โ ๏ธ Never commit this JSON file to GitHub. It is a private credential that grants access to your GCP resources.
Go to the GCS browser.
Inside your bucket, create these folders:
YOUR_BUCKET_NAME/
โโโ dvc_store/
โโโ images/
images/stores the Cheese App image dataset.dvc_store/stores the DVC-managed copies of each dataset version.
Step 3 of 4 โ run DVC in a consistent Docker environment. The container mounts the images in your GCS bucket into the project, so DVC can track them.
Inside your local data-versioning folder, open docker-shell.sh.
Replace the following values with your own setup:
export GCS_BUCKET_NAME="YOUR_BUCKET_NAME"
export GCP_PROJECT="YOUR_GCP_PROJECT_ID"
export GCP_ZONE="YOUR_GCP_ZONE"For example:
export GCS_BUCKET_NAME="cheese-app-data-versioning"
export GCP_PROJECT="ac215-project"
export GCP_ZONE="us-central1-a"The project includes a file named docker-entrypoint.sh.
An entrypoint script automatically runs when the container starts. It performs setup tasks that must happen every time the container runs.
For this container, it:
-
Mounts your GCS bucket inside the container.
-
Connects the bucketโs
imagesfolder to:/app/cheese_dataset
This makes the images stored in GCS available inside the container as the local cheese_dataset folder.
Make sure you are inside the data-versioning folder:
cd data-versioningStart the DVC development container:
sh docker-shell.sh๐ก Note: Run the DVC commands in the next section inside this container unless the tutorial says otherwise.
Step 4 of 4 โ use DVC and Git together to create reproducible dataset versions.
DVC and Git have different jobs:
| Tool | What it tracks |
|---|---|
| Git | Code and small DVC metadata files |
| DVC | Large dataset files |
| GCS | The remote location where DVC stores dataset versions |
Inside the container, run:
dvc initThis creates the DVC configuration files in your project.
Connect DVC to the dvc_store folder in your bucket:
dvc remote add -d cheese_dataset gs://YOUR_BUCKET_NAME/dvc_storeFor example:
dvc remote add -d cheese_dataset gs://cheese-app-data-versioning/dvc_storeTell DVC to track the dataset:
dvc add cheese_datasetDVC creates a small .dvc metadata file describing the exact state of the dataset.
Upload the DVC-tracked dataset files:
dvc pushYou can now open your GCS bucket and inspect the dvc_store folder.
๐ก Tip: The actual image files are stored in GCS. Git does not need to store these large files directly.
Run these commands outside the container, from your local data-versioning folder:
git status
git add .
git commit -m "Track initial cheese dataset with DVC"
git tag -a dataset_v20 -m "First version of cheese dataset"
git push --atomic origin main dataset_v20
โผ๏ธ Disclaimer The name-tag of the dataset might not be 'dataset_v20' for you as this tag is taken. Try with different numbers and see which might work for you for e.g. dataset_v21, dataset_v22, dataset_v23, etc. ๐ก Why tag the commit? The Git tagdataset_v20gives this exact dataset state a memorable name. Later, you can return to that version instead of guessing which data was used.
- Open the Colab Notebook.
- Follow the instructions in the notebook.
- View the dataset associated with
dataset_v20.
Now, simulate a real-world dataset update by adding new images.
Upload a few additional images to the images folder in your GCS bucket:
YOUR_BUCKET_NAME/images/
Because this folder is mounted into the container as /app/cheese_dataset, the new files will appear in the dataset directory.
Inside the container, run:
dvc add cheese_datasetPush the updated dataset to GCS:
dvc pushRun these commands outside the container:
git status
git add .
git commit -m "Add images to cheese dataset"
git tag -a dataset_v21 -m "Updated cheese dataset with additional images"
git push --atomic origin main dataset_v21
โผ๏ธ Disclaimer Again, he name-tag of the dataset might not be 'dataset_v21' for you as this tag is taken. Try with different numbers and see which might work for you for e.g. dataset_v22, dataset_v23, dataset_v24, etc.โ ๏ธ Note: You only need to rungit remote add origin ...once, when you first create your repository. Do not add it again here.
You now have two dataset versions:
| Git Tag | Dataset State |
|---|---|
dataset_v20 |
Original Cheese App image dataset |
dataset_v21 |
Dataset with additional uploaded images |
- Open the Colab Notebook.
- Follow the instructions in the notebook.
- View the dataset associated with
dataset_v21.
You used Git and DVC together to version a dataset:
- DVC tracked the dataset contents.
- GCS stored the large image files.
- Git stored the lightweight DVC metadata.
- Git tags identified meaningful dataset versions.
- Colab let you retrieve and inspect a specific version.
This workflow makes ML experiments reproducible because you can always identify exactly which dataset version was used.
When you are done, clean up Docker resources:
-
Run:
docker container ls
-
Stop any container that is running.
-
Run:
docker system prune
-
Run:
docker image ls ```# ๐ง Data Versioning with DVC
A hands-on tutorial for versioning the Cheese App image dataset with DVC, Git, Docker, and Google Cloud Storage (GCS).
Youโll use Docker to run DVC in a consistent development environment, store the actual image files in GCS, and use Git tags to identify specific versions of the dataset.
The goal: create reproducible versions of a dataset.
You will do this in two rounds:
-
๐ ๏ธ Set up your own repository and cloud storage. Create a writable copy of the class repository, create a GCP service account, and prepare a GCS bucket.
-
๐ณ Start a DVC development container. Use Docker to run the tools and mount your GCS image folder inside the container.
-
๐ฆ Create the first dataset version. Track the original Cheese App dataset with DVC, push it to GCS, and tag it in Git as
dataset_v20. -
๐ Update the dataset and create a new version. Add images, update DVC tracking, and tag the new state as
dataset_v21.
By the end, you will be able to retrieve a specific version of the dataset instead of relying on whichever files happen to be in the bucket today.
Complete the following before starting:
- Install and start the latest version of Docker Desktop.
- Have a GCP account and project.
- Have access to a GCS bucket.
- Have Git and a GitHub account.
- Configure GitHub SSH access if you use the SSH commands below.
You need a GCP service-account key for this tutorial. Keep it private and never commit it to GitHub.
Four walkthroughs:
- Prepare Docker and create your repository
- Set up GCP storage and credentials
- Start the DVC container
- Create and view dataset versions
Step 1 of 4 โ prepare a clean local development environment. First, make sure Docker is ready. Then create your own GitHub repository, since the class repository only gives you read access.
-
Run:
docker container ls
-
Stop any container that is running.
-
Run:
docker system prune
-
Run:
docker image ls
๐ก Tip:
docker system pruneremoves unused Docker resources. Read the confirmation prompt before enteringy.
Clone the data-versioning-ac215 branch:
git clone -b data-versioning-ac215 git@github.com:dlops-io/data-versioning.git๐ก Tip: This command uses SSH. You need to add your public SSH key to GitHub first. Alternatively, you can clone with HTTPS.
Move into the project folder:
cd data-versioningRemove the existing Git metadata:
rm -rf .gitInitialize a new Git repository:
git init
โ ๏ธ Why remove.git? The cloned repository is connected to the original class repository. Removing.gitdisconnects it so you can connect the code to a repository that you own.
Create a new private repository on GitHub called data-versioning.
Do not add a README, license, or .gitignore when creating it because these files already exist locally.
Your repository URL should look like this:
git@github.com:YOUR_GITHUB_USERNAME/data-versioning.git
Connect your local project to the new repository and push it:
git branch -M main
git remote add origin git@github.com:YOUR_GITHUB_USERNAME/data-versioning.git
git add .
git commit -m "Initial commit"
git push -u origin mainStep 2 of 4 โ give the container secure access to cloud storage. You will create a service account and prepare two folders in your GCS bucket: one for dataset images and one for DVCโs versioned files.
Create a folder named secrets next to your data-versioning folder.
Your folder structure should look like this:
parent-folder/
โโโ data-versioning/
โโโ secrets/
๐ Important: Keeping
secretsoutside the repository helps prevent you from accidentally uploading credentials to GitHub.
-
Open the GCP Console.
-
Search for Service Accounts, or navigate to IAM & Admin โ Service Accounts.
-
Create a new service account named:
data-service-account -
For Service account permissions, choose:
Cloud Storage โ Storage Admin -
Click Continue, then Done.
-
In the service-account list, click the three dots (
โฎ) in the Actions column and select Manage keys. -
Select Add Key โ Create new key โ JSON.
-
Download the JSON key file.
-
Copy it into your
secretsfolder and rename it:data-service-account.json
โ ๏ธ Never commit this JSON file to GitHub. It is a private credential that grants access to your GCP resources.
Go to the GCS browser.
Inside your bucket, create these folders:
YOUR_BUCKET_NAME/
โโโ dvc_store/
โโโ images/
images/stores the Cheese App image dataset.dvc_store/stores the DVC-managed copies of each dataset version.
Step 3 of 4 โ run DVC in a consistent Docker environment. The container mounts the images in your GCS bucket into the project, so DVC can track them.
Inside your local data-versioning folder, open docker-shell.sh.
Replace the following values with your own setup:
export GCS_BUCKET_NAME="YOUR_BUCKET_NAME"
export GCP_PROJECT="YOUR_GCP_PROJECT_ID"
export GCP_ZONE="YOUR_GCP_ZONE"For example:
export GCS_BUCKET_NAME="cheese-app-data-versioning"
export GCP_PROJECT="ac215-project"
export GCP_ZONE="us-central1-a"The project includes a file named docker-entrypoint.sh.
An entrypoint script automatically runs when the container starts. It performs setup tasks that must happen every time the container runs.
For this container, it:
-
Mounts your GCS bucket inside the container.
-
Connects the bucketโs
imagesfolder to:/app/cheese_dataset
This makes the images stored in GCS available inside the container as the local cheese_dataset folder.
Make sure you are inside the data-versioning folder:
cd data-versioningStart the DVC development container:
sh docker-shell.sh๐ก Note: Run the DVC commands in the next section inside this container unless the tutorial says otherwise.
Step 4 of 4 โ use DVC and Git together to create reproducible dataset versions.
DVC and Git have different jobs:
| Tool | What it tracks |
|---|---|
| Git | Code and small DVC metadata files |
| DVC | Large dataset files |
| GCS | The remote location where DVC stores dataset versions |
Inside the container, run:
dvc initThis creates the DVC configuration files in your project.
Connect DVC to the dvc_store folder in your bucket:
dvc remote add -d cheese_dataset gs://YOUR_BUCKET_NAME/dvc_storeFor example:
dvc remote add -d cheese_dataset gs://cheese-app-data-versioning/dvc_storeTell DVC to track the dataset:
dvc add cheese_datasetDVC creates a small .dvc metadata file describing the exact state of the dataset.
Upload the DVC-tracked dataset files:
dvc pushYou can now open your GCS bucket and inspect the dvc_store folder.
๐ก Tip: The actual image files are stored in GCS. Git does not need to store these large files directly.
Run these commands outside the container, from your local data-versioning folder:
git status
git add .
git commit -m "Track initial cheese dataset with DVC"
git tag -a dataset_v20 -m "First version of cheese dataset"
git push --atomic origin main dataset_v20๐ก Why tag the commit? The Git tag
dataset_v20gives this exact dataset state a memorable name. Later, you can return to that version instead of guessing which data was used.
- Open the Colab Notebook.
- Follow the instructions in the notebook.
- View the dataset associated with
dataset_v20.
Now, simulate a real-world dataset update by adding new images.
Upload a few additional images to the images folder in your GCS bucket:
YOUR_BUCKET_NAME/images/
Because this folder is mounted into the container as /app/cheese_dataset, the new files will appear in the dataset directory.
Inside the container, run:
dvc add cheese_datasetPush the updated dataset to GCS:
dvc pushRun these commands outside the container:
git status
git add .
git commit -m "Add images to cheese dataset"
git tag -a dataset_v21 -m "Updated cheese dataset with additional images"
git push --atomic origin main dataset_v21
โ ๏ธ Note: You only need to rungit remote add origin ...once, when you first create your repository. Do not add it again here.
You now have two dataset versions:
| Git Tag | Dataset State |
|---|---|
dataset_v20 |
Original Cheese App image dataset |
dataset_v21 |
Dataset with additional uploaded images |
- Open the Colab Notebook.
- Follow the instructions in the notebook.
- View the dataset associated with
dataset_v21.
You used Git and DVC together to version a dataset:
- DVC tracked the dataset contents.
- GCS stored the large image files.
- Git stored the lightweight DVC metadata.
- Git tags identified meaningful dataset versions.
- Colab let you retrieve and inspect a specific version.
This workflow makes ML experiments reproducible because you can always identify exactly which dataset version was used.
When you are done, clean up Docker resources:
-
Run:
docker container ls
-
Stop any container that is running.
-
Run:
docker system prune
-
Run:
docker image ls