Your pipeline uses GitLab Container Registry to store Docker images. You need to implement image tagging strategies, vulnerability scanning, garbage collection, and promotion between environments. Design the complete container lifecycle management.
Quick Answer
Tag images with commit SHA for immutability, semantic versions for releases, and environment labels for promotion. Implement container scanning in CI, use cleanup policies for untagged images, and promote by retagging (not rebuilding) when promoting across environments.
Detailed Answer
Image Tagging Strategy
Never use latest in production—it's mutable and breaks reproducibility. Use commit SHA ($CI_COMMIT_SHA or short SHA) as the primary immutable tag for every build. Add semantic version tags on release branches/tags. Add environment tags (staging, production) that are mutable pointers to the currently deployed SHA. This gives you both immutability (SHA) and human-readable references (version, environment).
Build Once, Promote Everywhere
A critical principle: build the image exactly once in CI, then promote it across environments by adding tags. Never rebuild for different environments—this ensures the exact bytes tested in staging are what runs in production. Use environment-specific configuration via ConfigMaps/Secrets, not baked into the image. The promotion step is simply: pull by SHA, tag with new environment, push.
Container Scanning Integration
GitLab's Container Scanning (powered by Trivy) runs after image build and produces a vulnerability report. Configure severity thresholds: fail the pipeline on CRITICAL/HIGH, warn on MEDIUM. The scan results appear in the merge request security widget and the project vulnerability report. For base image vulnerabilities, use multi-stage builds with distroless or Alpine base images to minimize attack surface.
Garbage Collection and Cleanup
GitLab Container Registry accumulates images rapidly in active projects. Configure cleanup policies: keep images matching semver tags indefinitely, keep last 10 images per branch, delete untagged manifests older than 7 days. For self-managed GitLab, run registry garbage collection as a cron job. Monitor registry storage to prevent disk exhaustion—a common cause of GitLab outages.
Multi-Architecture Builds
For organizations running both AMD64 and ARM64 (e.g., AWS Graviton), use Docker buildx with manifest lists to build multi-arch images. A single tag resolves to the correct architecture at pull time. This adds build time but simplifies deployment manifests.