Docker Curriculum
On this page
- Docker In Cicd Overview
- The Core Principle: Immutable Artifacts
- The Standard Docker CI/CD Pipeline
- Stage 1: Build
- Stage 2: Lint (Static Analysis)
- Stage 3: Test
- Stage 4: Security Scan
- Stage 5: Push
- Stage 6: Deploy
- The Two Environments Pattern
- Caching Strategy for Fast Builds
- Layer Caching with Registry
- BuildKit Inline Cache
- Summary
Docker In Cicd Overview
Continuous Integration and Continuous Delivery (CI/CD) pipelines are where Docker's benefits are most fully realized. Every commit is automatically built into a tested, scanned, and versioned image. Every deployment is a predictable, reproducible container swap. The environment that ran tests is identical to the environment that runs in production.
This file covers the architecture of a Docker-based CI/CD pipeline — what the stages are, what guarantees each stage provides, and how Docker images flow from a developer's commit to a production deployment.
The Core Principle: Immutable Artifacts
The most important principle in Docker-based CI/CD is that the container image is the deployment artifact.
In traditional pipelines, the artifact is code (a tarball, a JAR, a zip) that is then assembled into a running environment on the target server. The environment on the target server may differ from the environment where tests ran. "It works on my machine" becomes "it works in staging."
In a Docker-based pipeline:
- One image is built once from the commit
- The same image runs in all environments: test, staging, production
- The image is immutable — its SHA256 digest never changes
- The image is versioned by a git commit SHA or semantic version tag
This means if the image passes tests, you have high confidence the exact same image will work in production — because it is the same image.
The Standard Docker CI/CD Pipeline
Each stage is a gate. If a stage fails, the pipeline stops. Code with failing tests, known vulnerabilities, or Dockerfile linting errors never reaches the registry.
Stage 1: Build
The build stage creates the image from the Dockerfile using the current commit's source code.
Key practices:
- Tag with git SHA for immutable, traceable images
- Use
--cache-fromto pull previous layers for fast rebuilds - Pass build metadata (version, commit, date) as
ARGvalues
Stage 2: Lint (Static Analysis)
Lint the Dockerfile before running any containers — fast feedback, no compute wasted:
Stage 3: Test
Run the test suite inside the built image, using the exact same environment that will run in production:
Using Docker Compose for integration tests:
Stage 4: Security Scan
Scan the built image for known CVEs before pushing:
Stage 5: Push
After all gates pass, push the image to the registry:
Stage 6: Deploy
With the image in the registry, trigger the deployment:
Or for single-host Docker Compose deployments:
The Two Environments Pattern
A key architectural decision: should the CI environment build images using Docker-in-Docker, or should CI runners have Docker available natively?
Option 1: Docker-in-Docker (DinD)
The CI runner itself is a container. To run Docker inside it, you need "Docker in Docker." This is complex, has security implications (requires --privileged), and has performance overhead.
Option 2: Docker on the Host Runner (Recommended)
The CI runner is a VM or a bare-metal machine with Docker installed. Docker commands run directly. No privileged containers, no special configuration. This is how GitHub Actions, most Jenkins setups, and AWS CodeBuild work.
Caching Strategy for Fast Builds
Build speed is a developer experience issue. Slow CI is a productivity killer.
Layer Caching with Registry
BuildKit Inline Cache
Summary
- In Docker-based CI/CD, the container image is the deployment artifact — the same image that passes tests deploys to production
- A standard pipeline has six stages: Build → Lint → Test → Scan → Push → Deploy — each is a gate that can stop the pipeline
- Tag images with the git commit SHA for immutable, traceable artifacts; also tag
latestfor use as a build cache - Use
--cache-fromto pull previous image layers — dramatically reduces build time by reusing unchanged layers - Always scan with Trivy before pushing —
--exit-code 1 --severity CRITICAL,HIGHensures only secure images reach the registry - Use Docker-native CI runners (GitHub Actions, AWS CodeBuild) rather than Docker-in-Docker for simplicity, security, and performance
In the next file, we build a complete Docker CI/CD pipeline using GitHub Actions — the most widely used CI platform.