How to Push Image to Registry
How to Push Image to Registry Pushing a Docker image to a registry is a fundamental operation in modern software development and DevOps workflows. Whether you're deploying applications to cloud platforms, managing containerized microservices, or automating CI/CD pipelines, the ability to securely and efficiently push images to a registry ensures consistency, scalability, and reproducibility across
How to Push Image to Registry
Pushing a Docker image to a registry is a fundamental operation in modern software development and DevOps workflows. Whether you're deploying applications to cloud platforms, managing containerized microservices, or automating CI/CD pipelines, the ability to securely and efficiently push images to a registry ensures consistency, scalability, and reproducibility across environments. This tutorial provides a comprehensive, step-by-step guide to pushing Docker images to registries—covering public platforms like Docker Hub and private solutions like Amazon ECR, Google Container Registry, and Azure Container Registry. You’ll learn not only the mechanics of the process but also the underlying concepts, best practices, and real-world use cases that make this skill indispensable for developers and infrastructure engineers alike.
The registry serves as the central repository for container images—acting as the distribution layer between build and deployment stages. Without a properly configured push mechanism, even the most meticulously built images remain isolated on a developer’s machine, rendering containerization benefits useless in production. Understanding how to push images correctly not only streamlines deployment but also enhances security, version control, and collaboration across teams.
This guide assumes no prior expertise in container registries but expects basic familiarity with Docker CLI and terminal environments. By the end, you’ll be equipped to push images to any major registry with confidence, troubleshoot common issues, and implement industry-standard practices that align with enterprise security and compliance requirements.
Step-by-Step Guide
Prerequisites
Before pushing an image to a registry, ensure you have the following components properly configured:
- Docker installed on your local machine or build environment. Verify this by running
docker --versionin your terminal. - A Docker image built locally. If you haven’t built one yet, create a simple Dockerfile and run
docker build -t your-image-name:tag .. - Access to a registry. This could be Docker Hub (public), or a private registry such as Amazon ECR, Google Container Registry (GCR), Azure Container Registry (ACR), or Harbor.
- Authentication credentials for the registry. Most registries require login via CLI or API token before pushing.
It’s critical that your image is tagged correctly before pushing. Docker uses the format registry-domain/namespace/image-name:tag. For example, pushing to Docker Hub requires a tag like username/myapp:v1.0, while Amazon ECR requires the full registry URL: 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:v1.0.
Step 1: Build Your Docker Image
Start by creating a Dockerfile in your project directory. A minimal example:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Save this file as Dockerfile in your project root. Then, build the image using the Docker CLI:
docker build -t myapp:latest .
The -t flag assigns a tag to the image. The . at the end tells Docker to use the current directory as the build context. After execution, verify the image was created by running:
docker images
You should see your image listed with the repository name, tag, and image ID.
Step 2: Log In to the Registry
Each registry requires authentication before you can push images. The login process varies slightly depending on the provider.
Docker Hub
If you’re using Docker Hub, log in using:
docker login
This prompts you to enter your Docker Hub username and password (or personal access token for accounts with 2FA enabled). Once authenticated, Docker stores your credentials in ~/.docker/config.json.
Amazon ECR (Elastic Container Registry)
Amazon ECR requires authentication via AWS CLI. First, ensure the AWS CLI is installed and configured with appropriate IAM permissions:
aws configure
Then, generate a login token and authenticate Docker:
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com
Replace us-east-1 and the account ID with your region and AWS account number. This command retrieves a temporary token and passes it to Docker for authentication.
Google Container Registry (GCR)
For GCR, authenticate using the Google Cloud SDK:
gcloud auth configure-docker gcr.io
This configures Docker to use your Google Cloud credentials for GCR access. Ensure you’ve authenticated with gcloud auth login and have the correct project set via gcloud config set project your-project-id.
Azure Container Registry (ACR)
Azure requires login via the Azure CLI:
az login
az acr login --name your-registry-name
Ensure your user has the AcrPush role assigned to the registry. You can assign it via Azure Portal or CLI:
az role assignment create --assignee your-email@example.com --role AcrPush --scope /subscriptions/your-subscription-id/resourceGroups/your-rg/providers/Microsoft.ContainerRegistry/registries/your-registry-name
Step 3: Tag Your Image for the Registry
Once logged in, tag your local image with the full registry path. This step is essential—Docker will not allow you to push an image without a properly formatted tag.
For Docker Hub:
docker tag myapp:latest username/myapp:latest
For Amazon ECR:
docker tag myapp:latest 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest
For Google Container Registry:
docker tag myapp:latest gcr.io/your-project-id/myapp:latest
For Azure Container Registry:
docker tag myapp:latest your-registry-name.azurecr.io/myapp:latest
You can verify the tag was applied by running docker images again. You’ll now see two entries for the same image ID—one with the original name and one with the registry-prefixed name.
Step 4: Push the Image to the Registry
With the image tagged correctly and authentication complete, push the image using:
docker push username/myapp:latest
For Amazon ECR:
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest
For Google Container Registry:
docker push gcr.io/your-project-id/myapp:latest
For Azure Container Registry:
docker push your-registry-name.azurecr.io/myapp:latest
During the push, Docker uploads each layer of the image. If a layer already exists on the registry (due to previous pushes), it’s skipped, making subsequent pushes faster and bandwidth-efficient. You’ll see progress output in your terminal, including upload status and layer checksums.
Step 5: Verify the Push
After the push completes, verify the image is available in the registry.
- Docker Hub: Visit hub.docker.com, navigate to your repository, and confirm the tag appears.
- Amazon ECR: Open the AWS Console, go to ECR, select your registry, and check the repository list.
- Google Container Registry: Use
gcloud container images list-tags gcr.io/your-project-id/myappor view via Google Cloud Console. - Azure Container Registry: Run
az acr repository show-tags --name your-registry-name --repository myappor use the Azure Portal.
You can also pull the image from another machine to confirm accessibility:
docker pull username/myapp:latest
Step 6: Automate with CI/CD (Optional but Recommended)
Manually pushing images is fine for development, but in production, automation is essential. Integrate image pushes into your CI/CD pipeline using tools like GitHub Actions, GitLab CI, Jenkins, or CircleCI.
Example GitHub Actions workflow for pushing to Docker Hub:
name: Build and Push Docker Image
on:
push:
branches: [ main ]
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: username/myapp
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
This workflow automatically triggers on pushes to the main branch, builds the image, logs in using secrets, and pushes with tags derived from Git metadata (e.g., commit hash, branch name).
Best Practices
Use Semantic Versioning for Tags
Never use latest in production environments. While convenient for development, latest is mutable and makes rollbacks, audits, and debugging extremely difficult. Instead, adopt semantic versioning:
v1.0.0– Stable releasev1.1.0-beta– Pre-releasesha-abc123– Build from commit hash
Using commit hashes as tags ensures traceability. If a bug emerges in production, you can pinpoint the exact image used by matching the hash in your deployment logs.
Minimize Image Size
Smaller images are faster to push, pull, and deploy. Use multi-stage builds to reduce final image size:
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
This approach builds dependencies in a builder stage and copies only the necessary files into the final image, avoiding development tools and unnecessary layers.
Scan Images for Vulnerabilities
Before pushing, scan your image for known security vulnerabilities. Docker provides docker scan (requires Docker Desktop), and third-party tools like Trivy, Clair, or Snyk integrate into CI/CD pipelines:
docker scan username/myapp:v1.0
Configure your pipeline to fail if critical vulnerabilities are detected. This enforces a “shift-left” security model, catching issues early.
Use Private Registries for Sensitive Workloads
Public registries like Docker Hub are fine for open-source projects, but for proprietary applications, use private registries (ECR, ACR, Harbor) to control access. Restrict permissions using IAM roles, network policies, and token-based authentication.
Enable image signing with Notary or Cosign to ensure integrity and authenticity. Signed images prevent tampering and unauthorized modifications.
Implement Image Retention Policies
Registries can fill up quickly. Set up automated cleanup policies to remove old or unused images. For example:
- Keep the last 10 versions of each tag.
- Delete images older than 30 days if not tagged as
stableorrelease.
Most cloud providers support lifecycle rules. In ECR, use the AWS Console or CLI to define retention policies based on age or tag count.
Tag Images with Metadata
Use Docker labels to embed metadata into your images:
docker build -t username/myapp:v1.0 \
--label org.opencontainers.image.source=https://github.com/username/myapp \
--label org.opencontainers.image.revision=abc123 \
--label org.opencontainers.image.version=v1.0 \
.
These labels follow the Open Container Initiative (OCI) specification and are readable by orchestration tools like Kubernetes and Docker Compose.
Avoid Pushing from Development Machines
Never push images directly from a developer’s laptop. Always use a dedicated build server or CI/CD pipeline. This ensures:
- Consistent build environments
- Reproducible builds
- Centralized audit logs
- Enforced security policies
CI/CD pipelines also allow you to run tests, linting, and scanning before pushing—reducing the risk of deploying broken or insecure images.
Tools and Resources
Core Tools
- Docker CLI – The standard tool for building, tagging, and pushing images. Available at docs.docker.com.
- Docker Buildx – A CLI plugin for advanced build features, including multi-platform builds. Essential for cross-architecture deployments.
- AWS CLI – Required for authenticating with Amazon ECR. Install via AWS CLI.
- Google Cloud SDK – Required for GCR. Download at cloud.google.com/sdk.
- Azure CLI – For ACR authentication. Install at Microsoft Learn.
- Trivy – Open-source vulnerability scanner for containers. Use with
trivy image username/myapp:v1.0. Available at trivy.dev. - Harbor – Open-source registry with role-based access, scanning, and replication. Deployable on-premises or in the cloud. Visit goharbor.io.
CI/CD Integration Tools
- GitHub Actions – Native integration with Docker Hub, ECR, GCR, and ACR via official actions.
- GitLab CI/CD – Built-in Docker registry and powerful YAML-based pipelines.
- Jenkins – Use the Docker Pipeline plugin for advanced orchestration.
- CircleCI – Offers pre-built Docker orbs for streamlined image pushes.
- Argo CD – For GitOps deployments; pulls images from registries automatically based on Git state.
Monitoring and Governance
- Docker Scout – Docker’s official tool for image analysis, vulnerability detection, and compliance checks.
- Snyk – Integrates with registries to monitor for new vulnerabilities in deployed images.
- Open Policy Agent (OPA) – Enforce policies on image sources, tags, and signatures before deployment.
Documentation and References
- Docker Push Command Documentation
- Amazon ECR Push Guide
- GCR Push/Pull Guide
- Azure Container Registry CLI Guide
- Open Container Initiative Image Specification
Real Examples
Example 1: Pushing a Node.js App to Docker Hub
Imagine you’ve built a simple Express.js application and want to deploy it to Docker Hub.
Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Build and tag:
docker build -t mynodeapp:1.0.0 .
docker tag mynodeapp:1.0.0 johnsmith/mynodeapp:1.0.0
Login and push:
docker login
docker push johnsmith/mynodeapp:1.0.0
After pushing, the image is available at hub.docker.com/r/johnsmith/mynodeapp. Other developers can now pull it with docker pull johnsmith/mynodeapp:1.0.0.
Example 2: Automated Push to Amazon ECR via GitHub Actions
You’re managing a microservice in a private AWS environment. Your team uses GitHub Actions for CI/CD.
.github/workflows/deploy.yml:
name: Deploy to ECR
on:
push:
branches: [ release ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.login-ecr.outputs.registry }}/myapp:${{ github.sha }}
labels: org.opencontainers.image.source=https://github.com/${{ github.repository }}
This workflow:
- Triggers on pushes to the
releasebranch - Authenticates with AWS using secrets
- Builds the image and tags it with the Git commit SHA
- Pushes to ECR
- Embeds metadata for traceability
Now every release is immutable, traceable, and securely stored in AWS.
Example 3: Multi-Platform Image Push to Docker Hub
You’re building an application that runs on both AMD64 and ARM64 (e.g., Raspberry Pi). Use Buildx to create a multi-platform image:
docker buildx create --name mybuilder --use
docker buildx build --platform linux/amd64,linux/arm64 -t username/myapp:1.0.0 --push .
The --push flag automatically pushes the multi-platform manifest to Docker Hub. Users on any architecture will pull the correct variant automatically.
FAQs
What happens if I push an image with the same tag twice?
Most registries allow overwriting tags. Pushing username/myapp:latest twice replaces the previous image. This is dangerous in production. Always use immutable tags (e.g., version numbers or commit hashes) to prevent accidental overwrites.
Can I push images without logging in?
No. All private registries and most public ones (including Docker Hub) require authentication. Anonymous pushes are disabled by default for security reasons.
How long does it take to push an image?
It depends on image size and network speed. A 500MB image on a 100 Mbps connection takes about 40 seconds. Layer caching significantly reduces time on subsequent pushes. Use docker buildx with build cache for faster builds.
What’s the difference between Docker Hub and a private registry?
Docker Hub is a public registry hosted by Docker, ideal for open-source projects. Private registries (ECR, ACR, Harbor) offer access control, audit logs, vulnerability scanning, and network isolation—essential for enterprise and proprietary applications.
Can I push images to multiple registries at once?
Yes. Tag the same image with multiple registry paths and push each one:
docker tag myapp:1.0.0 username/myapp:1.0.0
docker tag myapp:1.0.0 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:1.0.0
docker push username/myapp:1.0.0
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:1.0.0
This is useful for hybrid cloud or multi-cloud deployments.
Why is my push failing with “unauthorized: authentication required”?
This error means Docker is not authenticated. Double-check:
- You ran
docker login(or equivalent for your registry) - Your credentials are correct
- Your tag matches the registry domain
- You have sufficient permissions (e.g., AcrPush role in Azure)
How do I delete an image from a registry?
Most registries require explicit deletion. For Docker Hub, use the web UI. For ECR:
aws ecr batch-delete-image --repository-name myapp --image-ids imageTag=v1.0
Always confirm deletion with a tag listing first. Never delete images without backups if they’re in production use.
Is it safe to store secrets in Docker images?
No. Never include API keys, passwords, or certificates in your Docker image. Use environment variables, secret managers (AWS Secrets Manager, HashiCorp Vault), or volume mounts at runtime instead.
Conclusion
Pushing a Docker image to a registry is more than a technical step—it’s a critical bridge between development and production. Mastering this process ensures your applications are consistently deployed, securely managed, and easily traceable across environments. By following the steps outlined in this guide—from building and tagging images to authenticating with registries and automating pushes via CI/CD—you empower your team to operate at scale with confidence.
Adopting best practices such as semantic versioning, vulnerability scanning, and immutable tags transforms your container workflow from a manual, error-prone task into a robust, auditable pipeline. Leveraging tools like Buildx, Trivy, and GitHub Actions further enhances reliability and security.
Whether you’re deploying to Docker Hub for open-source collaboration or pushing to Amazon ECR for enterprise-grade isolation, the principles remain the same: build once, tag wisely, authenticate securely, and automate relentlessly. As containerization continues to dominate modern infrastructure, the ability to push images effectively is not optional—it’s foundational.
Start small. Test with a single image. Then scale. Automate. Secure. And never push without a tag.