guides/docker
Infrastruktur · Containere · Self-hosting

Docker

Container-runtime og fundamentet under stort set alle selvhostede tjenester. Pak en applikation med alle dens afhængigheder i et isoleret, reproducerbart image og kør det ens på enhver Linux-host.

Engine: Open Source Linux Docker Inc.
Imageuforanderlig skabelon
Containerkørende instans
Composemulti-container stacks

Begreber

Tre kerneord du møder hele tiden: et image er en uforanderlig skabelon (kode + afhængigheder), en container er en kørende instans af et image, og Compose beskriver en eller flere containere deklarativt i en YAML-fil så hele stacken starter med én kommando.

Til din stack: Både n8n og Miniflux deployes nemmest som Docker Compose-stacks — denne guide er fundamentet for begge.

Installation

Ubuntu / Debian

Brug Dockers officielle apt-repo frem for distro-pakken — den er nyere og inkluderer Compose v2 som plugin.

1 · Fjern gamle pakker & tilføj forudsætninger
sudo apt remove docker docker-engine docker.io containerd runc # hvis til stede
sudo apt update
sudo apt install ca-certificates curl gnupg -y
2 · Tilføj Dockers GPG-nøgle & repo
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) \
  signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
På Zorin/Debian-derivater: hvis $VERSION_CODENAME ikke genkendes af repoet, sæt det manuelt til den Ubuntu/Debian-base din version bygger på (fx noble eller bookworm).
3 · Installér Engine + Compose-plugin
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin -y
4 · Verificér
sudo docker run --rm hello-world
docker compose version

Post-install

Kør Docker uden sudo og lad daemonen starte ved boot.

Egen bruger i docker-gruppe
sudo usermod -aG docker $USER
# log ud/ind eller:
newgrp docker
Aktivér ved boot
sudo systemctl enable --now docker
Sikkerhedsnote: Medlemskab af docker-gruppen svarer reelt til root-adgang (man kan montere værtsfilsystemet ind i en container). Giv kun betroede brugere adgang, og overvej rootless-mode på multi-user-systemer.

Docker Compose

deklarativt

Beskriv din stack i compose.yaml og styr den med docker compose. Eksempel-skelet:

compose.yaml (minimal)
services:
  app:
    image: nginx:latest
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - ./data:/usr/share/nginx/html:ro
    networks: [ web ]

networks:
  web:
Bind til 127.0.0.1 så porten kun er lokal og kun eksponeres via din Nginx-reverse-proxy — ikke direkte mod internettet.
KommandoFunktion
docker compose up -dStart stack i baggrunden (detached)
docker compose downStop og fjern containere + netværk
docker compose pullHent nyeste images
docker compose logs -fFølg logs live
docker compose psStatus for stackens services
docker compose restartGenstart services
docker compose exec app shÅbn shell i en kørende container
Opdateringsrutine: docker compose pull && docker compose up -d henter nye images og genskaber kun de containere der ændrede sig.

CLI-reference

KommandoFunktion
docker ps / docker ps -aKørende / alle containere
docker imagesListe lokale images
docker logs -f NAMEFølg en containers logs
docker exec -it NAME shInteraktiv shell i container
docker stop / start / restart NAMELivscyklus-styring
docker rm NAME / docker rmi IMAGEFjern container / image
docker inspect NAMEFuld JSON-metadata (netværk, mounts, config)
docker statsLive CPU/RAM/IO pr. container
docker system dfDiskforbrug fordelt på images/containere/volumes
docker system prune -aRyd ubrugte images/containere/netværk (frigør plads)
Pas på prune -a: Den fjerner alle images der ikke er i brug af en container — også dem du vil beholde. Tilføj --volumes kun hvis du bevidst vil slette ikke-monterede volumes (kan betyde datatab).

Netværk

Containere på samme bruger-definerede netværk kan nå hinanden via servicenavn som hostname — det er sådan n8n finder sin database.

TypeBrug
bridge (default)Standard isoleret netværk pr. Compose-stack; service-navn = DNS
hostDeler værtens netværksstak direkte (ingen isolation — undgå hvis muligt)
noneIngen netværk — fuld isolation
internalBridge uden udgående internet — godt til databaser
Mønster: Læg databasen på et internal-netværk så den ikke kan nå internettet, og applikationen på både det interne og et proxy-netværk. Eksponér aldrig databaseporten på værten.

Volumes & persistens

Containere er flygtige — data der skal overleve en genskabelse skal i et volume eller bind-mount.

Named volume (Docker-styret)
docker volume create n8n_data
docker volume ls
docker volume inspect n8n_data
Bind-mount (vært-sti)
# i compose: ./data:/app/data
# giver dig direkte adgang til filerne på værten
Backup: Named volumes ligger under /var/lib/docker/volumes/. Til din restic/pCloud-stack kan du enten backuppe den sti, eller bedre: docker compose exec db pg_dump … for konsistente database-dumps frem for at kopiere rå filer mens databasen kører.

Hærdning

KontrolAnbefaling
Port-bindingBind til 127.0.0.1, eksponér kun via reverse-proxy
restart-policyunless-stopped så tjenester kommer op efter reboot
Image-tagsPin til konkrete versioner, ikke blindt latest, i produktion
read-onlyread_only: true + tmpfs hvor muligt
capabilitiescap_drop: [ALL] og tilføj kun det nødvendige
no-new-privilegessecurity_opt: [no-new-privileges:true]
UFWBemærk: Docker manipulerer iptables og kan omgå UFW-regler — bind til localhost frem for at stole på UFW alene
OpdateringRegelmæssig pull + genskab; overvåg base-image-CVE'er
Docker + UFW-fælden: Docker skriver sine egne iptables-regler og kan publicere porte forbi dine UFW-regler. Hvis du binder en port til 0.0.0.0, er den ofte åben mod internettet uanset UFW. Løsningen: bind altid til 127.0.0.1:PORT for interne tjenester, eller brug ufw-docker-projektet til at rette regelrækkefølgen.