Przejdź do treści

Ustawienia plików cookie

Prosimy wybrać, na które rodzaje plików cookie Państwo zezwalają. Wybór można zmienić w dowolnym momencie w Ustawieniach plików cookie na dole każdej strony. Polityka prywatności

Niezbędne

Zawsze włączone

Potrzebne do logowania, zachowania koszyka i zapamiętania wyborów. Są zawsze włączone.

Jakie pliki cookie?
  • weboke_sessie, weboke_klant, weboke_remember: sesja i pozostanie zalogowanym
  • weboke_basket: koszyk
  • wkBtwIncl: wyświetlanie cen z VAT lub bez VAT
  • wok_cookies: wybór dotyczący plików cookie, 12 miesięcy

Mierzą, która reklama prowadzi do odwiedzin lub zamówienia, abyśmy nie płacili za reklamy, które nic nie dają.

Jakie pliki cookie?
  • Google Ads przez Google Tag Manager (_gcl_au, _gcl_aw), do 90 dni
  • OpenAI Ads, reklamy w ChatGPT
  • wok_aff: przez którego partnera trafili Państwo do nas (program partnerski), 60 dni

4,6

Kraj i język

Każdy kraj ma własną stronę z cenami i stawką VAT tego kraju.

Wyświetl

Docker compose i zapora sieciowa

Moduł 9: Docker i docker compose · Czas czytania: 12 min

Cel lekcji: Po tej lekcji potrafią Państwo opisać usługi w pliku compose, uruchamiać je, aktualizować i zatrzymywać, a także wyjaśnić, dlaczego opublikowane porty Dockera omijają ufw i jak temu zapobiec.

Kluczowe pojęcia: compose.yaml, services, image, ports, volumes, environment, .env, restart, networks, depends_on, healthcheck, docker compose up -d, pull, logs, down, przestarzałe version:, Docker i ufw, DOCKER-USER, publikowanie na 127.0.0.1, sekrety, docker.sock

Dlaczego compose?

Za pomocą docker run (lekcja 9.2) uruchamiają Państwo jeden kontener z długą linią opcji. Prawdziwa aplikacja składa się jednak często z kilku kontenerów: programu, bazy danych, reverse proxy. Zapamiętywanie tych poleceń i wpisywanie ich ponownie po restarcie lub aktualizacji prędzej czy później kończy się błędem.

Docker Compose opisuje wszystkie kontenery aplikacji w jednym pliku: compose.yaml. Plik ten umieszczają Państwo we własnym katalogu, na przykład /srv/status/compose.yaml, i zarządzają wszystkim za pomocą docker compose. Plik jest jednocześnie Państwa dokumentacją: co działa, jaki obraz, jakie porty, gdzie są dane. Wystarczy dodać ten katalog do kopii zapasowej (lekcja 8.1), a aplikację można odtworzyć na nowym serwerze w kilka minut.

Wtyczka nazywa się docker compose (ze spacją, wersja 2). Stary, osobny program docker-compose (z łącznikiem) został zastąpiony; można go jeszcze spotkać w starych poradnikach. Przestarzałe jest również pole version: "3.8" na początku starych plików: Compose zawsze używa najnowszego schematu, a przy version: wyświetla tylko ostrzeżenie.

Czytanie pliku compose

Przykład z programem i bazą danych 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 po kroku:

  • services: każda usługa staje się kontenerem. Nazwa (app, db) jest także nazwą hosta, po której kontenery się odnajdują. Compose tworzy dla aplikacji własną sieć, dlatego app łączy się z bazą danych pod adresem db:5432.
  • image: zawsze z tagiem wersji (lekcja 9.1).
  • restart: co Docker robi, gdy kontener się zatrzyma lub serwer zostanie zrestartowany. unless-stopped uruchamia go ponownie, chyba że zatrzymali go Państwo celowo. Bez polityki restartu aplikacja po restarcie serwera (lekcja 4.2) nie wróci.
  • ports: tylko aplikacja publikuje port i tylko na 127.0.0.1. Baza danych nie publikuje niczego: aplikacja dociera do niej przez sieć wewnętrzną. Baza danych z ports: - "5432:5432" to jeden z najczęściej popełnianych błędów (patrz niżej).
  • environment: ustawienia programu. Hasło nie jest w nim zapisane dosłownie, tylko jako ${DB_PASSWORD}.
  • volumes: nazwany wolumen db-data przechowuje bazę danych, gdy kontener zostanie wymieniony.
  • depends_on z healthcheck: aplikacja startuje dopiero wtedy, gdy baza danych jest naprawdę gotowa, a nie tylko uruchomiona.

