Docker Compose w 2026: Aplikacje wielokontenerowe, sieci i pytania rekrutacyjne DevOps

Kompletny przewodnik po Docker Compose w 2026 roku. Architektura wielokontenerowa, konfiguracja sieci, health checks, zarządzanie sekretami oraz najczęstsze pytania na rozmowach kwalifikacyjnych DevOps.

Docker Compose w 2026 - aplikacje wielokontenerowe i sieci

Docker Compose pozostaje podstawowym narzędziem do definiowania i uruchamiania wielokontenerowych aplikacji Docker w 2026 roku. Niezależnie od tego, czy chodzi o orkiestrację lokalnego środowiska deweloperskiego, czy przygotowanie do rozmowy kwalifikacyjnej DevOps, zrozumienie sieci Compose, zależności między serwisami i wzorców produkcyjnych wyróżnia doświadczonych inżynierów.

Kluczowe informacje

Docker Compose wykorzystuje deklaratywny format YAML do definiowania serwisów, sieci i wolumenów w jednym pliku. Uruchomienie polecenia docker compose up uruchamia cały stos aplikacji z izolowaną siecią i trwałym przechowywaniem danych.

Architektura Docker Compose

Docker Compose działa na prostej zasadzie: definicja serwisów aplikacji w pliku compose.yaml (nowoczesna konwencja nazewnictwa zastępująca docker-compose.yml), a Compose zajmuje się tworzeniem kontenerów, konfiguracją sieci i zarządzaniem cyklem życia.

Specyfikacja Docker Compose definiuje trzy podstawowe koncepty:

  • Serwisy: Konfiguracje kontenerów zawierające obraz, kontekst budowania, zmienne środowiskowe i limity zasobów
  • Sieci: Izolowane kanały komunikacyjne między serwisami
  • Wolumeny: Trwałe przechowywanie danych przetrwające restart kontenerów
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

Ta konfiguracja demonstruje kilka wzorców gotowych do produkcji: health checks dla prawidłowej kolejności uruchamiania, Docker secrets dla wrażliwych danych, nazwane wolumeny dla trwałości oraz jawne definicje sieci.

Sieci Docker Compose - szczegółowe omówienie

Domyślnie Compose tworzy pojedynczą sieć dla aplikacji. Wszystkie serwisy dołączają do tej sieci i mogą komunikować się ze sobą używając nazwy serwisu jako hostname. Zrozumienie tego modelu sieciowego jest fundamentalne dla późniejszej migracji do Kubernetes.

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

Flaga internal: true uniemożliwia sieci backend dostęp do zewnętrznego internetu. Serwis frontend łączy obie sieci, działając jako jedyny punkt wejścia. Ta segmentacja sieci odzwierciedla praktyki bezpieczeństwa produkcyjnego.

Rozpoznawanie DNS

Wbudowany serwer DNS Dockera automatycznie rozpoznaje nazwy serwisów. Serwis api łączy się z bazą danych pod adresem db:5432 bez żadnej ręcznej konfiguracji IP.

Multi-stage builds z Compose

Obrazy produkcyjne powinny być minimalne. Multi-stage builds w połączeniu z profilami Compose umożliwiają różne konfiguracje dla środowiska deweloperskiego i produkcyjnego.

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

# Etap 2: Produkcja
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"]

# Etap 3: Rozwój
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}

Uruchomienie BUILD_TARGET=development COMPOSE_PROFILES=dev docker compose up startuje konfigurację deweloperską z hot reload.

Zależności serwisów i health checks

Dyrektywa depends_on kontroluje kolejność uruchamiania, ale start kontenerów nie oznacza gotowości serwisów. Health checks rozwiązują ten problem synchronizacji — wzorzec często poruszany podczas rozmów rekrutacyjnych DevOps.

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

Istnieją trzy warunki zależności:

  • service_started: Domyślny, kontener został uruchomiony
  • service_healthy: Health check przeszedł pomyślnie
  • service_completed_successfully: Kontener zakończył się kodem 0 (dla kontenerów init)

Gotowy na rozmowy o DevOps?

Ćwicz z naszymi interaktywnymi symulatorami, flashcards i testami technicznymi.

Docker Compose w środowisku deweloperskim

Środowiska deweloperskie korzystają z bind mounts, nadpisywania zmiennych środowiskowych i narzędzi debugowania. Plik compose.override.yaml automatycznie łączy się z compose.yaml.

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

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

  db:
    ports:
      - "5432:5432"

Anonimowy wolumen /app/node_modules zapobiega nadpisaniu zainstalowanych zależności kontenera przez node_modules hosta.

Wzorce wdrożeń produkcyjnych

Docker Compose sprawdza się przy wdrożeniach produkcyjnych na pojedynczym hoście. Dla orkiestracji wielohostowej Kubernetes z Helm zapewnia lepsze skalowanie, ale Compose pozostaje odpowiedni dla mniejszych aplikacji.

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

Klucz deploy konfiguruje limity zasobów, liczbę replik i polityki restartowania. Uruchomienie docker compose -f compose.prod.yaml up -d startuje stos produkcyjny w trybie odłączonym.

Zmienne środowiskowe i zarządzanie sekretami

