Current date May 18, 2026
DevOps

Docker Compose in 2026: best practices that actually matter

URL copied
Share URL copied
Docker Compose in 2026: best practices that actually matter
Docker Compose in 2026: best practices that actually matter

`docker-compose up` is the first command you learn. What comes next — networking, secrets, healthchecks, profiles for different environments — is what separates a functional configuration from a production-ready one.

Multi-stage builds: fewer MBs, more security

A production Dockerfile should never include development tools:

# Stage 1: dependencies and build
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci                    # [!code highlight]
COPY . .
RUN npm run build

# Stage 2: minimal final image
FROM node:22-alpine AS production  # [!code ++]
WORKDIR /app                       # [!code ++]
                                   # [!code ++]
# Only copy what's necessary       # [!code ++]
COPY --from=builder /app/dist ./dist  # [!code ++]
COPY --from=builder /app/node_modules ./node_modules  # [!code ++]
                                   # [!code ++]
USER node                          # do not run as root // [!code ++]
EXPOSE 3000
CMD ["node", "dist/server.js"]

The difference in size can be from 600 MB → 80 MB.

Profiles for different environments

With `profiles` you can activate services based on context without maintaining multiple Compose files:

services:
  api:
    # no profile = always active
    build: .

  adminer:
    image: adminer
    profiles: [dev, debug] # only in dev // [!code highlight]
    ports:
      - "8080:8080"

  prometheus:
    image: prom/prometheus
    profiles: [monitoring] # only when you need it // [!code highlight]
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
# Only bring up API + DB
docker compose up

# Bring up with dev tools
docker compose --profile dev up

# Entire monitoring stack
docker compose --profile monitoring up

Healthchecks that actually work

The basic `depends_on` only waits for the container to start, not for the service to be ready. The difference matters:

services:
  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 10
      start_period: 10s # initial grace period // [!code highlight]

  worker:
    build: .
    depends_on:
      redis:
        condition: service_healthy # wait for green healthcheck // [!code highlight]

Networking: isolation by default

Every `compose.yml` creates its own network. To communicate separate stacks:

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true # no internet access // [!code highlight]

services:
  nginx:
    networks: [frontend, backend] # the only one touching both networks

  api:
    networks: [backend] # isolated from the outside // [!code highlight]

  db:
    networks: [backend] # ditto

Checklist before production

  • [ ] Sensitive variables in `secrets` or `.env` outside the repository
  • [ ] Multi-stage build active
  • [ ] `restart: unless-stopped` on all critical services
  • [ ] Healthchecks configured with proper `start_period`
  • [ ] `depends_on` with `condition: service_healthy`
  • [ ] Non-root users in containers (`USER node`, `USER app`)
  • [ ] Named volumes for persistent data (no bind mounts in prod)
  • [ ] `–max-old-space-size` configured according to container memory

> The difference between a tutorial `compose.yml` and a production one is not in the number of lines — it’s in knowing what can fail and having accounted for it.

Share URL copied

Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Active0
AI3
AI & Automation10

Exclusives

Lifestyle

Related Articles

Platform Engineering: Chìa khóa nâng tầm DevOps năm 2026

Tại sao Platform Engineering đang dần thay thế các mô hình DevOps...

DevOps Hiện Đại Năm 2026: Khi AI Trở Thành ‘Quản Gia’ Cho Infrastructure

Khám phá cách AI đang tái định nghĩa quy trình DevOps, từ...

Tự động hóa CI/CD cho Blog Astro với GitHub Actions và OpenClaw

Hướng dẫn cách xây dựng quy trình tự động hóa việc xuất...

Terminal productivity: the tools that transformed my workflow

A tour of modern command-line tools that replace Unix classics — faster,...