Modul 9 · 9.3
Docker compose in požarni zid
Modul 9: Docker in docker compose · Čas branja: 12 minut
Učni cilj: Po tej lekciji boste znali opisati storitve v datoteki compose, jih zagnati, posodobiti in ustaviti, pojasnili pa boste tudi, zakaj objavljena vrata Dockerja obidejo ufw in kako to preprečite.
Ključni pojmi: compose.yaml, services, image, ports, volumes, environment, .env, restart, networks, depends_on, healthcheck, docker compose up -d, pull, logs, down, opuščeni version:, Docker in ufw, DOCKER-USER, objava na 127.0.0.1, skrivnosti, docker.sock
Zakaj compose?
Z ukazom docker run (lekcija 9.2) zaženete en vsebnik z dolgo vrstico možnosti. Prava aplikacija je pogosto sestavljena iz več vsebnikov: programa, podatkovne baze in obratnega posredniškega strežnika. Če si morate te vrstice zapomniti in jih po ponovnem zagonu ali posodobitvi znova vtipkati, se slej ko prej kaj zalomi.
Docker Compose opiše vse vsebnike aplikacije v eni datoteki: compose.yaml. To datoteko postavite v lastno mapo, na primer /srv/status/compose.yaml, in vse upravljate z ukazom docker compose. Datoteka je hkrati Vaša dokumentacija: kaj teče, katera slika, katera vrata in kje so podatki. Če to mapo vključite v varnostno kopijo (lekcija 8.1), lahko aplikacijo na novem strežniku obnovite v nekaj minutah.
Vtičnik se imenuje docker compose (s presledkom, različica 2). Stari samostojni program docker-compose (s pomišljajem) je bil nadomeščen; srečate ga še v starih navodilih. Opuščeno je tudi polje version: "3.8" na vrhu starih datotek: Compose vedno uporablja najnovejšo shemo in pri version: izpiše le opozorilo.
Branje datoteke compose
Primer s programom in podatkovno bazo PostgreSQL:
# /srv/notities/compose.yaml
services:
app:
image: ghcr.io/example/notities:1.4
restart: unless-stopped
ports:
- "127.0.0.1:8081:8080"
environment:
DB_HOST: db
DB_USER: notities
DB_PASSWORD: ${DB_PASSWORD}
depends_on:
db:
condition: service_healthy
db:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_USER: notities
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U notities"]
interval: 10s
retries: 5
volumes:
db-data:Korak za korakom:
- services: vsaka storitev postane vsebnik. Ime (
app,db) je tudi ime gostitelja, prek katerega se vsebniki najdejo med seboj. Compose za aplikacijo ustvari lastno omrežje, zato seapps podatkovno bazo poveže nadb:5432. - image: vedno z oznako različice (lekcija 9.1).
- restart: kaj Docker naredi, ko se vsebnik ustavi ali se strežnik znova zažene.
unless-stoppedga znova zažene, razen če ste ga namerno ustavili sami. Brez pravila za ponovni zagon se Vaša aplikacija po ponovnem zagonu strežnika (lekcija 4.2) ne vrne. - ports: vrata objavi samo aplikacija, in to samo na
127.0.0.1. Podatkovna baza ne objavi ničesar: aplikacija jo doseže prek notranjega omrežja. Podatkovna baza zports: - "5432:5432"je ena najpogostejših napak (glejte spodaj). - environment: nastavitve za program. Geslo ni zapisano dobesedno, temveč kot
${DB_PASSWORD}. - volumes: poimenovani nosilec
db-dataohrani podatkovno bazo, ko je vsebnik zamenjan. - depends_on s healthcheck: aplikacija se zažene šele, ko je podatkovna baza res pripravljena, ne le zagnana.
Skrivnosti v datoteki .env
Compose prebere spremenljivke, kot je ${DB_PASSWORD}, iz datoteke .env v isti mapi:
# /srv/notities/.env
DB_PASSWORD=Kies-hier-een-lang-willekeurig-wachtwoordanna@web1:/srv/notities$ sudo chmod 600 .envTako geslo ni zapisano v datoteki compose, ki jo morda hranite v Gitu ali prilepite na forum, ko prosite za pomoč. Dodajte .env v .gitignore. Geslo ustvarite z upraviteljem gesel ali z ukazom openssl rand -base64 24.
Vsakdanja uporaba
Vse ukaze izvajate v mapi z datoteko compose:
anna@web1:/srv/notities$ sudo docker compose config # preverite datoteko, spremenljivke izpolnjene
anna@web1:/srv/notities$ sudo docker compose up -d # zaženite vse (ali posodobite glede na datoteko)
anna@web1:/srv/notities$ sudo docker compose ps # stanje po storitvah
anna@web1:/srv/notities$ sudo docker compose logs -f app
anna@web1:/srv/notities$ sudo docker compose pull # prenesite nove slike
anna@web1:/srv/notities$ sudo docker compose up -d # zamenjajte vsebnike z novimi slikami
anna@web1:/srv/notities$ sudo docker compose down # ustavite in odstranite vsebnikedown pusti Vaše nosilce pri miru. down -v izbriše tudi nosilce aplikacije in s tem Vašo podatkovno bazo. To vtipkajte samo, če res želite začeti znova.
docker compose config je enakovreden ukazoma nginx -t in sshd -t: pokaže, kako Compose razume Vašo datoteko, z vsemi izpolnjenimi spremenljivkami, še preden karkoli zaženete. Pazite, da izpisa nato ne prilepite nikamor, saj so v njem gesla.
Docker obide ufw
Zdaj pa najpomembnejša varnostna točka tega modula. V lekciji 5.2 ste ufw nastavili na »zavrni vse, razen SSH, 80 in 443«. Pričakovali bi, da vsebnik z ports: - "5432:5432" potem ni dosegljiv. Ni tako.
Dokumentacija Dockerja to pove naravnost: Docker in ufw uporabljata pravila požarnega zidu na način, ki med seboj ni združljiv. Ko objavite vrata, Docker sam vstavi pravila v požarni zid jedra. Ta pravila preusmerijo promet v vsebnik (prevajanje naslovov, DNAT), še preden se uporabijo pravila ufw. Paket torej gre mimo ufw. ufw status ne pokaže nič posebnega, čeprav so vrata dosegljiva iz celotnega interneta. Enako velja za firewalld.
Poleg tega Docker brez naslova objavlja na 0.0.0.0 in [::], torej na IPv4 in IPv6 (lekcija 9.1).
Trije načini, kako to narediti pravilno, od preprostega do zahtevnega:
- Ne objavljajte ničesar, kar ne rabi biti javno. Podatkovne baze, predpomnilniki in notranje storitve ne dobijo
ports:. Vsebniki v isti aplikaciji compose se dosežejo prek notranjega omrežja. - Objavljajte na povratni zanki (loopback).
"127.0.0.1:8081:8080". Tako lahko do storitve dostopa samo strežnik sam, pred njo pa postavite obratni posredniški strežnik (nginx ali Caddy, modul 7), ki posluša na 443. Docker lahko to nastavi tudi kot privzeto: nastavitev demona poskrbi, da vsa objavljena vrata brez naslova pristanejo na127.0.0.1. - Pravila v verigi DOCKER-USER. Docker ustvari prazno verigo
DOCKER-USER, ki se obdela pred njegovimi lastnimi pravili. Vanjo lahko sami vstavite pravila, na primer »samo ta naslov IP sme do objavljenih vrat«. To je zahtevnejše delo z iptables ali nftables, pri katerem se hitro zmotite. Za večino majhnih strežnikov zadoščata načina 1 in 2.
Vedno preverite od zunaj, kot v lekciji 5.1: nc -vz -w 3 <ip> 5432 s svojega prenosnika ali s preverjanjem tečaja pri nalogah Z5.1 in Z10.4.
Še dve stvari, ki jih ne počnete
- Ne priklapljajte
/var/run/docker.sockv vsebnik, razen če natančno veste, zakaj. Vsebnik z dostopom do vtičnice Dockerja lahko sam zaganja vsebnike, tudi takega s celotnim diskom gostitelja (lekcija 9.2). Nekatera orodja (nadzorne plošče, samodejni posodobitelji) to zahtevajo; to v bistvu pomeni, da temu programu dodelite pravice root. - Ne uporabljajte
privileged: truealinetwork_mode: hostsamo zato, ker tako piše v navodilih. Oboje večinoma odstrani izolacijo vsebnika. Uporabite ju le, če avtor pojasni, zakaj je to potrebno.
Povzetek
- Datoteka compose (
compose.yaml) opiše vse vsebnike aplikacije; je hkrati dokumentacija in sodi v Vašo varnostno kopijo. - Uporabljajte oznake različic, pravilo za ponovni zagon, poimenovane nosilce, healthcheck, kjer je mogoče, in skrivnosti v
.envs pravicami 600. docker compose config,up -d,ps,logs,pull,down;down -vizbriše tudi nosilce.- Objavljena vrata obidejo ufw in firewalld. Objavite samo, kar mora biti javno, sicer pa na
127.0.0.1z obratnim posredniškim strežnikom spredaj. - Brez docker.sock,
privilegedalinetwork_mode: hostbrez dobrega razloga.
Kviz
Naloga
Naloga Z9.3: Pregled datoteke compose. V primeru datoteke compose-nakijken.txt je (kot besedilna datoteka) datoteka compose majhne spletne trgovine z aplikacijo, podatkovno bazo, predpomnilnikom in skrbniškim orodjem. V njej je šest napak, ki so bile obravnavane v tej lekciji ali v lekcijah 9.1 in 9.2. Za vsak oštevilčen blok vrstic označite, ali je pravilen ali napačen, in pri vsaki napaki izberite pravilen popravek. Program odgovore primerja s fiksnim ključem. Če imate lastno datoteko compose, jo nato preglejte po istih točkah.
Za nadaljnje branje
- Dokumentacija Dockerja, How Compose works (compose.yaml): https://docs.docker.com/compose/intro/compose-application-model/
- Dokumentacija Dockerja, Version and name top-level elements: https://docs.docker.com/reference/compose-file/version-and-name/
- Dokumentacija Dockerja, Packet filtering and firewalls (Docker and ufw): https://docs.docker.com/engine/network/packet-filtering-firewalls/
- Dokumentacija Dockerja, Port publishing and mapping: https://docs.docker.com/engine/network/port-publishing/
- Dokumentacija Dockerja, Interpolation (spremenljivke in .env): https://docs.docker.com/reference/compose-file/interpolation/
- VPS: od prve prijave do varnega strežnika 6.2: Vaša delovna mapa s compose.yaml, .env in Caddy
- VPS: od prve prijave do varnega strežnika 6.3: Docker in požarni zid: varna objava vrat
