๐Ÿš€ (Post 6): CI/CD with Docker โ€” Automating Builds, Tests & Deployment!

DevOps isn't complete without automation. Once you've containerized your app, it's time to automate everything from building and testing to deploying it across environments. This post dives into integrating Docker with CI/CD pipelines using tools like GitHub Actions, writing multi-stage Dockerfiles, and optimizing builds with caching strategies.

๐Ÿงฑ Docker in the DevOps Workflow

Here's how Docker fits into a CI/CD pipeline:

๐Ÿณ Multi-Stage Dockerfile: Build Once, Ship Clean

Multi-stage builds help you build and package your app efficiently by separating build dependencies from the final image. Here's a production-ready example for a Node.js app:

# Stage 1 โ€” Build
FROM node:18-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2 โ€” Production
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
RUN npm ci --only=production
CMD ["node", "dist/index.js"]

Why it matters: Final image is smaller, faster, and contains no unnecessary dev files.

๐Ÿค– GitHub Actions + Docker: Your CI/CD Pipeline

Let's walk through a full CI/CD setup using GitHub Actions.

๐Ÿ“ .github/workflows/docker-ci.yml

name: CI/CD with Docker

on:
  push:
    branches: [main]

jobs:
  build-test-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: ๐Ÿ“ฅ Checkout code
        uses: actions/checkout@v3

      - name: ๐Ÿณ Set up Docker
        uses: docker/setup-buildx-action@v2

      - name: ๐Ÿ”จ Build image
        run: docker build -t aelify/app:latest .

      - name: โœ… Run tests in container
        run: docker run --rm aelify/app:latest npm test

      - name: ๐Ÿ” Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: ๐Ÿš€ Push to Docker Hub
        run: docker push aelify/app:latest

      - name: ๐Ÿšข Deploy (optional)
        run: ssh ${{ secrets.SSH_USER }}@${{ secrets.SERVER_IP }} \
             'docker pull aelify/app:latest && docker restart my-container'

๐Ÿ” Secrets like Docker credentials or SSH keys should be stored securely in GitHub Secrets.

๐Ÿงช Running Tests Inside Docker

Want to test your app exactly how it'll run in production? Docker is perfect:

docker build -t test-app .
docker run --rm test-app npm test

๐Ÿ”ฅ Tip: Include test dependencies only in the first stage of your Dockerfile.

๐Ÿง  Optimize Docker Builds with Caching

Here's a smart way to cache dependencies in Docker:

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .

By copying package.json separately, Docker caches dependencies unless they change โ€” drastically speeding up builds.

๐Ÿ—๏ธ GitLab CI Alternative (Bonus)

If you use GitLab, here's a similar pipeline:

build:
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker build -t registry.gitlab.com/youruser/app:latest .
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
    - docker push registry.gitlab.com/youruser/app:latest

๐Ÿ” CI/CD Recap

Docker + CI/CD = shipping confidently and consistently. Whether you're deploying weekly or hourly, these tools let you move fast and stay reliable. Start small, automate relentlessly, and enjoy the ride. ๐Ÿงช๐Ÿšข๐Ÿ’ก

In our next post, we'll dive into ๐Ÿ” (Post 7): Securing Docker โ€” Best Practices for Hardening Containers & Hosts!

โ€” Blog by Aelify (ML2AI.com)

๐Ÿ“š Documentation Index