Docker Compose in 2026: Multi-Container Apps, Networking en DevOps Sollicitatievragen

Docker Compose tutorial voor multi-container applicaties met networking, volumes en productie-deployment. Inclusief veelgestelde DevOps sollicitatievragen.

Docker Compose in 2026: Multi-Container Apps, Networking en DevOps Sollicitatievragen

Docker Compose blijft in 2026 de voorkeurstool voor het definiëren en uitvoeren van multi-container Docker-applicaties. Of het nu gaat om het orkestreren van een lokale development stack of het voorbereiden op een DevOps-sollicitatiegesprek, het begrijpen van Compose networking, service-afhankelijkheden en productiepatronen onderscheidt junior ontwikkelaars van senior professionals.

Kernpunt

Docker Compose gebruikt een declaratief YAML-formaat om services, netwerken en volumes in één bestand te definiëren. Het uitvoeren van docker compose up start de volledige applicatiestack met geïsoleerd netwerk en persistente opslag.

De Docker Compose Architectuur Begrijpen

Docker Compose werkt volgens een eenvoudig principe: definieer de services van de applicatie in een compose.yaml-bestand (de moderne naamgevingsconventie die docker-compose.yml vervangt), en Compose regelt de containercreatie, netwerkconfiguratie en lifecycle-beheer.

De Docker Compose specificatie definieert drie kernconcepten:

  • Services: Containerconfiguraties inclusief image, build context, omgevingsvariabelen en resourcelimieten
  • Networks: Geïsoleerde communicatiekanalen tussen services
  • Volumes: Persistente dataopslag die container-restarts overleeft
yaml
# compose.yaml
services:
  api:
    build: ./api
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://db:5432/app
    depends_on:
      db:
        condition: service_healthy
    networks:
      - backend

  db:
    image: postgres:16
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=app
      - POSTGRES_PASSWORD_FILE=/run/secrets/db_password
    secrets:
      - db_password
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5
    networks:
      - backend

networks:
  backend:
    driver: bridge

volumes:
  postgres_data:

secrets:
  db_password:
    file: ./secrets/db_password.txt

Deze configuratie demonstreert verschillende productie-ready patronen: health checks voor afhankelijkheidsvolgorde, Docker secrets voor gevoelige data, benoemde volumes voor persistentie en expliciete netwerkdefinities.

Docker Compose Networking Uitgelicht

Standaard creëert Compose een enkel netwerk voor de applicatie. Alle services treden toe tot dit netwerk en kunnen elkaar bereiken via de servicenaam als hostname. Het begrijpen van dit netwerkmodel is fundamenteel voor een latere Kubernetes-migratie.

yaml
# compose.yaml
services:
  frontend:
    build: ./frontend
    ports:
      - "80:80"
    networks:
      - frontend-net
      - backend-net

  api:
    build: ./api
    networks:
      - backend-net

  cache:
    image: redis:7-alpine
    networks:
      - backend-net

  db:
    image: postgres:16
    networks:
      - backend-net

networks:
  frontend-net:
    driver: bridge
  backend-net:
    driver: bridge
    internal: true

De internal: true flag voorkomt dat het backend-netwerk toegang heeft tot het externe internet. De frontend service verbindt beide netwerken en fungeert als enig toegangspunt. Deze netwerksegmentatie weerspiegelt beveiligingspraktijken in productieomgevingen.

DNS-Resolutie

De ingebouwde DNS-server van Docker lost servicenamen automatisch op. De api-service bereikt de database op db:5432 zonder handmatige IP-configuratie.

Multi-Stage Builds met Compose

Productie-images moeten minimaal zijn. Multi-stage builds gecombineerd met Compose-profielen maken verschillende configuraties mogelijk voor development en productie.

dockerfile
# api/Dockerfile
# Stage 1: Build
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2: Production
FROM node:22-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
USER node
EXPOSE 3000
CMD ["node", "dist/index.js"]

