Gå direkte til indholdet

Cookieindstillinger

Vælg for hver type, hvilke cookies du tillader. Du kan altid ændre dit valg via Cookieindstillinger nederst på hver side. Privatlivspolitik

Nødvendige

Altid slået til

Nødvendige for at logge ind, gemme din kurv og huske dine valg. De er altid slået til.

Hvilke cookies?
  • weboke_sessie, weboke_klant, weboke_remember: din session og at forblive logget ind
  • weboke_basket: din kurv
  • wkBtwIncl: vise priser med eller uden moms
  • wok_cookies: dit cookievalg, 12 måneder

Måler, hvilken annonce der fører til et besøg eller en bestilling, så vi ikke betaler for annoncer, der ikke virker.

Hvilke cookies?
  • Google Ads via Google Tag Manager (_gcl_au, _gcl_aw), op til 90 dage
  • OpenAI Ads, annoncer i ChatGPT
  • wok_aff: hvilken partner der henviste dig til os (affiliateprogram), 60 dage

4,6

Land og sprog

Hvert land har sin egen side med landets priser og moms.

Se

Docker compose og firewallen

Modul 9: Docker og docker compose · Læsetid: 12 minutter

Læringsmål: Efter denne lektion kan du beskrive tjenester i en compose-fil, starte, opdatere og stoppe dem, og du kan forklare hvorfor publicerede porte fra Docker går uden om ufw, og hvordan du forhindrer det.

Centrale begreber: compose.yaml, services, image, ports, volumes, environment, .env, restart, networks, depends_on, healthcheck, docker compose up -d, pull, logs, down, forældet version:, Docker og ufw, DOCKER-USER, publicering på 127.0.0.1, hemmeligheder, docker.sock

Hvorfor compose?

Med docker run (lektion 9.2) starter du én container med en lang linje af indstillinger. Et rigtigt program består ofte af flere containere: selve programmet, en database, en reverse proxy. Hvis du skal huske de linjer og skrive dem igen efter en genstart eller opdatering, går det galt på et tidspunkt.

Docker Compose beskriver alle containere i et program i én fil: compose.yaml. Du lægger filen i sin egen mappe, for eksempel /srv/status/compose.yaml, og styrer det hele med docker compose. Filen er samtidig din dokumentation: hvad kører der, hvilket image, hvilke porte, hvor ligger dataene. Tag mappen med i din backup (lektion 8.1), så kan du genskabe programmet på en ny server på få minutter.

Pluginnet hedder docker compose (med mellemrum, version 2). Det gamle selvstændige program docker-compose (med bindestreg) er erstattet; du ser det stadig i gamle vejledninger. Feltet version: "3.8" øverst i gamle filer er også forældet: Compose bruger altid det nyeste skema og giver kun en advarsel ved version:.

Læs en compose-fil

Et eksempel med et program og en PostgreSQL-database:

# /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:

Trin for trin:

  • services: hver tjeneste bliver en container. Navnet (app, db) er også det hostnavn, containerne finder hinanden med. Compose opretter et eget netværk til programmet, så app forbinder til databasen på db:5432.
  • image: altid med et versionstag (lektion 9.1).
  • restart: hvad Docker gør, når containeren stopper, eller serveren genstarter. unless-stopped starter den igen, medmindre du selv har stoppet den med vilje. Uden en restart-politik kommer dit program ikke tilbage efter en genstart (lektion 4.2).
  • ports: kun appen publicerer en port, og kun på 127.0.0.1. Databasen publicerer ingenting: appen når den via det interne netværk. En database med ports: - "5432:5432" er en af de mest almindelige fejl (se nedenfor).
  • environment: indstillinger til programmet. Adgangskoden står ikke direkte i filen, men som ${DB_PASSWORD}.
  • volumes: det navngivne volume db-data bevarer databasen, når containeren bliver udskiftet.
  • depends_on med healthcheck: appen starter først, når databasen faktisk er klar, ikke bare startet.

Hemmeligheder i en .env-fil

Compose læser variabler som ${DB_PASSWORD} fra en fil .env i samme mappe:

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

Så står adgangskoden ikke i compose-filen, som du måske gemmer i Git eller indsætter på et forum for at få hjælp. Tilføj .env til .gitignore. Lav adgangskoden med en adgangskodeadministrator eller med openssl rand -base64 24.

Daglig brug

Alle kommandoer kører du i mappen med compose-filen:

anna@web1:/srv/notities$ sudo docker compose config     # tjek filen, variabler udfyldt
anna@web1:/srv/notities$ sudo docker compose up -d      # start alt (eller opdater til filen)
anna@web1:/srv/notities$ sudo docker compose ps         # status pr. tjeneste
anna@web1:/srv/notities$ sudo docker compose logs -f app
anna@web1:/srv/notities$ sudo docker compose pull       # hent nye images
anna@web1:/srv/notities$ sudo docker compose up -d      # erstat containere med de nye images
anna@web1:/srv/notities$ sudo docker compose down       # stop og fjern containere

down lader dine volumes være. down -v sletter også programmets volumes, og dermed din database. Skriv det kun, hvis du virkelig vil starte forfra.