Wrażliwa konfiguracja wymaga odpowiedniego podejścia. Docker Compose wspiera różne metody, od plików .env po Docker secrets.

bash
# .env
POSTGRES_PASSWORD=dev_password_only
API_SECRET_KEY=local_dev_key
yaml
# compose.yaml
services:
  api:
    environment:
      - API_SECRET_KEY  # Dziedziczy ze shella lub .env
      - DATABASE_URL=postgres://user:${POSTGRES_PASSWORD}@db:5432/app
    env_file:
      - ./config/api.env

Dla produkcji Docker secrets zapewnia lepsze bezpieczeństwo poprzez montowanie wrażliwych danych jako plików zamiast zmiennych środowiskowych:

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
Uwaga bezpieczeństwa

Nigdy nie commituj plików .env zawierających produkcyjne sekrety do systemu kontroli wersji. Do wdrożeń produkcyjnych wykorzystuj zewnętrzne rozwiązania do zarządzania sekretami, takie jak HashiCorp Vault lub usługi dostawców chmurowych.

Popularne pytania rekrutacyjne DevOps o Docker Compose

Rekruterzy testują zrozumienie koncepcji Compose poprzez praktyczne scenariusze. Te pytania pojawiają się często na rozmowach o stanowiska DevOps i platform engineering.

P: Jak komunikują się kontenery w sieci Compose?

Docker tworzy dedykowaną sieć bridge dla każdego projektu Compose. Serwisy komunikują się używając nazw serwisów jako hostnames. Wbudowany serwer DNS rozpoznaje te nazwy na adresy IP kontenerów. Ruch zewnętrzny dociera do serwisów tylko przez jawnie opublikowane porty.

P: Co się dzieje po uruchomieniu docker compose up z istniejącymi kontenerami?

Compose porównuje aktualną konfigurację z działającymi kontenerami. Niezmienione serwisy kontynuują działanie. Zmodyfikowane serwisy są odtwarzane z nowymi ustawieniami. Nowe serwisy startują od nowa. Usunięte serwisy są zatrzymywane i usuwane.

P: Jak obsługiwać migracje bazy danych w Compose?

Istnieją dwa wzorce. Pierwszy wykorzystuje kontener init z zależnością service_completed_successfully:

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

  api:
    depends_on:
      migrate:
        condition: service_completed_successfully

Drugi polega na włączeniu logiki migracji do skryptu startowego aplikacji, sprawdzającego i aplikującego oczekujące migracje przed akceptowaniem ruchu.

P: Czym różnią się wolumeny od bind mounts?

Nazwane wolumeny są zarządzane przez Dockera, przechowywane w /var/lib/docker/volumes i przenośne między hostami. Bind mounts mapują katalogi hosta bezpośrednio do kontenerów, przydatne w developmencie, ale zależne od środowiska. Wolumeny wspierają sterowniki dla zdalnego przechowywania jak NFS lub chmurowe block storage.

P: Jaka jest różnica między docker-compose a docker compose?

docker-compose z łącznikiem to samodzielne narzędzie V1 oparte na Pythonie, obecnie przestarzałe. docker compose ze spacją to implementacja V2 oparta na Go, zintegrowana z Docker CLI. V2 jest szybsza, w pełni wspiera specyfikację Compose i jest aktywnie rozwijana.

Debugowanie aplikacji Compose

Rozwiązywanie problemów z konteneryzowanymi aplikacjami wymaga specyficznych technik. Te polecenia ujawniają, co dzieje się wewnątrz stosu Compose:

bash
# Wyświetl logi ze wszystkich serwisów
docker compose logs -f

# Logi z konkretnego serwisu ze znacznikami czasu
docker compose logs -f --timestamps api

# Wykonaj polecenie w działającym kontenerze
docker compose exec api sh

# Uruchom jednorazowe polecenie (startuje nowy kontener)
docker compose run --rm api npm test

# Wyświetl wykorzystanie zasobów
docker compose top
docker stats

# Sprawdź konfigurację sieci
docker network inspect project_backend

# Waliduj plik compose
docker compose config

Polecenie docker compose config łączy wszystkie pliki compose i pokazuje finalną konfigurację — nieocenione przy debugowaniu problemów z interpolacją zmiennych.

Podsumowanie

  • Docker Compose definiuje wielokontenerowe aplikacje w pojedynczym pliku YAML z serwisami, sieciami i wolumenami
  • Serwisy komunikują się przez DNS używając nazw serwisów jako hostnames w domyślnej sieci bridge
  • Health checks z warunkiem service_healthy zapewniają prawidłową kolejność uruchamiania
  • Plik compose.override.yaml służy do ustawień deweloperskich jak bind mounts i porty debugowania
  • Wdrożenia produkcyjne korzystają z limitów zasobów, polityk restartowania i Docker secrets dla wrażliwych danych
  • CLI docker compose (V2) zastępuje przestarzałe docker-compose (V1) oferując lepszą wydajność i funkcje

Zacznij ćwiczyć!

Sprawdź swoją wiedzę z naszymi symulatorami rozmów i testami technicznymi.

Tagi

#docker
#docker compose
#devops
#kontenery
#sieci
#rekrutacja

Udostępnij

Powiązane artykuły