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 main 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.
Run this in your terminal:
git clone -b main https://github.com/dlops-io/data-versioning.gitThen enter the folder:
cd data-versioningThis uses HTTPS instead of SSH, so you donโt need an SSH key.
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
Or, if you are using HTTPS, use this instead:
git remote set-url origin https://github.com/raima2001/data-versioning.gitin the next incoming steps.
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.
Before we start the docker container, make sure to upload some pictures in the images folder in your GCS Bucket folder in order to see the changes in your dataset versions
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