Loeng — Mitme teenuse käitamine koos
Kestus: ~35 minutit Tase: Algaste — eeldame et tead Docker build/run käske
Õpiväljundid
Pärast loengut oskad:
- selgitada miks reaalne rakendus vajab mitut konteinerit
- kirjeldada
docker-compose.ymlstruktuuri - käivitada ja peatada multi-container stack ühe käsuga
- eristada mis on teenus, võrk ja maht Compose'is
- põhjendada miks andmebaasi andmed lähevad volume'i, mitte konteinerisse
1. Miks mitu konteinerit?
Eelmisel nädalal pakkisime Flask rakenduse ühte image'isse ja käivitasime üksiku konteinerina. Väikeseks demoks sobib, aga päris rakendusel on rohkem osi: Flask vajab andmebaasi (PostgreSQL), ja tihti ka nginx'i ees, mis käsitleb HTTPS-i ja jagab liiklust.
Miks mitte panna kõik — Flask, PostgreSQL, nginx — ühte konteinerisse? Tehniliselt saab, praktikas halb mõte. Kui kõik on ühes: ei saa andmebaasi uuendada rakendust puudutamata, ei saa nginx'i restart'ida Flaski protsessi mõjutamata, ei saa üht komponenti eraldi skaleerida. Iga komponent oma konteineris = vastutus eraldatud.
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#ede7f6','primaryBorderColor':'#5e35b1','primaryTextColor':'#212121','lineColor':'#7e57c2'}}}%%
graph LR
U[Klient] -->|port 80| N[nginx]
N -->|web:5000| W[Flask web]
W -->|db:5432| D[(PostgreSQL)]
D -.->|püsib| V[volume pgdata]
2. docker-compose.yml — struktuur
Mitme konteineri käivitamine ükshaaval docker run-iga on tüütu ja veaohtlik — pordid, võrgud, järjekord tuleb iga kord meeles pidada. Compose kogub kogu kirjelduse ühte faili.
services:
flask:
build: .
ports:
- "5000:5000"
depends_on:
- postgres
networks:
- appnet
postgres:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- appnet
nginx:
image: nginx:latest
ports:
- "80:80"
depends_on:
- flask
networks:
- appnet
volumes:
pgdata:
networks:
appnet:
services kirjeldab kolme teenust. Flask ehitatakse kohapeal (build: .), postgres ja nginx tulevad valmis image'itena. ports seob konteineri pordi väljapoole — ainult flask ja nginx vajavad seda, postgres räägib ainult sisevõrgus. depends_on määrab käivitusjärjekorra — aga tähelepanu: see ootab ainult et konteiner käivituks, mitte et postgres oleks päriselt päringuteks valmis. Selle nüansi lahendab reaalne rakendus retry-loogikaga.
Warning
Compose on YAML. "Lihtne, nad ütlesid." Kaks tundi hiljem otsid, miks depends_on ei tööta — ja põhjus on üks tühik vale koha peal. Taane on Compose'is tähendus, mitte iluvõte. Kasuta redaktorit, mis taande näitab.
volumes defineerib pgdata mahu andmete säilitamiseks. networks loob appnet sisevõrgu, kus kõik kolm suhtlevad.
3. Põhikäsklused
docker compose up -d # käivita kõik teenused taustal, ehita puuduvad image'id
docker compose ps # mis teenused töötavad
docker compose logs flask # ühe teenuse logi
docker compose down # peata ja eemalda kõik konteinerid + võrk
down on üks käsk kolme asemel (mitte kolm docker stop + docker rm).
4. Võrgud
Compose loob teenuste vahele sisevõrgu, kus iga teenus on kättesaadav oma nime järgi. Flask koodis pole andmebaasi aadressiks IP, vaid nimi postgres:
postgres on DNS-nimi, mille Compose ise sisevõrku lahendab — töötab, sest mõlemad teenused on samas appnet võrgus.
Väljastpoolt on nähtav ainult see, mis on ports all. Meie näites flaski 5000 ja nginx'i 80. Postgres'il pole ports sektsiooni — andmebaas ei ole väljastpoolt üldse ligipääsetav, ainult sama stacki teenused näevad seda. See pole piirang, see on kaitse.
5. Volumes
Konteiner on ajutine. Kustutad postgres konteineri ja käivitad uue — sisemine failisüsteem on taas puhas, nagu image algselt oli. Kui andmebaasi andmed oleksid konteineri sees, kaoksid nad iga kord.
Volume hoiab andmed konteinerist väljaspool, host-masina kettal. Konteiner näeb volume't tavalise kataloogina, aga andmed elavad konteinerist sõltumatult. Kustutad konteineri, käivitad uue sama volume'iga — andmed on alles.
Seepärast on meie failis pgdata:/var/lib/postgresql/data — postgres kirjutab sinna, ja volume tagab et see püsib üle konteineri elutsükli.
6. Miks tööl oluline
Suur makse- või veebiteenus koosneb kümnetest komponentidest — backend, andmebaas, cache, sõnumijärjekord — igaüks eraldi konteinerina. Ükski ei tööta üksi, kõik sõltuvad üksteisest, ja kogu kooslus peab käivituma samamoodi arendaja masinal ja tootmises.
Compose teeb selle korratavaks. Uus meeskonnaliige ei paigalda käsitsi PostgreSQL'i, Redis'it ja kõike muud — üks fail, üks käsk (docker compose up -d), ja tal on sama keskkond mis kõigil teistel. Erinevused keskkondade vahel (paroolid, domeenid) tulevad keskkonnamuutujatest, mitte failistruktuuri muutmisest.
Kokkuvõte
- Iga komponent oma konteineris — rakendus, andmebaas, proxy eraldi, mitte üks suur konteiner
- docker-compose.yml kirjeldab kogu stacki ühes failis — teenused, pordid, sõltuvused, võrgud, volume'id
- Põhikäsklused:
up -d,down,logs,ps - Teenused leiavad üksteist nime järgi — Compose sisevõrgus
postgreson DNS-nimi, mitte IP - Väljapoole on nähtav ainult
portsall kirjas olev — andmebaas ilmaports-ita jääb sisevõrku - Andmebaasi andmed lähevad volume'i, mitte konteinerisse — konteiner ajutine, volume püsiv
Allikad
| Allikas | URL |
|---|---|
| Docker Compose | https://docs.docker.com/compose/ |
| Compose file referents | https://docs.docker.com/reference/compose-file/ |
| Compose Getting Started | https://docs.docker.com/compose/gettingstarted/ |
Versioonid (testitud, juuli 2026): Docker Compose v2.x, PostgreSQL postgres:16.
Järgmine: Praktikumis paned kokku Flask + PostgreSQL + nginx stacki.