Přejít na obsah

Nastavení cookies

Zvolte, které druhy cookies povolíte. Svou volbu můžete kdykoli změnit přes Nastavení cookies v dolní části každé stránky. Prohlášení o ochraně osobních údajů

Nezbytné

Vždy zapnuté

Potřebné pro přihlášení, uchování košíku a zapamatování vašich voleb. Jsou vždy zapnuté.

Které cookies?
  • weboke_sessie, weboke_klant, weboke_remember: vaše relace a trvalé přihlášení
  • weboke_basket: váš košík
  • wkBtwIncl: zobrazení cen s DPH nebo bez DPH
  • wok_cookies: vaše volba cookies, 12 měsíců

Měří, která reklama vede k návštěvě nebo objednávce, abychom neplatili za reklamy, které nic nepřinášejí.

Které cookies?
  • Google Ads přes Google Tag Manager (_gcl_au, _gcl_aw), až 90 dní
  • OpenAI Ads, reklamy v ChatGPT
  • wok_aff: partner, který vás k nám doporučil (partnerský program), 60 dní

4,6

Země a jazyk

Každá země má vlastní web s cenami a DPH dané země.

Zobrazit

Docker compose a firewall

Modul 9: Docker a docker compose · Doba čtení: 12 min.

Cíl lekce: Po této lekci dokážete popsat služby v souboru compose, spustit je, aktualizovat a zastavit. Také vysvětlíte, proč publikované porty Dockeru obcházejí ufw a jak tomu zabránit.

Klíčové pojmy: compose.yaml, services, image, ports, volumes, environment, .env, restart, networks, depends_on, healthcheck, docker compose up -d, pull, logs, down, zastaralé version:, Docker a ufw, DOCKER-USER, publikování na 127.0.0.1, tajné údaje, docker.sock

Proč compose?

Pomocí docker run (lekce 9.2) spustíte jeden kontejner s dlouhým řádkem voleb. Skutečná aplikace se ale často skládá z více kontejnerů: programu, databáze a reverzní proxy. Pamatovat si tyto řádky a po restartu nebo aktualizaci je znovu psát se jednou nepovede.

Docker Compose popisuje všechny kontejnery aplikace v jednom souboru: compose.yaml. Tento soubor uložíte do vlastní složky, například /srv/status/compose.yaml, a vše spravujete pomocí docker compose. Soubor je zároveň Vaší dokumentací: co běží, jaký image, jaké porty, kde jsou uložena data. Zahrňte tuto složku do zálohy (lekce 8.1) a aplikaci pak obnovíte na novém serveru za pár minut.

Plugin se jmenuje docker compose (s mezerou, verze 2). Starý samostatný program docker-compose (se spojovníkem) byl nahrazen; uvidíte ho ještě ve starých návodech. Zastaralé je i pole version: "3.8" na začátku starých souborů: Compose vždy používá nejnovější schéma a u version: zobrazí jen varování.

Jak číst soubor compose

Příklad s programem a databází 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:

Krok za krokem:

  • services: každá služba se stane kontejnerem. Název (app, db) je zároveň názvem hostitele, podle kterého se kontejnery navzájem najdou. Compose vytvoří pro aplikaci vlastní síť, takže app se připojí k databázi na db:5432.
  • image: vždy s tagem verze (lekce 9.1).
  • restart: co Docker udělá, když se kontejner zastaví nebo se server restartuje. unless-stopped ho znovu spustí, pokud jste ho sami vědomě nezastavili. Bez pravidla pro restart se Vaše aplikace po restartu (lekce 4.2) nevrátí.
  • ports: port publikuje jen aplikace, a to pouze na 127.0.0.1. Databáze nepublikuje nic: aplikace se k ní dostane přes interní síť. Databáze s ports: - "5432:5432" je jednou z nejčastějších chyb (viz níže).
  • environment: nastavení pro program. Heslo v něm není doslovně, ale jako ${DB_PASSWORD}.
  • volumes: pojmenovaný svazek db-data uchová databázi, i když je kontejner nahrazen.
  • depends_on s healthcheck: aplikace se spustí, až když je databáze opravdu připravená, ne jen spuštěná.

Tajné údaje v souboru .env

Compose načítá proměnné jako ${DB_PASSWORD} ze souboru .env ve stejné složce:

# /srv/notities/.env
DB_PASSWORD=Kies-hier-een-lang-willekeurig-wachtwoord
anna@web1:/srv/notities$ sudo chmod 600 .env

Heslo tak není v souboru compose, který možná uchováváte v Gitu nebo vkládáte na fórum, když žádáte o pomoc. Přidejte .env do .gitignore. Heslo vytvořte ve správci hesel nebo pomocí openssl rand -base64 24.

Každodenní používání

Všechny příkazy spouštějte ve složce se souborem compose:

anna@web1:/srv/notities$ sudo docker compose config     # zkontrolovat soubor, proměnné doplněny
anna@web1:/srv/notities$ sudo docker compose up -d      # spustit vše (nebo aktualizovat podle souboru)
anna@web1:/srv/notities$ sudo docker compose ps         # stav jednotlivých služeb
anna@web1:/srv/notities$ sudo docker compose logs -f app
anna@web1:/srv/notities$ sudo docker compose pull       # stáhnout nové images
anna@web1:/srv/notities$ sudo docker compose up -d      # nahradit kontejnery novými images
anna@web1:/srv/notities$ sudo docker compose down       # zastavit a odstranit kontejnery

down ponechá Vaše svazky. down -v odstraní i svazky aplikace, a tím i Vaši databázi. Zadejte to jen tehdy, když opravdu chcete začít znovu.