# Stage 3: Development
FROM node:22-alpine AS development
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
USER node
CMD ["npm", "run", "dev"]
yaml
# compose.yaml
services:
  api:
    build:
      context: ./api
      target: ${BUILD_TARGET:-production}
    volumes:
      - ${API_VOLUMES:-./api/dist:/app/dist:ro}
    profiles:
      - ${COMPOSE_PROFILES:-prod}

Het uitvoeren van BUILD_TARGET=development COMPOSE_PROFILES=dev docker compose up start de development-configuratie met hot reload.

Service-Afhankelijkheden en Health Checks

De depends_on-directive bepaalt de opstartvolgorde, maar gestarte containers betekenen niet dat services klaar zijn. Health checks lossen dit timing-probleem op, een patroon dat vaak wordt gevraagd in DevOps-sollicitatiegesprekken.

yaml
# compose.yaml
services:
  api:
    build: ./api
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
      migrations:
        condition: service_completed_successfully

  migrations:
    build: ./api
    command: npm run migrate
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 5
      start_period: 10s

  cache:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 3

Er bestaan drie afhankelijkheidscondities:

  • service_started: Standaard, container is gestart
  • service_healthy: Health check is geslaagd
  • service_completed_successfully: Container eindigt met code 0 (voor init-containers)

Klaar om je DevOps gesprekken te halen?

Oefen met onze interactieve simulatoren, flashcards en technische tests.

Docker Compose voor Lokale Development

Development-omgevingen profiteren van bind mounts, omgevingsoverrides en debugging-tools. Het compose.override.yaml-bestand wordt automatisch samengevoegd met compose.yaml.

yaml
# compose.yaml (basisconfiguratie)
services:
  api:
    build: ./api
    environment:
      - NODE_ENV=production

  db:
    image: postgres:16
yaml
# compose.override.yaml (development overrides)
services:
  api:
    build:
      target: development
    volumes:
      - ./api:/app
      - /app/node_modules
    environment:
      - NODE_ENV=development
      - DEBUG=app:*
    ports:
      - "9229:9229"

  db:
    ports:
      - "5432:5432"

Het anonieme volume /app/node_modules voorkomt dat de node_modules van de host de geïnstalleerde dependencies van de container overschrijven.

Productie Deployment Patronen

Docker Compose werkt voor single-host productie-deployments. Voor multi-host orkestratie biedt Kubernetes met Helm betere schaalbaarheid, maar Compose blijft geschikt voor kleinere applicaties.

yaml
# compose.prod.yaml
services:
  api:
    image: registry.example.com/api:${VERSION:-latest}
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: "0.5"
          memory: 512M
        reservations:
          cpus: "0.25"
          memory: 256M
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      - api

De deploy-key configureert resourcelimieten, replica-aantallen en herstartbeleid. Het uitvoeren van docker compose -f compose.prod.yaml up -d start de productiestack in detached modus.

Omgevingsvariabelen en Secrets Management

Gevoelige configuratie vereist zorgvuldige behandeling. Docker Compose ondersteunt meerdere benaderingen, van .env-bestanden tot Docker secrets.

bash
# .env
POSTGRES_PASSWORD=dev_password_only
API_SECRET_KEY=local_dev_key
yaml
# compose.yaml
services:
  api:
    environment:
      - API_SECRET_KEY  # Erft van shell of .env
      - DATABASE_URL=postgres://user:${POSTGRES_PASSWORD}@db:5432/app
    env_file:
      - ./config/api.env

Voor productie bieden Docker secrets betere beveiliging door gevoelige data als bestanden te mounten in plaats van omgevingsvariabelen:

yaml
# compose.prod.yaml
services:
  api:
    secrets:
      - api_key
      - db_password
    environment:
      - API_KEY_FILE=/run/secrets/api_key

secrets:
  api_key:
    external: true
  db_password:
    file: ./secrets/db_password.txt
Beveiligingswaarschuwing

Commit nooit .env-bestanden met productie-secrets naar versiebeheer. Gebruik voor productie-deployments externe secret management zoals HashiCorp Vault of cloud provider oplossingen.

