Container Registry: Image Storage, Scanning, and Distribution
Set up and secure container registries for storing, scanning, and distributing container images across your CI/CD pipeline and clusters.
Introduction
When registries make sense
A container registry is essential when you are building and deploying containerized applications. If your CI/CD pipeline produces Docker images, you need somewhere to store them between the build step and the deployment step. Even for small projects, a registry gives you a versioned history of your images that you cannot get from local Docker storage.
Use a registry when you need image promotion between environments. An image built once in the CI pipeline should flow from dev to staging to production without rebuilding. The registry holds the canonical artifact at each stage.
For teams with multiple services, a shared registry lets different pipelines pull base images and intermediate layers without repeatedly downloading from public sources. This speeds up builds and reduces external dependencies.
When to skip or simplify
If your application is not containerized and never will be, a container registry does not add value. Some projects are better served by plain artifact storage (S3, GCS) for JARs, binaries, or Helm charts.
For personal projects or experiments that never leave your local machine, running a local registry or skipping one entirely makes sense. You can always add a registry later when the project grows.
Registry Architecture Flow
flowchart LR
A[Developer] -->|docker build| B[CI Pipeline]
B -->|docker push| C[Container Registry]
C -->|docker pull| D[Staging Cluster]
C -->|docker pull| E[Production Cluster]
F[Scanner] -->|periodic scan| C
Registry Options
Cloud-provider registries:
| Provider | Service | Notes |
|---|---|---|
| AWS | ECR | Integrated with IAM, VPC endpoints |
| Azure | ACR | Geo-replication, webhook integration |
| GCP | GCR | Integrated with Cloud Build, IAM |
| Artifact Registry | Successor to GCR, multi-format |
Self-hosted options:
| Registry | Best For |
|---|---|
| Harbor | Enterprise with authentication, replication |
| GitLab Container Registry | GitLab-integrated deployments |
| Docker Hub | Public images, simple needs |
| ChartMuseum | Helm charts alongside images |
AWS ECR example:
# Create ECR repository
aws ecr create-repository \
--repository-name myapp/backend \
--image-scanning-configuration scanOnPush=true \
--encryption-configuration encryptionType=AES256
# Login to ECR
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin 123456789.dkr.ecr.us-east-1.amazonaws.com
# Push image
docker build -t myapp/backend:1.0.0 .
docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/myapp/backend:1.0.0
Azure ACR example:
# Create ACR
az acr create \
--resource-group mygroup \
--name myregistry \
--sku Standard \
--location eastus
# Enable admin user
az acr update -n myregistry --admin-enabled true
# Login and push
az acr login --name myregistry
docker build -t myregistry.azurecr.io/myapp:1.0.0 .
docker push myregistry.azurecr.io/myapp:1.0.0
Image Tagging Strategies
Tags identify image versions and control which code deploys where.
Common tagging patterns:
| Pattern | Example | Use Case |
|---|---|---|
| Git SHA | a1b2c3d | Precise traceability |
| Semantic version | 1.2.3 | Releases |
| Date-time | 202603251430 | CI/CD timestamps |
latest | latest | Default, avoid for prod |
| Environment | prod, staging | Environment promotion |
Recommended strategy for production:
# Always tag with multiple identifiers
IMAGE="myregistry.azurecr.io/myapp/backend"
# SHA for exact traceability
docker build -t $IMAGE:sha-$(git rev-parse --short HEAD)
# Semantic version from tag
docker build -t $IMAGE:$(cat VERSION)
# Date-time for CI builds
docker build -t $IMAGE:$(date +%Y%m%d%H%M%S)
# Don't use :latest in production manifests
# Instead:
kubectl set image deployment/myapp backend=$IMAGE:sha-a1b2c3d
Immutable tags for releases:
# Helm values for production deployment
image:
repository: myregistry.azurecr.io/myapp/backend
tag: "v1.2.3" # Immutable once released
pullPolicy: IfNotPresent # Only pulls if not present
Vulnerability Scanning
Integrate scanning into your pipeline to catch vulnerabilities before deployment.
Trivy in CI/CD:
# GitHub Actions
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: myregistry.azurecr.io/myapp:${{ github.sha }}
format: "sarif"
output: "trivy-results.sarif"
severity: "CRITICAL,HIGH"
exit-code: "1" # Fail on critical vulnerabilities
- name: Upload Trivy results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: "trivy-results.sarif"
Harbor scanning:
Harbor integrates Trivy and other scanners natively. Configure in /etc/harbor/harbor.yml:
# Enable CVE prevention
vulnerability:
severity: # Reject push if severity >= this level
- high
- critical
stop_uploading: true
stop_downloading: true
update_bulk: "1h"
Gatekeeper policy:
# OPA Gatekeeper constraint for image signatures
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredImageTag
metadata:
name: require-tag
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
parameters:
namespaces: ["production"]
exemptImages:
- "myregistry.azurecr.io/base-image:*"
Image Promotion Between Environments
Promote images through environments with validation at each stage.
GitLab CI image promotion:
stages:
- build
- scan
- staging
- production
build:
stage: build
script:
- docker build -t $IMAGE:build-$CI_COMMIT_SHA .
- docker push $IMAGE:build-$CI_COMMIT_SHA
scan:
stage: scan
script:
- trivy image --exit-code 1 --severity HIGH,CRITICAL $IMAGE:build-$CI_COMMIT_SHA
allow_failure: false
promote:staging:
stage: staging
script:
- docker tag $IMAGE:build-$CI_COMMIT_SHA $IMAGE:staging-$CI_COMMIT_SHA
- docker push $IMAGE:staging-$CI_COMMIT_SHA
- curl -X POST "https://argo.example.com/api/v1/apps/myapp/sync" \
-d '{"prune":true,"dryRun":false}'
only:
- main
promote:production:
stage: production
script:
- docker tag $IMAGE:build-$CI_COMMIT_SHA $IMAGE:production-$CI_COMMIT_SHA
- docker push $IMAGE:production-$CI_COMMIT_SHA
- # Update deployment manifests or trigger ArgoCD
when: manual
only:
- main
Digest-based promotion for immutability:
# Get image digest
DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' myregistry.azurecr.io/myapp:1.0.0)
echo $DIGEST
# Output: myregistry.azurecr.io/myapp@sha256:abc123...
# Deploy by digest (immutable)
docker run myregistry.azurecr.io/myapp@sha256:abc123...
Registry Caching for Faster Builds
Cache images to reduce build times and external dependencies.
GitHub Actions cache for Docker:
- uses: docker/setup-buildx-action@v3
with:
driver-opts: |
image=moby/buildkit:buildx-stable
network=host
- uses: docker/build-push-action@v5
with:
push: true
tags: myregistry.azurecr.io/myapp:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
Registry mirror for air-gapped environments:
# Deploy a pull-through cache
helm install registry-cache stable/docker-registry \
--set pullThrough.enabled=true \
--set cache.remoteURL=https://registry-1.docker.io
# Configure Docker daemon on nodes
# /etc/docker/daemon.json
{
"registry-mirrors": ["https://cache.mycorp.example.com"]
}
Access Control and Authentication
Control who can push, pull, and manage images.
AWS ECR IAM policies:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789:role/deploy-role"
},
"Action": [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:BatchCheckLayerAvailability"
]
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789:role/ci-service-account"
},
"Action": ["ecr:*"]
}
]
}
Azure RBAC for ACR:
# Reader role for production pods
az role assignment create \
--assignee-object-id $(kubectl get serviceaccount default -n production -o jsonpath='{.metadata.uid}') \
--role AcrPull \
--scope /subscriptions/.../resourceGroups/mygroup/providers/Microsoft.ContainerRegistry/registries/myregistry
# Contributor for CI/CD pipelines
az role assignment create \
--assignee $CI_SERVICE_PRINCIPAL_ID \
--role Contributor \
--scope /subscriptions/.../resourceGroups/mygroup/providers/Microsoft.ContainerRegistry/registries/myregistry
Kubernetes image pull secrets:
# Create image pull secret
kubectl create secret docker-registry acr-secret \
--docker-server=myregistry.azurecr.io \
--docker-username=myuser \
--docker-password=$(az keyvault secret show --name acr-password --vault-name myvault -o tsv --query value) \
--docker-email=myuser@example.com
# Reference in service account
apiVersion: v1
kind: ServiceAccount
metadata:
name: myapp-sa
namespace: production
imagePullSecrets:
- name: acr-secret
Production Failure Scenarios
Common Registry Failures
| Failure | Impact | Mitigation |
|---|---|---|
| Registry authentication token expired | Cannot pull or push images, deployments fail | Use service accounts with rotating credentials |
| Image not found after tag deletion | Deployment tries to pull deleted image | Never delete tags in production, use immutable tags |
| Quota exceeded on cloud registry | Cannot push new images | Monitor storage usage, set lifecycle policies |
| Network partition to registry | Builds cannot push, deployments cannot pull | Use multi-region replication, local registry cache |
| Vulnerability scan blocking deploys | Critical CVE stops production deployment | Define triage process for CVEs, do not scan blindly |
Image Pull Failures
flowchart TD
A[Pod Schedule] --> B{Pull Image}
B -->|Success| C[Pod Starts]
B -->|Fail| D{Error Type}
D -->|Image Not Found| E[Check tag exists in registry]
D -->|Auth Failed| F[Refresh pull secret]
D -->|Quota Exceeded| G[Delete old images]
E --> H[Redeploy]
F --> H
G --> H
Observability Hooks
What to monitor:
- Image push success/failure rate
- Pull request latency by region
- Storage consumption growth rate
- Vulnerability scan results trend
- Authentication failure spikes
# AWS ECR - check repository size
aws ecr describe-repositories --query 'repositories[].{name:repositoryName,size:imageScanningConfiguration.scanOnPush}'
# Azure ACR - check usage
az acr show-usage --name myregistry
# Docker Hub - check rate limits
curl -s -o /dev/null -w "%{http_code}" https://hub.docker.com/v2/
Common Pitfalls / Anti-Patterns
Using the :latest tag in production manifests
When your manifest references myapp:latest, you have no idea which image actually deployed. If you need to roll back, you cannot because :latest keeps changing. Always use specific immutable tags (commit SHA, semantic version, or date-based).
Not scanning images before deployment
Pushing unscanned images to production means you discover vulnerabilities after they are running. Integrate Trivy or similar scanners into your CI pipeline and block pushes when critical CVEs are found.
Leaving unused images in the registry
Old images accumulate and consume storage. Without lifecycle policies, your registry bill grows while nobody knows which images are actually in use. Set up retention policies that delete images not referenced by any deployment.
Mixing image sources in one pipeline
Using Docker Hub for base images, your private registry for app images, and a third-party registry for dependencies makes it hard to track where each piece comes from. Keep a clear lineage from build to registry to deployment.
Forgetting about cross-region replication
If your production cluster is in us-west-2 but your registry is only in us-east-1, every image pull crosses the country. Configure replication for the regions where your clusters run.
Trade-off Analysis
| Registry | Hosted vs Self-Hosted | Auth | Cost | Best For |
|---|---|---|---|---|
| Docker Hub | Both | Docker Auth | Free tier / paid | Open source images |
| ECR | Cloud-hosted | IAM | Pay per storage + egress | AWS workloads |
| GCR / Artifact Registry | Cloud-hosted | IAM + VMDF | Pay per storage + egress | GCP workloads |
| ACR | Cloud-hosted | IAM + admin keys | Pay per storage + egress | Azure workloads |
| Harbor | Self-hosted | OIDC, LDAP, local | Infrastructure cost | Enterprise / air-gapped |
| GitHub Packages | Cloud-hosted | GitHub token | Storage + bandwidth | GitHub-native workflows |
| GitLab Container Registry | Cloud-hosted | GitLab token | Storage + bandwidth | GitLab-native workflows |
Interview Questions
ECR (AWS): native IAM integration, VPC endpoints for private networking, pay per storage and egress. ACR (Azure): geo-replication, webhook integration, admin user option. GCR/Artifact Registry (GCP): integrated with Cloud Build, IAM with VM metadata service. Harbor (self-hosted): enterprise-grade with OIDC/LDAP auth, replication across registries, CVE scanning. ECR/ACR/GCR are cloud-hosted managed services — no infrastructure to manage, automatic scaling. Harbor is self-hosted — full control but requires maintenance. Choose based on cloud provider, authentication integration needs, and whether you need self-hosted vs cloud-hosted.
Immutable tagging strategy: 1) Never use :latest in production manifests — it changes and you lose traceability, 2) Use commit SHA tags: :sha-{git rev-parse --short HEAD} for exact traceability from code to image, 3) Use semantic version tags: :v1.2.3 for releases with clear versioning, 4) Use date-time tags: :202603251430 for CI builds that need uniqueness, 5) Tag with multiple identifiers: production image gets :v1.2.3, :sha-abc123, and environment tag, 6) Set imagePullPolicy: IfNotPresent to avoid unexpected pulls. Immutable tags mean once a tag is released, it never changes — same SHA always points to same content.
Vulnerability scanning integration: 1) Use Trivy or similar scanner in CI pipeline after build and push, 2) Configure scanOnPush=true for automatic scanning on every image push, 3) Set severity thresholds — block deployment on CRITICAL vulnerabilities, warn on HIGH, 4) In GitHub Actions: use aquasecurity/trivy-action with exit-code to fail pipeline, 5) Upload results to security dashboard (GitHub Security tab, security hub), 6) For Harbor, enable CVE prevention in configuration — reject pushes when severity exceeds threshold, 7) Set up periodic rescanning of existing images for new CVEs, 8) Define triage process for handling exceptions when scanning blocks legitimate builds.
Cross-region replication strategy: 1) Most cloud registries support geo-replication — enable it to replicate images across regions automatically, 2) For multi-region Kubernetes clusters, deploy images to registry regions closest to your clusters, 3) Use pull-through cache for air-gapped or remote regions — cache images locally, 4) Configure replication rules based on tags or repositories, 5) Monitor replication lag and failure rates, 6) For Harbor, use the replication feature to push to multiple Harbor instances, 7) Consider using a global DNS that routes to nearest registry region. Unreplicated registries cause image pull latency and potential availability issues if a region fails.
Digest vs tag references: Tags are mutable — myapp:v1.2.3 can be overwritten to point to different content. Digests are immutable — myapp@sha256:abc123 always points to exactly that image content. Digest references provide true immutability — you know exactly what code is running. Use digest references in production for cryptographic certainty. Workflow: after building, inspect digest with docker inspect --format='{{index .RepoDigests 0}}', then deploy using digest. Tags are more human-readable for development and staging. Best practice: use tags for development, digest for production deployments.
Registry access control implementation: 1) Use cloud IAM roles for AWS ECR, Azure RBAC for ACR, GCP IAM for GCR — not shared passwords, 2) CI/CD pipelines get service account credentials via OIDC federation or workload identity — no long-lived secrets, 3) Production pods use image pull secrets with minimal permissions — only pull, not push, 4) Separate credentials for different environments — staging pipeline pushes to staging repo, production pipeline pushes to production repo, 5) Use least privilege: deploy role can only pull images, ci-service-account can push to specific repos, 6) Rotate credentials regularly. Kubernetes imagePullSecrets reference registry credentials stored as Kubernetes secrets.
Image build and pull optimization: 1) Multi-stage builds — final image contains only runtime, not build tools, 2) Use slim or alpine base images to reduce size, 3) Leverage Docker layer caching — structure Dockerfile so unchanged layers are cached, 4) In CI, use cache-from and cache-to with buildx for layer caching across builds, 5) Use registry caching for dependencies — cache npm packages, Maven artifacts during build, 6) Pre-pull base images on nodes to avoid pull latency during deployment, 7) Use GitHub Actions cache for buildx, 8) For air-gapped environments, set up pull-through cache that mirrors required images. Smaller images = faster pulls, better caching = faster builds.
Image lifecycle management: 1) Set retention policies that delete untagged images after N days, 2) Never delete tags in production — use immutable tags that are never overwritten, 3) Monitor storage growth rate and set alerts for unusual increases, 4) Use lifecycle policies based on tag patterns — keep release tags, prune CI build tags, 5) Implement cleanup for image promotion — after promoting from staging to production, delete staging tag or use automated cleanup jobs, 6) For ECR, use lifecycle policies with rule priority — stop images older than 90 days, 7) Regular audit of which images are actually in use vs just stored. Registry bloat increases costs and slows down registry operations.
Image signing implementation with Cosign: 1) Sign images after push using cosign sign command with key or workload identity, 2) Store signatures in Sigstore transparency log (rekor) for auditing, 3) In Kubernetes, use OPA Gatekeeper or Kyverno admission controllers to verify signatures before allowing image pulls, 4) Configure image policy that requires all production images to be signed by specific keys, 5) Use attestation to attach metadata (SBOMs, test results) to images, 6) Verify signatures with cosign verify before deployment. Sigstore cosign provides keyless signing via OIDC — no managing signing keys manually.
Image pull secret failures: 1) Pods cannot start — ImagePullBackOff with "invalid secret" error, 2) Deployment fails silently if only some replicas fail, 3) Rotating credentials requires updating Kubernetes secrets and restarting pods, 4) If using Azure admin credentials, rotation invalidates stored password. Prevention: use short-lived credentials via workload identity instead of static secrets, implement automated rotation before expiry, monitor authentication failure metrics, have runbooks for secret refresh. In ECR, use ECR credentials helper that automatically fetches short-lived tokens. In ACR, use azure-workload-identity federation to avoid secrets entirely.
Image promotion pipeline design: 1) Build once in CI — tag with commit SHA and build number, 2) Push to dev registry with dev tag, 3) Run automated tests against dev image — vulnerability scan, integration tests, 4) On success, promote to staging registry — retag with staging prefix, 5) Run E2E tests and smoke tests in staging environment, 6) On approval, promote to production — retag with production tag, use digest reference for immutable reference, 7) Track promotion history in metadata — which commit, which tests passed, who approved. Digest-based promotion ensures immutability — production always references exact SHA that passed tests.
Pull-through cache: a local registry that proxies and caches images from upstream registries. Use when: you have air-gapped environments that cannot reach Docker Hub directly, you want to reduce external dependencies in CI, you have slow or unreliable internet connectivity, you want to cache base images for faster builds. Harbor and Docker Registry support pull-through cache mode. Configure nodes to use the cache as their only registry mirror. Cache automatically downloads images on first pull and serves from cache thereafter. For air-gapped Kubernetes, deploy a pull-through cache on the same network as your cluster.
Quota exceeded handling: 1) Monitor storage usage and set alerts before hitting limits, 2) Implement lifecycle policies to auto-delete old/unused images before quota is reached, 3) When quota is exceeded: delete old images, especially untagged (dangling) images, 4) Compress existing images if possible — not usually applicable since images are already compressed, 5) For ongoing prevention: implement retention policies, audit for unused images regularly, use smaller base images. Cloud providers have storage quotas and API rate limits — track both and implement cleanup before hitting limits. Emergency fix: manually delete images via cloud console or CLI.
Docker Hub vs private registry considerations: Docker Hub has rate limits on pulls (anonymous: 100/6 hours, authenticated: 200/6 hours) that can block production deployments. Use private registries when: you hit rate limits, you need to scan images for CVEs before use, you want control over image availability and uptime, you need audit trail of who pulls which images. Private registries also provide better integration with CI/CD and Kubernetes. Public images from Docker Hub may have supply chain risks — base images could be compromised. Best practice: use private registry for all production workloads, use Docker Hub only for getting base images during build, then push to your private registry.
Image pull troubleshooting: 1) Check pod status — ImagePullBackOff indicates auth failures, ErrImageNotFound indicates missing tag, 2) Verify image tag exists in registry: docker manifest inspect, 3) For auth failures: check imagePullSecret is correct, secret hasn't expired, service account has correct secret reference, 4) For network issues: can node reach registry? check DNS resolution, firewall rules, 5) For quota issues: check storage limits, 6) Use kubectl describe pod for detailed events, kubectl logs for container startup logs, 7) Verify imagePullPolicy — Always pulls every time, IfNotPresent uses cached. Common fixes: update image tag to correct version, create image pull secret correctly, add network policies to allow registry access.
Harbor enterprise features: 1) Authentication via OIDC/LDAP for enterprise identity integration, 2) Replication across multiple Harbor instances or to cloud registries for disaster recovery, 3) Vulnerability scanning with Trivy integrated natively, 4) CVE prevention — block pushes with severity above threshold, 5) Content signing with Notary for image trust, 6) Role-based access control — different permissions for developers vs production, 7) Registry mirroring for air-gapped environments. Use Harbor when you need central management of container images across multiple teams and environments, with enterprise auth and governance requirements.
Registry webhook automation: 1) Configure webhooks on push, pull, delete events, 2) Trigger CI/CD pipelines on image push — automatically run tests and promote images, 3) Notify Slack/Teams on security findings or quota warnings, 4) Trigger vulnerability scanning workflows on new image pushes, 5) Integrate with ArgoCD/Flux to update deployments when new image version is available. Most registries support webhook configuration: ACR webhooks, ECR event notification via SNS/SQS, Harbor webhook. Use webhook relays if internal services cannot be reached directly from registry.
Egress cost reduction: 1) Deploy registry in same region as your clusters — images stay within same region, no egress charges, 2) Use registry replication to have images close to all clusters, 3) Implement pull-through caching so images are cached at edge locations near clusters, 4) Use smaller base images to reduce data transferred, 5) Limit unnecessary pulls — configure proper imagePullPolicy (IfNotPresent), 6) Audit who is pulling what and from where — identify unexpected cross-region pulls, 7) Consider registry egress pricing when selecting cloud provider for multi-cloud strategies. Egress can be significant at scale — monitor and optimize.
Image traceability implementation: 1) Tag images with git commit SHA — provides exact link to source code, 2) Store build metadata — who built, when, what source commit, what tests passed, 3) Use SBOM (Software Bill of Materials) attestation to attach provenance, 4) Implement digest references in production — exact SHA ensures you know what runs, 5) Log image references in deployment records, 6) Use image signing (Cosign) to cryptographically verify image origin, 7) In Kubernetes, annotate pods with image digest for audit. This creates audit trail from code commit → build → image → deployment.
Scanning vs signing: Container scanning analyzes images for known vulnerabilities (CVEs) — static analysis of image contents. Signing cryptographically verifies image identity and provenance — who built it, that it wasn't tampered with. Use scanning to catch security vulnerabilities before deployment — integrate into CI to block vulnerable images. Use signing to ensure you're running what you think you're running — prevents supply chain attacks where images are replaced or modified. Best practice: implement both — scan for vulnerabilities, sign for trust. Tools: Trivy/Clair for scanning, Cosign/Notary for signing.
Further Reading
Official Documentation
- Docker Registry Documentation - Self-hosted registry setup
- Harbor Documentation - Enterprise registry with replication
- AWS ECR Documentation - Cloud-native image registry
- Azure ACR Documentation - Container registry on Azure
Related Guides
- CI/CD Pipeline Design - Pipeline architecture patterns
- Deployment Strategies - Deployment patterns and rollout strategies
- Automated Testing in CI/CD - Testing strategies and quality gates
Tools and References
- Trivy - Vulnerability scanner for containers
- Clair - Static vulnerability analysis for containers
- Cosign - Container image signing and verification
- OPA Gatekeeper - Policy enforcement for Kubernetes
Conclusion
Key Takeaways
- Use specific immutable tags (SHA, semver) instead of
:latestin production - Integrate vulnerability scanning into CI to catch CVEs before deployment
- Configure access control through cloud IAM, not shared passwords
- Set up registry replication for multi-region deployments
- Monitor push/pull success rates, storage growth, and scan results
Registry Health Checklist
# Verify you can pull your production image
docker pull myregistry.azurecr.io/myapp:prod && echo "Pull successful"
# Check for critical CVEs before deploying
trivy image --severity CRITICAL,HIGH myregistry.azurecr.io/myapp:v1.2.3
# List unused images (older than 90 days)
aws ecr list-images --repository-name myapp --filter '{"tagStatus": "UNTAGGED"}'
# Verify pull secret works in Kubernetes
kubectl get secret acr-secret --output jsonpath='{.data.\.dockerconfigjson}' | base64 -d Category
Related Posts
Container Images: Building, Optimizing, and Distributing
Learn how Docker container images work, layer caching strategies, image optimization techniques, and how to publish your own images to container registries.
Docker Networking: From Bridge to Overlay
Master Docker's networking models—bridge, host, overlay, and macvlan—for connecting containers across hosts and distributed applications.
Docker Fundamentals
Learn Docker containerization fundamentals: images, containers, volumes, networking, and best practices for building and deploying applications.