Sekrety w pliku .env

Compose odczytuje zmienne takie jak ${DB_PASSWORD} z pliku .env w tym samym katalogu:

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

Dzięki temu hasła nie ma w pliku compose, który być może przechowują Państwo w Git lub wklejają na forum, prosząc o pomoc. Prosimy dodać .env do .gitignore. Hasło warto wygenerować menedżerem haseł lub poleceniem openssl rand -base64 24.

Codzienne użycie

Wszystkie polecenia wykonują Państwo w katalogu z plikiem compose:

anna@web1:/srv/notities$ sudo docker compose config     # sprawdź plik, zmienne podstawione
anna@web1:/srv/notities$ sudo docker compose up -d      # uruchom wszystko (lub zaktualizuj zgodnie z plikiem)
anna@web1:/srv/notities$ sudo docker compose ps         # status każdej usługi
anna@web1:/srv/notities$ sudo docker compose logs -f app
anna@web1:/srv/notities$ sudo docker compose pull       # pobierz nowe obrazy
anna@web1:/srv/notities$ sudo docker compose up -d      # zastąp kontenery nowymi obrazami
anna@web1:/srv/notities$ sudo docker compose down       # zatrzymaj i usuń kontenery

down pozostawia wolumeny. down -v usuwa także wolumeny aplikacji, a wraz z nimi bazę danych. Prosimy wpisywać to tylko wtedy, gdy naprawdę chcą Państwo zacząć od nowa.

docker compose config jest odpowiednikiem nginx -t i sshd -t: pokazuje, jak Compose rozumie Państwa plik, ze wszystkimi wstawionymi zmiennymi, zanim cokolwiek zostanie uruchomione. Prosimy nie wklejać nigdzie tego wyniku, ponieważ zawiera hasła.

Docker omija ufw

Teraz najważniejsza kwestia bezpieczeństwa w tym module. W lekcji 5.2 ustawili Państwo ufw na "odrzucaj wszystko oprócz SSH, 80 i 443". Można by się spodziewać, że kontener z ports: - "5432:5432" nie będzie wtedy osiągalny. Tak nie jest.

Dokumentacja Dockera mówi to wprost: Docker i ufw używają reguł zapory w sposób, który się ze sobą nie godzi. Gdy publikują Państwo port, Docker sam dodaje reguły do zapory jądra. Reguły te przekierowują ruch do kontenera (translacja adresów, DNAT), zanim zostaną zastosowane reguły ufw. Pakiet omija więc ufw. ufw status nie pokazuje niczego szczególnego, a port jest osiągalny z całego internetu. To samo dotyczy firewalld.

Ponadto Docker bez podanego adresu publikuje na 0.0.0.0 i [::], czyli zarówno na IPv4, jak i na IPv6 (lekcja 9.1).

Trzy sposoby, aby zrobić to dobrze, od prostego do złożonego:

  1. Nie publikować niczego, co nie musi być publiczne. Bazy danych, cache i usługi wewnętrzne nie dostają ports:. Kontenery w tej samej aplikacji compose docierają do siebie przez sieć wewnętrzną.
  2. Publikować na loopback. "127.0.0.1:8081:8080". Wtedy dostęp ma tylko sam serwer, a przed usługą stawiają Państwo reverse proxy (nginx lub Caddy, moduł 7), który nasłuchuje na 443. Docker może też mieć to jako ustawienie domyślne: opcja demona sprawia, że wszystkie opublikowane porty bez adresu trafiają na 127.0.0.1.
  3. Reguły w łańcuchu DOCKER-USER. Docker tworzy pusty łańcuch DOCKER-USER, który jest przetwarzany przed jego własnymi regułami. Mogą Państwo dodać tam własne reguły, na przykład "tylko ten adres IP ma dostęp do opublikowanych portów". To zaawansowana praca z iptables lub nftables, w której łatwo o błąd. Dla większości małych serwerów wystarczą sposoby 1 i 2.

