Building Docker Images in CI
Imagine a car factory. Every car starts with a blueprint (Dockerfile), and the assembly line builds identical cars from that blueprint. In CI pipelines, building Docker images works the same way — every commit triggers a fresh build, ensuring consistency and reliability across environments.
Building Images Foundations
1. Why Build Docker Images in CI?
- Consistency: Every build uses the same Dockerfile, producing identical environments.
- Automation: Images are built automatically on code commits.
- Portability: Built images can run anywhere (local, cloud, Swarm, Kubernetes).
- Integration: Images are pushed to registries for deployment in CD.
2. Key Steps in Building Images in CI
- Define Dockerfile: Blueprint for the application.
- Configure CI Tool: Jenkins, GitHub Actions, GitLab CI, etc.
- Build Image: Run
docker buildin pipeline. - Test Image: Run unit/integration tests inside container.
- Push Image: Upload to registry (Docker Hub, AWS ECR, GCP Artifact Registry).
3. Example GitHub Actions Workflow
name: CI Pipeline
on:
push:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Set up Docker
uses: docker/setup-buildx-action@v1
- name: Build Docker Image
run: docker build -t myapp:latest .
- name: Run Tests
run: docker run --rm myapp:latest npm test
- name: Push to Docker Hub
run: |
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
docker tag myapp:latest mydockerhub/myapp:latest
docker push mydockerhub/myapp:latest
4. Example GitLab CI/CD Workflow
stages:
- build
- test
- push
build:
stage: build
script:
- docker build -t myapp:latest .
test:
stage: test
script:
- docker run --rm myapp:latest npm test
push:
stage: push
script:
- docker login -u $DOCKER_USER -p $DOCKER_PASS
- docker tag myapp:latest mydockerhub/myapp:latest
- docker push mydockerhub/myapp:latest
Things to Remember
- CI pipelines automate Docker image builds on every commit.
- Testing inside containers ensures reliability before deployment.
- Registries act as distribution hubs for deployment in CD.
Hands‑On Lab
Step 1: Write a Dockerfile for a Python Flask App
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]
Step 2: Build Image in CI
docker build -t flaskapp:latest .
Step 3: Run Tests in Container
docker run --rm flaskapp pytest
Step 4: Push Image to Registry
docker tag flaskapp:latest mydockerhub/flaskapp:latest
docker push mydockerhub/flaskapp:latest
Practice Exercise
- Write a Dockerfile for a Node.js app.
- Configure a CI pipeline (GitHub Actions or GitLab CI) to:
- Build the image.
- Run tests inside the container.
- Push the image to Docker Hub.
- Verify the image is available in the registry.
- Reflect on how automation reduces manual effort and errors.
Visual Learning Model
CI Pipeline: Building Docker Images
├── Code Commit → triggers pipeline
├── Build → docker build
├── Test → run in container
├── Push → registry
└── Deploy → CD stage
The Hackers Notebook
Building Docker images in CI ensures consistency, automation, and portability. Pipelines automatically build, test, and push images to registries, preparing them for deployment. This step is the backbone of modern DevOps workflows, enabling reliable and repeatable software delivery.

Updated on Dec 26, 2025