Hop Into Eggciting Learning Opportunities | Flat 25% OFF | Code: EASTER
docker6 min read

How to Build, Tag, and Push Docker Images to Docker Hub (Best Practices)

Suyash RaizadaSuyash Raizada
How to Build, Tag, and Push Docker Images to Docker Hub (Best Practices)

How to build, tag, and push Docker images to Docker Hub is a core skill for modern developers and DevOps teams. Done well, it produces smaller images, faster builds, fewer vulnerabilities, and more reliable deployments. Done poorly, it can lead to bloated images, slow CI pipelines, accidental secret leaks, and hard-to-debug rollbacks.

This guide walks through a practical workflow for building Docker images effectively, applying safe tagging strategies, and pushing to Docker Hub, with a best-practice checklist you can reuse in CI/CD pipelines.

Certified Artificial Intelligence Expert Ad Strip

1) Build Docker Images Effectively (Size, Speed, and Security)

Use Multi-Stage Builds for Production Images

Multi-stage builds separate the build environment from the runtime environment, which is fundamental for optimized production images. A common structure looks like this:

  • Dependencies stage: installs only what is needed to build or run the application

  • Builder stage: compiles assets or builds the application using build tools

  • Runtime stage: contains only the minimal artifacts required to execute the app

This reduces the final image size because compilers, package managers, and build caches do not end up in the runtime image.

Pick Minimal, Trusted Base Images

Base image selection affects both security and performance. Prefer trusted sources like Docker Official Images, and choose minimal images where feasible to reduce download time and the vulnerability surface area.

For Node.js workloads, the size difference between typical choices illustrates why this matters:

  • node:20: roughly 1 GB, often suited to development tooling

  • node:20-slim: roughly 200 MB when apt-get is required

  • node:20-alpine: roughly 130 MB for many production apps

  • distroless Node runtime: roughly 100 MB for a smaller, more locked-down runtime

Container security practices continue moving toward distroless and minimal base images, particularly for internet-facing services where attack surface reduction is a priority.

Optimize Layer Caching for Faster Builds

Docker caches layers when the instructions and inputs do not change. To take advantage of this behavior:

  • Copy dependency manifests first (such as package-lock.json) and install dependencies before copying the rest of the source code. Source code changes frequently; dependency files change less often.

  • Combine related RUN commands to reduce the number of layers and keep builds efficient.

These practices typically produce significant CI speedups, especially for projects with heavy dependencies.

Use a .dockerignore File to Reduce Build Context and Prevent Leaks

Before Docker builds, it sends a build context to the daemon. Without a .dockerignore file, you may accidentally send local secrets, logs, git history, and other unnecessary files. This increases build time and can expose sensitive data in images or intermediate layers.

A practical .dockerignore typically includes:

  • node_modules/ (when dependencies are installed inside the image)

  • .git/ and .gitignore

  • *.log, coverage/, and dist/ (depending on your workflow)

  • .env files and local secrets

Run as a Non-Root User

Running containers as root expands the blast radius if an attacker compromises the application process. In your final runtime stage, create and switch to a non-root user. This is a widely recommended hardening step and aligns with modern container security baselines.

Never Bake Secrets Into Images

Do not embed SSH keys, passwords, API tokens, or TLS private keys in a Docker image. Even if files are removed later in a Dockerfile, they may persist in previous layers. Instead:

  • Inject configuration via orchestrator-managed environment variables where appropriate

  • Use secret managers or platform secret stores (the preferred approach)

  • Use build-time arguments only when you fully understand their exposure and auditability

Add HEALTHCHECK for Safer Operations

A Dockerfile HEALTHCHECK instruction lets Docker and orchestrators detect unhealthy containers and restart them automatically. A common configuration uses:

  • interval: 30 seconds

  • timeout: 10 seconds

  • retries: 3

Health checks do not replace dedicated monitoring, but they provide an immediate safety net for broken dependencies and hung processes.

2) Tag Docker Images for Clarity and Safe Rollbacks

Avoid the latest Tag in Production