docker compose config svarer til nginx -t og sshd -t: den viser, hvordan Compose forstår din fil, med alle variabler udfyldt, før du starter noget. Pas på ikke at indsætte outputtet nogen steder, for adgangskoderne står i det.

Docker går uden om ufw

Nu kommer det vigtigste sikkerhedspunkt i dette modul. I lektion 5.2 satte du ufw til "afvis alt undtagen SSH, 80 og 443". Du ville forvente, at en container med ports: - "5432:5432" så ikke kan nås. Sådan er det ikke.

Docker-dokumentationen siger det direkte: Docker og ufw bruger firewallregler på en måde, der ikke passer sammen. Når du publicerer en port, skriver Docker selv regler i kernens firewall. De regler sender trafikken videre til containeren (adresseoversættelse, DNAT), før ufw-reglerne bliver anvendt. Pakken går altså uden om ufw. ufw status viser intet særligt, mens porten kan nås fra hele internettet. Det samme gælder firewalld.

Desuden publicerer Docker uden adresse på 0.0.0.0 og [::], altså på både IPv4 og IPv6 (lektion 9.1).

Tre måder at gøre det rigtigt på, fra enkel til avanceret:

  1. Publicér ikke noget, der ikke behøver at være offentligt. Databaser, caches og interne tjenester får ingen ports:. Containere i samme compose-program når hinanden via det interne netværk.
  2. Publicér på loopback. "127.0.0.1:8081:8080". Så kan kun serveren selv komme til, og du sætter en reverse proxy (nginx eller Caddy, modul 7) foran, som lytter på 443. Docker kan også få det som standard: en daemon-indstilling får alle publicerede porte uden adresse til at lande på 127.0.0.1.
  3. Regler i kæden DOCKER-USER. Docker opretter en tom kæde DOCKER-USER, som bliver gennemløbet før Dockers egne regler. Der kan du selv tilføje regler, for eksempel "kun denne IP-adresse må nå de publicerede porte". Det er avanceret arbejde med iptables eller nftables og nemt at gøre forkert. For de fleste små servere er 1 og 2 nok.

Kontrollér altid udefra, som i lektion 5.1: nc -vz -w 3 <ip> 5432 fra din bærbare, eller kursuskontrollen i opgave Z5.1 og Z10.4.

To ting mere, du ikke gør

  • Montér ikke /var/run/docker.sock i en container, medmindre du ved præcis hvorfor. En container med adgang til Docker-socketten kan selv starte containere, også en med hele værtens disk (lektion 9.2). Nogle hjælpeprogrammer (dashboards, automatiske opdateringsværktøjer) beder om det; det svarer reelt til at give programmet root.
  • Ingen privileged: true eller network_mode: host, bare fordi en vejledning siger det. Begge fjerner størstedelen af containerens afskærmning. Brug dem kun, hvis udvikleren forklarer, hvorfor det er nødvendigt.

Opsummering

  • En compose-fil (compose.yaml) beskriver alle containere i et program; den er samtidig dokumentation og hører hjemme i din backup.
  • Brug versionstags, en restart-politik, navngivne volumes, et healthcheck hvor det er muligt, og hemmeligheder i en .env med rettigheder 600.
  • docker compose config, up -d, ps, logs, pull, down; down -v sletter også volumes.
  • Publicerede porte går uden om ufw og firewalld. Publicér kun det, der skal være offentligt, og ellers på 127.0.0.1 med en reverse proxy foran.
  • Ingen docker.sock, privileged eller network_mode: host uden en god grund.

Quiz

1. ufw er sat til "afvis alt undtagen 22, 80 og 443". Din compose-fil har ports: - "5432:5432" ved databasen. Kan databasen nås fra internettet?



2. Hvordan når containeren app databasen i samme compose-program, hvis databasen ikke publicerer en port?



3. Efter en genstart af serveren kører dine containere ikke længere. Hvad mangler sandsynligvis i compose-filen?



4. Hvad er forskellen på docker compose down og docker compose down -v?



5. Et dashboardprogram beder i sin vejledning om - /var/run/docker.sock:/var/run/docker.sock. Hvad betyder det for sikkerheden?



Opgave

Opgave Z9.3: Gennemgå en compose-fil. Eksempelfilen compose-nakijken.txt indeholder (som tekstfil) compose-filen til en lille webshop med en app, en database, en cache og et administrationsværktøj. Der er seks fejl i den, som er gennemgået i denne lektion eller i lektion 9.1 og 9.2. Angiv for hver nummereret blok af linjer, om den er rigtig eller forkert, og vælg for hver fejl den rigtige rettelse. Programmet sammenligner med den faste nøgle. Har du selv en compose-fil, så gennemgå den bagefter efter de samme punkter.

Opgave Z9.3: Gennemgå en compose-fil

Fil til denne opgave: compose-nakijken.txt





















Det, du udfylder, og hvad vi finder, gemmer vi ikke. Din browser husker dine svar, og om du har bestået opgaven. Er du logget ind, gemmer vi kun, at du (næsten) bestod opgaven, i Mine kurser; der kan du også slette det.

Læs mere

Et øjeblik…

Opsæt dine domæner

Angiv for hvert domæne navneserverne, tilknytningen til din hosting, og hvem der bliver ejer.

Indlæser dine domæner…