Overview and What You Will Learn
In this lab, you will create an Artifact Registry repository, build and push a container image to it directly from source using Cloud Build, and configure a cleanup policy to automatically remove old image versions before storage cost accumulates unnoticed.
Why This Matters in Production
A team pushes a new container image on every single commit for over a year, never once cleaning up old versions, and a routine cost review discovers the registry has quietly accumulated thousands of unused image versions nobody will ever pull again. Artifact Registry's cleanup policies exist specifically to prevent this exact silent accumulation.
Core Principles
Artifact Registry is Google Cloud's current, unified package and container image storage service - the successor to the older Container Registry, extended to also handle language packages (like npm, Maven, and Python packages), not just container images.
+------------------------------------------+| Artifact Registry Repository || (regional or multi-regional) |+------------------------------------------+ | v+------------------------------------------+| Container images, npm packages, Maven || artifacts, Python packages - all in one || unified service |+------------------------------------------+ | v+------------------------------------------+| Pulled by Compute Engine, GKE, Cloud Run, || or Cloud Functions during deployment |+------------------------------------------+Detailed Step-by-Step Practical Lab
- Create a project and enable the necessary APIs:
gcloud projects create gcp-registry-lab-2026 --name="Artifact Registry Lab"gcloud config set project gcp-registry-lab-2026gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com- Create a Docker-format repository:
gcloud artifacts repositories create app-images \ --repository-format=docker \ --location=asia-south1 \ --description="Container images for application services"- Configure Docker authentication to this repository:
gcloud auth configure-docker asia-south1-docker.pkg.dev- Build and push an image directly using Cloud Build, with no local Docker installation needed:
gcloud builds submit \ --tag asia-south1-docker.pkg.dev/gcp-registry-lab-2026/app-images/checkout-service:v1 .- List images in the repository to confirm the push succeeded:
gcloud artifacts docker images list \ asia-south1-docker.pkg.dev/gcp-registry-lab-2026/app-images- Build and push a second version, simulating an ongoing development cycle:
gcloud builds submit \ --tag asia-south1-docker.pkg.dev/gcp-registry-lab-2026/app-images/checkout-service:v2 .- Configure a cleanup policy that automatically deletes untagged images older than 30 days, preventing indefinite accumulation:
cat > cleanup-policy.yaml << 'CLEANUPEOF'- id: delete-old-untagged action: type: Delete condition: tagState: untagged olderThan: 30dCLEANUPEOF gcloud artifacts repositories set-cleanup-policies app-images \ --location=asia-south1 \ --policy=cleanup-policy.yamlNoteThis cleanup policy specifically targets untagged images - ones that exist in the repository but aren't referenced by any tag anymore, typically the byproduct of repeated builds pushing to the same tag. Tagged, actively-referenced images are left untouched regardless of age.
- Clean up the lab itself:
gcloud artifacts repositories delete app-images --location=asia-south1 --quietgcloud projects delete gcp-registry-lab-2026 --quietProduction Best Practices & Common Pitfalls
Common MistakePushing a new image on every commit indefinitely with no cleanup policy configured, letting storage cost accumulate silently from thousands of old, unused image versions nobody will ever pull again. A cleanup policy configured once continues working automatically going forward.
TipUse immutable tags (like a git commit SHA) for every build rather than repeatedly overwriting a single tag like
latest. This makes exactly which image version is running in production always traceable, and makes a cleanup policy targeting untagged images meaningfully safer, since nothing important is ever truly "untagged."
- Artifact Registry replaced the older Container Registry as Google's current recommendation - new projects should default to Artifact Registry, which also supports multiple package formats beyond just container images in one unified service.
- Repository location affects both latency and cost. A regional repository colocated with the Compute Engine, GKE, or Cloud Run resources that pull from it reduces image pull latency during deployments compared to a repository in a distant region.
Quick Reference & Troubleshooting Commands
| Command | Description |
|---|---|
gcloud artifacts repositories create |
Create a new Artifact Registry repository |
gcloud builds submit --tag |
Build and push an image using Cloud Build |
gcloud artifacts docker images list |
List images in a repository |
gcloud artifacts repositories set-cleanup-policies |
Configure automatic old-image cleanup |