Veelgestelde DevOps Sollicitatievragen over Docker Compose

Interviewers testen het begrip van Compose-concepten door praktische scenario's. Deze vragen komen regelmatig voor in DevOps en platform engineering sollicitatiegesprekken.

V: Hoe communiceren containers in een Compose-netwerk?

Docker creëert een dedicated bridge-netwerk voor elk Compose-project. Services communiceren via hun servicenamen als hostnamen. De ingebouwde DNS-server lost deze namen op naar container-IP-adressen. Extern verkeer bereikt services alleen via expliciet gepubliceerde poorten.

V: Wat gebeurt er bij het uitvoeren van docker compose up met bestaande containers?

Compose vergelijkt de huidige configuratie met draaiende containers. Ongewijzigde services blijven draaien. Gewijzigde services worden opnieuw aangemaakt met nieuwe instellingen. Nieuwe services starten vers. Verwijderde services worden gestopt en verwijderd.

V: Hoe worden databasemigraties in Compose afgehandeld?

Er bestaan twee patronen. Ten eerste: gebruik een init-container met service_completed_successfully-afhankelijkheid:

yaml
services:
  migrate:
    image: api:latest
    command: npm run migrate
    depends_on:
      db:
        condition: service_healthy

  api:
    depends_on:
      migrate:
        condition: service_completed_successfully

Ten tweede: migratie-logica opnemen in het applicatie-opstartscript, waarbij openstaande migraties worden gecontroleerd en toegepast voordat verkeer wordt geaccepteerd.

V: Wat is het verschil tussen volumes en bind mounts?

Benoemde volumes worden beheerd door Docker, opgeslagen in /var/lib/docker/volumes, en zijn overdraagbaar tussen hosts. Bind mounts mappen host-directories direct in containers, nuttig voor development maar omgevingsafhankelijk. Volumes ondersteunen drivers voor remote storage zoals NFS of cloud block storage.

V: Wat is het verschil tussen docker-compose en docker compose?

Het met koppelteken geschreven docker-compose was de standalone V1-tool gebaseerd op Python, nu deprecated. Het met spatie geschreven docker compose is de Go-gebaseerde V2-implementatie geïntegreerd in de Docker CLI. V2 is sneller, ondersteunt de Compose Specificatie volledig en ontvangt actieve ontwikkeling.

Debugging van Compose Applicaties

Troubleshooting van gecontaineriseerde applicaties vereist specifieke technieken. Deze commando's onthullen wat er gebeurt in de Compose-stack:

bash
# Logs bekijken van alle services
docker compose logs -f

# Logs van specifieke service met timestamps
docker compose logs -f --timestamps api

# Commando uitvoeren in draaiende container
docker compose exec api sh

# Eenmalig commando uitvoeren (start nieuwe container)
docker compose run --rm api npm test

# Resourcegebruik bekijken
docker compose top
docker stats

# Netwerkconfiguratie inspecteren
docker network inspect project_backend

# Compose-bestand valideren
docker compose config

Het docker compose config commando voegt alle compose-bestanden samen en toont de uiteindelijke configuratie, onmisbaar voor het debuggen van variabele-interpolatieproblemen.

Conclusie

  • Docker Compose definieert multi-container applicaties in een enkel YAML-bestand met services, netwerken en volumes
  • Services communiceren via DNS met servicenamen als hostnamen binnen het standaard bridge-netwerk
  • Health checks met service_healthy-condities zorgen voor correcte opstartvolgorde
  • Gebruik compose.override.yaml voor development-specifieke instellingen zoals bind mounts en debug-poorten
  • Productie-deployments profiteren van resourcelimieten, herstartbeleid en Docker secrets voor gevoelige data
  • De docker compose CLI (V2) vervangt de deprecated docker-compose (V1) met betere prestaties en meer functies

Begin met oefenen!

Test je kennis met onze gespreksimulatoren en technische tests.

Delen

Gerelateerde artikelen