Master Docker in Real Projects: Compose + CI/CD + Best Practices

With real-world Docker Compose setups, GitHub Actions CI pipelines, and practical command recipes.

Everything you need to master Docker to Compose & CI/CD pipelines — from dev to deployment — in one place.

Docker Fundamentals

Whether you're debugging a container, cleaning up images, or building complex multi-stage setups, this is your one-stop command reference.

Getting Started with Docker

Check Docker Version

docker --version
docker version

Check Docker Info

docker info

Working with Images

Pull an Image

docker pull ubuntu:22.04

List Images

docker images

Remove Image

docker rmi ubuntu:22.04

Build Image from Dockerfile

docker build -t my-app-image .

Tag Image

docker tag my-app-image myrepo/my-app-image:latest

Push Image to Registry

docker push myrepo/my-app-image:latest

Working with Containers

Run Container

docker run -it ubuntu /bin/bash
docker run --name mycontainer -d nginx

List Running Containers

docker ps

List All Containers (including stopped)

docker ps -a

Stop Container

docker stop mycontainer

Start Container

docker start mycontainer

Remove Container

docker rm mycontainer

Debugging & Logs

View Logs of a Container

docker logs mycontainer

Attach to a Running Container

docker attach mycontainer

Exec into a Running Container

docker exec -it mycontainer /bin/bash

Cleaning Up

Remove All Stopped Containers

docker container prune

Remove All Unused Images

docker image prune

Remove Everything (Careful!)

docker system prune -a

Networking

List Networks

docker network ls

Create Network

docker network create my-network

Run Container with Network

docker run --network=my-network nginx

Volumes & Persistence

List Volumes

docker volume ls

Create Volume

docker volume create my-volume

Run with Volume

docker run -v my-volume:/app/data nginx

Bind Mount Local Directory

docker run -v $(pwd)/config:/app/config nginx

Advanced Usage

Multi-Stage Build (Dockerfile)

FROM node:18 AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html

Build with Build Args

docker build --build-arg VERSION=1.0 -t myapp .

Monitoring & Stats

View Container Stats

docker stats

Inspect Container

docker inspect mycontainer

TL;DR: Most Useful Everyday Commands

docker ps -a              # List all containers
docker images             # List all images
docker logs <id>          # Logs from container
docker exec -it <id> bash # Shell into container
docker rm <id>            # Remove container
docker rmi <id>           # Remove image

From Docker to Compose

Now we are going for Scaling Multi-Container Apps…!

What is Docker Compose?

Docker Compose is a tool for defining and running multi-container Docker applications. You define services, networks, and volumes in a single YAML file (docker-compose.yml).

It simplifies local development, staging, testing, and even production deployments for small- to mid-size apps.

Basic docker-compose.yml Structure

docker-compose.yml

version: '3.8'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
    volumes:
      - .:/app
  redis:
    image: redis:alpine

Key Options —

  • build: Context for Dockerfile

  • ports: Map host:container ports

  • environment: Inject ENV vars

  • volumes: Sync host and container files

Real-World Docker Compose Examples

1. Node.js App + MongoDB

version: '3.8'
services:
  backend:
    build: ./backend
    ports:
      - "4000:4000"
    depends_on:
      - mongo
  mongo:
    image: mongo
    volumes:
      - mongo_data:/data/db
volumes:
  mongo_data:

2. Next.js + Redis + MySQL + Nginx + PHPMyAdmin

version: '3.9'

services:
  app:
    build: ./app
    ports:
      - "3000:3000"
    depends_on:
      - db

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: myapp
    volumes:
      - mysql_data:/var/lib/mysql

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports:
      - "8081:80"
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORD: root
    depends_on:
      - db

  nginx:
    image: nginx
    ports:
      - "8080:80"

volumes:
  mysql_data:

Useful Commands

# Start all services
docker-compose up

# Rebuild on changes
docker-compose up --build

# Start in background (detached mode)
docker-compose up -d

# Stop all services
docker-compose down

# List running containers
docker-compose ps

# Run a one-off command
docker-compose exec web sh

CI/CD with Docker

Using GitHub Actions Example

Let’s automate builds + tests with GitHub Actions.

📁 .github/workflows/docker.yml

name: Docker CI
on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Set up Docker
      uses: docker/setup-buildx-action@v2

    - name: Build Docker image
      run: docker build -t myapp .

    - name: Run tests
      run: docker run myapp npm test

CI/CD with Docker Compose

In GitHub Actions

name: Docker Compose CI
on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      docker:
        image: docker:20.10.16

    steps:
    - uses: actions/checkout@v3

    - name: Set up Docker Compose
      run: |
        sudo curl -L "https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
        sudo chmod +x /usr/local/bin/docker-compose

    - name: Run Integration Tests
      run: |
        docker-compose up -d
        docker-compose exec web npm test

Bonus: Secrets in Docker Compose

  environment:
    - DB_PASSWORD=${DB_PASSWORD}

Set in .env file or CI/CD secrets manager.

Best Practices Recap

AreaTip
Build CachingUse .dockerignore + multistage builds
SecretsAvoid hardcoding in YAML, use ENV or secrets manager
Clean Updocker-compose down -v to remove volumes too
LogsUse docker-compose logs -f for debugging
HealthchecksAdd to services for better orchestration
1
Subscribe to my newsletter

Read articles from Faiz Ahmed Farooqui directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Faiz Ahmed Farooqui
Faiz Ahmed Farooqui

Principal Technical Consultant at GeekyAnts. Bootstrapping our own Data Centre services. I lead the development and management of innovative software products and frameworks at GeekyAnts, leveraging a wide range of technologies including OpenStack, Postgres, MySQL, GraphQL, Docker, Redis, API Gateway, Dapr, NodeJS, NextJS, and Laravel (PHP). With over 9 years of hands-on experience, I specialize in agile software development, CI/CD implementation, security, scaling, design, architecture, and cloud infrastructure. My expertise extends to Metal as a Service (MaaS), Unattended OS Installation, OpenStack Cloud, Data Centre Automation & Management, and proficiency in utilizing tools like OpenNebula, Firecracker, FirecrackerContainerD, Qemu, and OpenVSwitch. I guide and mentor a team of engineers, ensuring we meet our goals while fostering strong relationships with internal and external stakeholders. I contribute to various open-source projects on GitHub and share industry and technology insights on my blog at blog.faizahmed.in. I hold an Engineer's Degree in Computer Science and Engineering from Raj Kumar Goel Engineering College and have multiple relevant certifications showcased on my LinkedIn skill badges.