Servery a DevOps

Docker Compose: webová aplikace a PostgreSQL v jednom souboru

Praktický compose.yaml pro webovou aplikaci s PostgreSQL a Redisem – sítě, volumes, healthcheck, depends_on, .env, nasazení na VPS za Nginx a užitečné příkazy.

12. 10. 2026 · 4 min čtení

Jakmile má aplikace víc částí – backend, databázi, cache – ruční docker run s dlouhými parametry přestane bavit. Docker Compose popíše celé prostředí v jednom YAML souboru a spustí ho jedním příkazem. Ukážeme si kompletní, produkčně použitelný příklad.

Compose v2

Dnes se používá Compose v2 jako plugin Dockeru: příkaz docker compose (s mezerou). Starší docker-compose (s pomlčkou) je zastaralý. Doporučený název souboru je compose.yaml; docker-compose.yml funguje také. Klíč version: na začátku souboru už není potřeba.

docker compose version

Struktura projektu

app/
├── compose.yaml
├── .env
├── Dockerfile
└── src/...

Kompletní compose.yaml

services:
  web:
    build: .
    restart: unless-stopped
    env_file: .env
    environment:
      DATABASE_URL: postgres://app:${POSTGRES_PASSWORD}@db:5432/app
      REDIS_URL: redis://redis:6379/0
    ports:
      - "127.0.0.1:8000:8000"
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started

  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: app
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 5s
      timeout: 3s
      retries: 10

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - redisdata:/data

volumes:
  pgdata:
  redisdata:

A .env vedle něj (nepatří do Gitu):

POSTGRES_PASSWORD=dlouhe-nahodne-heslo
SECRET_KEY=dalsi-nahodny-retezec

Compose soubor .env ve stejné složce načte automaticky pro dosazení ${...} proměnných. env_file: navíc předá jeho obsah do kontejneru web.

Co je na tom důležité

Síť a jména služeb. Compose vytvoří pro projekt vlastní síť a služby se navzájem najdou podle jména. Aplikace se k databázi připojuje na hostitele db, ne localhost. To je nejčastější chyba začátečníků: localhost uvnitř kontejneru je kontejner sám.

Porty. Databáze a Redis nemají sekci ports – nejsou dostupné zvenku, jen pro ostatní služby v síti. Aplikace je publikovaná jen na 127.0.0.1, protože před ní bude Nginx. Port publikovaný na 0.0.0.0 by Docker otevřel do internetu i přes pravidla UFW.

depends_on s healthcheckem. Samotné depends_on čeká jen na start kontejneru, ne na to, až databáze přijímá spojení. condition: service_healthy počká na úspěšný healthcheck.

Volumes. Pojmenované volumes pgdata a redisdata přežijí docker compose down i rebuild. Zmizí jen s docker compose down -v – s tímto přepínačem opatrně.

Základní příkazy

docker compose up -d              # spustit vše na pozadí
docker compose up -d --build      # přestavět image a spustit
docker compose ps                 # stav služeb
docker compose logs -f web        # logy jedné služby
docker compose exec web sh        # shell v běžícím kontejneru
docker compose exec db psql -U app app
docker compose restart web
docker compose pull               # stáhnout novější image
docker compose down               # zastavit a odstranit kontejnery (data zůstanou)
docker compose config             # výsledná konfigurace po dosazení proměnných

docker compose config je skvělý na ladění – ukáže, jestli se proměnné z .env dosadily správně.

Migrace a jednorázové příkazy

docker compose run --rm web python manage.py migrate
docker compose run --rm web python manage.py createsuperuser

run --rm spustí nový dočasný kontejner a po dokončení ho smaže.

Vývoj vs. produkce

Pro lokální vývoj chcete připojený zdrojový kód a reload. Vytvořte compose.override.yaml, který Compose načte automaticky:

services:
  web:
    volumes:
      - ./src:/app/src
    command: ["python", "-m", "flask", "--app", "src.app", "run", "--host=0.0.0.0", "--port=8000", "--debug"]

Na serveru tento soubor nemějte (nebo spouštějte explicitně docker compose -f compose.yaml up -d).

Nginx před aplikací

Na VPS typicky běží Nginx přímo na hostiteli a řeší HTTPS (Certbot). Konfigurace serveru:

server {
    server_name app.example.cz;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Pak sudo certbot --nginx -d app.example.cz.

Aktualizace aplikace

git pull
docker compose up -d --build
docker image prune -f

Compose znovu vytvoří jen kontejnery, jejichž konfigurace nebo image se změnily. Databáze poběží dál. Tento postup můžete zautomatizovat podle článku o deployi přes GitHub Actions.

Časté problémy

Příznak Příčina
connection refused na localhost:5432 v kontejneru použijte db:5432
aplikace padá při startu, DB „ještě není“ chybí healthcheck + condition: service_healthy
po změně hesla v .env se nelze přihlásit Postgres čte POSTGRES_PASSWORD jen při první inicializaci prázdného volume
změny v kódu se neprojeví chybí --build

Nezapomeňte na zálohy databáze – volume není záloha. Postup najdete v článku Docker volumes a zálohy.