Modul 7 — Virtualizace a kontejnery: Docker

30. Docker Compose pro multi-kontejnerové aplikace

Definice a spouštění vícekontejnerových aplikací pomocí Docker Compose a souboru docker-compose.yml.

Odhadovaná délka studia: 55 minut · Stav: nehotovo

Technologie: Docker

Úvod a kontext

Reálné aplikace se skoro nikdy neskládají z jediného kontejneru —
typická webová aplikace potřebuje samotnou aplikaci, databázi, případně
cache (Redis) a reverzní proxy. Spouštět a propojovat každý z těchto
kontejnerů ručně přes docker run s dlouhými seznamy přepínačů je
neúnosné a nereprodukovatelné. Docker Compose řeší přesně tento
problém — celou vícekontejnerovou aplikaci popíše v jednom
deklarativním souboru a spustí ji jedním příkazem.

Teorie

Co Compose řeší

Docker Compose je nástroj (dodávaný jako docker compose, součást
moderní instalace Dockeru) pro definici a řízení aplikací složených z
více kontejnerů, které spolu komunikují. Místo řady docker run
příkazů popíšete celou aplikaci v souboru docker-compose.yml — jaké
kontejnery (services) aplikace potřebuje, jak jsou propojené, jaké
porty a data sdílejí — a Compose podle tohoto popisu vše vytvoří,
nastartuje ve správném pořadí a propojí do společné sítě.

Struktura docker-compose.yml

Základní stavební kameny souboru:

services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://appka:heslo@db:5432/appka
    depends_on:
      - db
  db:
    image: postgres:16
    environment:
      - POSTGRES_USER=appka
      - POSTGRES_PASSWORD=heslo
      - POSTGRES_DB=appka
    volumes:
      - dbdata:/var/lib/postgresql/data

volumes:
  dbdata:
  • services — každá položka je jeden kontejner (v terminologii Compose
    "služba"); web a db výše jsou dvě samostatné služby.
  • build: . — tato služba se sestaví z Dockerfile v aktuálním adresáři
    (alternativa k image:, který by stáhl hotový image z registry).
  • environment — proměnné prostředí předané do kontejneru; zde
    aplikace web dostane připojovací řetězec k databázi, kde db je
    jméno služby, které Compose automaticky přeloží na IP adresu
    odpovídajícího kontejneru.
  • depends_on — určuje pořadí startu (Compose nejdřív nastartuje db,
    pak web); nezaručuje ale, že je databáze uvnitř db skutečně
    připravená přijímat spojení, jen že kontejner běží (na to existují
    tzv. healthchecks, viz pozdější lekce o Kubernetes).
  • volumes (nahoře na úrovni celého souboru) — pojmenovaný svazek
    dbdata, který přetrvá i po smazání kontejneru db, takže data
    databáze nezmizí při přebudování kontejneru.

Síťování mezi službami

Compose automaticky vytvoří pro celou aplikaci vlastní izolovanou síť a
připojí do ní všechny služby. Uvnitř této sítě mohou služby komunikovat
mezi sebou přes svá jména jako přes DNS záznamy — proto ve výše uvedeném
příkladu funguje db:5432 jako adresa databáze z pohledu služby web,
aniž by bylo nutné znát skutečnou IP adresu kontejneru (ta se navíc při
každém restartu může změnit).

Životní cyklus Compose aplikace

Compose spravuje celou aplikaci jako jednotku — jedním příkazem lze
všechny služby nastartovat, zastavit nebo kompletně odstranit včetně
vytvořené sítě (ale ne pojmenovaných volumes, pokud to není výslovně
požadováno — to je záměrná ochrana dat).

Praktický příklad

Uložení výše uvedeného docker-compose.yml do adresáře projektu vedle
Dockerfile z minulé lekce a spuštění celé aplikace:

docker compose up -d

-d opět znamená běh na pozadí. Compose při prvním spuštění sestaví
image služby web (protože má build: .), stáhne image postgres:16
pro službu db, vytvoří síť i pojmenovaný volume a nastartuje obě
služby.

Užitečné příkazy pro každodenní práci:

docker compose ps                 # stav služeb definovaných v projektu
docker compose logs -f web         # průběžné sledování logů jedné služby
docker compose exec web sh         # shell uvnitř běžící služby web
docker compose restart web         # restart jen jedné služby
docker compose down                # zastaví a odstraní kontejnery i síť
docker compose down -v             # totéž, navíc smaže i volumes (pozor: nevratně smaže data databáze)

Škálování jedné služby na víc instancí (užitečné např. pro víc kopií
aplikačního serveru za load balancerem):

docker compose up -d --scale web=3

Ověření, že aplikace web vidí databázi db přes jméno služby (spuštěno
zevnitř kontejneru web):

docker compose exec web sh -c "getent hosts db"

Výstup ukáže interní IP adresu přiřazenou kontejneru db v rámci sítě
vytvořené Composem — důkaz, že jména služeb fungují jako DNS.

Shrnutí

Docker Compose popisuje vícekontejnerovou aplikaci deklarativně v
docker-compose.yml — jaké služby aplikace má, jak jsou propojené a
jaká data sdílejí — a spouští ji jedním příkazem docker compose up
místo ruční sekvence docker run příkazů. Compose automaticky vytváří
společnou síť, ve které se služby vidí navzájem přes svá jména, a
pojmenované volumes chrání data (např. obsah databáze) před ztrátou při
přebudování kontejnerů.

Kontrolní otázky

  1. K čemu slouží klíč depends_on a co negarantuje?
  2. Jak služba web v příkladu najde databázi db, aniž by znala její
    IP adresu?
  3. Jaký je rozdíl mezi docker compose down a docker compose down -v?
  4. Napište docker-compose.yml fragment přidávající třetí službu
    redis (image redis:7-alpine), na které bude služba web záviset.

Lekce na sebe nejsou zamčené — libovolnou lekci můžete otevřít i označit jako hotovou v jakémkoliv pořadí.