docker compose config je obdobou nginx -t a sshd -t: ukáže, jak Compose rozumí Vašemu souboru, se všemi dosazenými proměnnými, ještě než cokoli spustíte. Dejte pozor, abyste výstup nikam nevkládali, protože obsahuje hesla.

Docker obchází ufw

Nyní nejdůležitější bezpečnostní bod tohoto modulu. V lekci 5.2 jste nastavili ufw na "vše zakázat kromě SSH, 80 a 443". Čekali byste, že kontejner s ports: - "5432:5432" pak nebude dostupný. Není tomu tak.

Dokumentace Dockeru to říká doslova: Docker a ufw používají pravidla firewallu způsobem, který se navzájem nesnáší. Když publikujete port, Docker sám vloží pravidla do firewallu jádra. Tato pravidla přesměrují provoz do kontejneru (překlad adres, DNAT) dříve, než se uplatní pravidla ufw. Paket tedy ufw obejde. ufw status neukáže nic zvláštního, přestože je port dostupný z celého internetu. Totéž platí pro firewalld.

Navíc Docker bez uvedené adresy publikuje na 0.0.0.0 a [::], tedy na IPv4 i IPv6 (lekce 9.1).

Tři způsoby, jak to udělat správně, od jednoduchého po složitý:

  1. Nepublikujte nic, co nemusí být veřejné. Databáze, cache a interní služby nedostanou ports:. Kontejnery ve stejné aplikaci compose se navzájem dosáhnou přes interní síť.
  2. Publikujte na loopback. "127.0.0.1:8081:8080". Pak se k nim dostane jen samotný server a před ně postavíte reverzní proxy (nginx nebo Caddy, modul 7), která naslouchá na 443. Docker to může mít i jako výchozí nastavení: nastavení démona zajistí, že všechny publikované porty bez adresy skončí na 127.0.0.1.
  3. Pravidla v řetězci DOCKER-USER. Docker vytvoří prázdný řetězec DOCKER-USER, který se prochází před jeho vlastními pravidly. Tam můžete vložit vlastní pravidla, například "na publikované porty smí jen tato IP adresa". Jde o pokročilou práci s iptables nebo nftables, ve které se snadno udělá chyba. Pro většinu malých serverů stačí způsoby 1 a 2.

Vždy kontrolujte zvenku, jako v lekci 5.1: nc -vz -w 3 <ip> 5432 z Vašeho notebooku, nebo kontrolou kurzu v úkolu Z5.1 a Z10.4.

Ještě dvě věci, které nedělejte

  • Nepřipojujte /var/run/docker.sock do kontejneru, pokud přesně nevíte proč. Kontejner s přístupem k socketu Dockeru může sám spouštět kontejnery, i takový, který má celý disk hostitele (lekce 9.2). Některé nástroje (dashboardy, automatické aktualizátory) to vyžadují; v podstatě tím danému programu dáváte práva roota.
  • Nepoužívejte privileged: true ani network_mode: host jen proto, že to říká návod. Obojí z velké části ruší izolaci kontejneru. Používejte to jen tehdy, když autor vysvětlí, proč je to nutné.

Shrnutí

  • Soubor compose (compose.yaml) popisuje všechny kontejnery aplikace; je zároveň dokumentací a patří do Vaší zálohy.
  • Používejte tagy verzí, pravidlo pro restart, pojmenované svazky, healthcheck tam, kde to jde, a tajné údaje v .env s oprávněním 600.
  • docker compose config, up -d, ps, logs, pull, down; down -v odstraní i svazky.
  • Publikované porty obcházejí ufw i firewalld. Publikujte jen to, co musí být veřejné, a jinak na 127.0.0.1 s reverzní proxy před tím.
  • Žádný docker.sock, privileged ani network_mode: host bez dobrého důvodu.

Kvíz

1. ufw je nastaven na "vše zakázat kromě 22, 80 a 443". Váš soubor compose má u databáze ports: - "5432:5432". Je databáze dostupná z internetu?



2. Jak se kontejner app dostane k databázi ve stejné aplikaci compose, když databáze nepublikuje žádný port?



3. Po restartu serveru už Vaše kontejnery neběží. Co v souboru compose nejspíš chybí?



4. Jaký je rozdíl mezi docker compose down a docker compose down -v?



5. Dashboard ve svém návodu požaduje - /var/run/docker.sock:/var/run/docker.sock. Co to znamená pro bezpečnost?



Úkol

Úkol Z9.3: Kontrola souboru compose. Ve vzorovém souboru compose-nakijken.txt je (jako textový soubor) soubor compose malého e-shopu s aplikací, databází, cache a nástrojem pro správu. Obsahuje šest chyb, které byly probrány v této lekci nebo v lekcích 9.1 a 9.2. U každého očíslovaného bloku řádků uveďte, zda je správně, nebo chybně, a u každé chyby zvolte správnou opravu. Program Vaše odpovědi porovná s pevným klíčem. Máte-li vlastní soubor compose, projděte ho potom podle stejných bodů.

Úkol Z9.3: Kontrola souboru compose

Soubor k tomuto úkolu: compose-nakijken.txt





















Co vyplníte a co zjistíme, neukládáme. Váš prohlížeč si pamatuje Vaše odpovědi a to, zda jste úkol splnili. Pokud jste přihlášeni, ukládáme v sekci Moje kurzy pouze to, že jste úkol měli (téměř) správně; i to tam můžete odstranit.

Doporučujeme k přečtení

Chvíli strpení…

Nastavení vašich domén

U každé domény nastavte jmenné servery, propojení s hostingem a to, kdo bude držitelem.

Načítání vašich domén…