Zawsze prosimy sprawdzać z zewnątrz, jak w lekcji 5.1: nc -vz -w 3 <ip> 5432 z Państwa laptopa lub kontrolą kursu z zadania Z5.1 i Z10.4.

Jeszcze dwie rzeczy, których się nie robi

  • Nie montować /var/run/docker.sock w kontenerze, chyba że dokładnie wiedzą Państwo dlaczego. Kontener z dostępem do gniazda Dockera może sam uruchamiać kontenery, także taki z całym dyskiem hosta (lekcja 9.2). Niektóre narzędzia (panele, automatyczne aktualizatory) tego wymagają; w praktyce oznacza to przyznanie temu programowi uprawnień root.
  • Nie używać privileged: true ani network_mode: host tylko dlatego, że tak każe poradnik. Obie opcje w dużej mierze usuwają izolację kontenera. Należy ich używać tylko wtedy, gdy twórca wyjaśnia, dlaczego są potrzebne.

Podsumowanie

  • Plik compose (compose.yaml) opisuje wszystkie kontenery aplikacji; jest jednocześnie dokumentacją i powinien znaleźć się w kopii zapasowej.
  • Prosimy używać tagów wersji, polityki restartu, nazwanych wolumenów, healthcheck tam, gdzie to możliwe, oraz sekretów w .env z uprawnieniami 600.
  • docker compose config, up -d, ps, logs, pull, down; down -v usuwa także wolumeny.
  • Opublikowane porty omijają ufw i firewalld. Publikować należy tylko to, co musi być publiczne, a w pozostałych przypadkach na 127.0.0.1 z reverse proxy przed usługą.
  • Bez docker.sock, privileged czy network_mode: host bez ważnego powodu.

Quiz

1. ufw jest ustawiony na "odrzucaj wszystko oprócz 22, 80 i 443". Państwa plik compose ma przy bazie danych ports: - "5432:5432". Czy baza danych jest osiągalna z internetu?



2. Jak kontener app dociera do bazy danych w tej samej aplikacji compose, jeśli baza danych nie publikuje portu?



3. Po restarcie serwera Państwa kontenery już nie działają. Czego prawdopodobnie brakuje w pliku compose?



4. Jaka jest różnica między docker compose down a docker compose down -v?



5. Program typu panel w swojej instrukcji wymaga - /var/run/docker.sock:/var/run/docker.sock. Co to oznacza dla bezpieczeństwa?



Zadanie

Zadanie Z9.3: Sprawdzanie pliku compose. W przykładowym pliku compose-nakijken.txt znajduje się (jako plik tekstowy) plik compose małego sklepu internetowego z aplikacją, bazą danych, cache i narzędziem administracyjnym. Zawiera on sześć błędów omówionych w tej lekcji lub w lekcjach 9.1 i 9.2. Prosimy wskazać dla każdego ponumerowanego bloku linii, czy jest poprawny, czy błędny, a przy każdym błędzie wybrać właściwą poprawkę. Program porównuje odpowiedzi ze stałym kluczem. Jeśli mają Państwo własny plik compose, prosimy następnie sprawdzić go pod kątem tych samych punktów.

Zadanie Z9.3: Sprawdzanie pliku compose

Plik do tego zadania: compose-nakijken.txt





















Wprowadzone dane i wyniki sprawdzania nie są zapisywane. Przeglądarka zapamiętuje udzielone odpowiedzi oraz informację, czy zadanie zostało zaliczone. Po zalogowaniu w Moje kursy zapisywana jest jedynie informacja, że zadanie zostało zaliczone (lub prawie zaliczone); tam można ją również usunąć.

Przeczytaj więcej

Chwileczkę…

Konfiguracja domen

Dla każdej domeny można ustawić serwery nazw, powiązanie z hostingiem oraz to, kto zostanie właścicielem.

Wczytywanie domen…