Skip to main content

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

  1. Define Dockerfile: Blueprint for the application.
  2. Configure CI Tool: Jenkins, GitHub Actions, GitLab CI, etc.
  3. Build Image: Run docker build in pipeline.
  4. Test Image: Run unit/integration tests inside container.
  5. 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

  1. Write a Dockerfile for a Node.js app.
  2. Configure a CI pipeline (GitHub Actions or GitLab CI) to:
    • Build the image.
    • Run tests inside the container.
    • Push the image to Docker Hub.
  3. Verify the image is available in the registry.
  4. 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.


Tips, Tricks, Roadmaps, Resources, Networking, Motivation, Guidance, and Cool Stuff ♥

Updated on Dec 26, 2025