Using latest in production makes it difficult to know what version is deployed and can accidentally roll forward to an unexpected build. It also complicates rollback because the tag is not inherently tied to a specific version.

Better alternatives include:

  • Semantic versioning: 1.4.2

  • Timestamps: 2026-03-28.1

  • Git commit SHA: git-3f2c9a1

  • Digests: immutable references that guarantee exact image identity

Use Descriptive Tags That Map to Your Codebase

Choose a tagging scheme that makes it straightforward to correlate an image with the source code and CI pipeline that produced it. A common practice is to publish multiple tags for the same build, for example:

  • app:1.8.0

  • app:1.8

  • app:git-3f2c9a1

This approach improves traceability, audit readiness, and incident response efficiency.

Pin Base Images to Digests for Supply Chain Integrity

Even trusted tags can shift if a publisher reissues them. Pinning base images to a digest improves consistency across environments and strengthens supply chain integrity. Digest pinning and image signing are increasingly important as organizations harden their container security posture.

3) Scan and Verify Images Before Pushing

Lint Dockerfiles and Scan for Vulnerabilities

Before pushing to Docker Hub, run automated checks as part of your workflow:

  • Dockerfile linting to enforce maintainable best practices

  • Vulnerability scanning to detect known CVEs in OS packages and application dependencies

These checks are most effective when enforced in CI rather than left to manual review.

Sign and Verify Images with Docker Content Trust

Image signing and verification helps protect against tampering and supply chain risks during distribution. Enabling Docker Content Trust by setting DOCKER_CONTENT_TRUST=1 adds a verification step to pulls and pushes, depending on your workflow and repository configuration.

Also consider using verified images from trusted publishers. Some vendors distribute regularly updated, security-scanned images that meet enterprise hardening requirements.

4) How to Build, Tag, and Push Docker Images to Docker Hub

Step 1: Build the Image Locally

From the directory that contains your Dockerfile, run:

docker build -t myapp:1.0.0 .

Use an explicit version tag so the artifact is identifiable and the build is repeatable.

Step 2: Log In to Docker Hub

Authenticate with your Docker Hub account:

docker login

In enterprise environments, apply least-privilege access principles and use automation-friendly access tokens where supported by your governance policies.

Step 3: Tag the Image for Docker Hub

Docker Hub repositories follow the username-or-org/repository:tag format:

docker tag myapp:1.0.0 yourusername/myapp:1.0.0

If you also want a moving tag for convenience (not recommended for production deployments), you can publish it alongside versioned tags - for example, stable or release - as long as production deployments rely on immutable versioned tags or digests.

Step 4: Push the Image

Upload the image layers to Docker Hub:

docker push yourusername/myapp:1.0.0

After the push completes, you can pull the image from any environment with:

docker pull yourusername/myapp:1.0.0

5) Pre-Deployment Verification Checklist

Before publishing to Docker Hub or deploying to production, validate the following:

  • Multi-stage build separates build and runtime stages

  • Base image is minimal (slim, Alpine, or distroless where appropriate)

  • Dependencies are copied before source code to optimize layer caching

  • Related RUN commands are combined to reduce layer count

  • .dockerignore excludes unnecessary files and local secrets

  • Container runs as a non-root user

  • No secrets are baked into the image or intermediate layers

  • Health check is configured in the Dockerfile

  • Base image version is pinned, preferably by digest for reproducibility

  • Image has been linted and scanned for known vulnerabilities

Conclusion

Knowing how to build, tag, and push Docker images to Docker Hub goes well beyond running three commands. The difference between a quick demo image and a production-ready artifact comes down to multi-stage builds, minimal and pinned base images, cache-friendly layering, disciplined tagging practices, and security controls such as non-root execution, vulnerability scanning, and image signing.

For teams formalizing container practices at scale, building structured skills in Docker, DevOps, and cloud security provides a strong foundation. Blockchain Council offers relevant learning paths including DevOps and container security training, as well as broader cybersecurity certifications designed to support secure software supply chains.

Related Articles

View All

Trending Articles

View All

Search Programs

Search all certifications, exams, live training, e-books and more.