guides/n8n
Automatisering · Workflows · Self-hosting

n8n · Docker

Self-hosted workflow-automatisering med visuel node-editor. Forbind API'er, databaser og tjenester i pipelines uden at hoste det hos tredjepart. Denne guide kører n8n som Docker Compose-stack med PostgreSQL bagved.

Fair-code-licens Docker / Linux n8n GmbH
PostgreSQLanbefalet backend
Webhookskræver public URL
Queuemode til skalering

Inden du starter

n8n kan køre med en intern SQLite-fil, men til alt seriøst bør du bruge PostgreSQL — det er mere robust ved mange workflows og samtidige kørsler. Forudsætning: en fungerende Docker-installation.

Forudsætning: Følg Docker-guiden først. Til webhooks (fx din phishing-analyzer eller RSS-triggers) skal n8n have en offentlig URL via reverse-proxy — se Reverse-proxy.

Compose-stack

PostgreSQL

En komplet stack med n8n + Postgres på et isoleret netværk. Læg det i en mappe, fx ~/n8n/.

compose.yaml
services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - pg_data:/var/lib/postgresql/data
    networks: [ internal ]
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -U $${POSTGRES_USER}" ]
      interval: 10s
      retries: 5

  n8n:
    image: docker.n8n.io/n8nio/n8n:latest
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
      DB_POSTGRESDB_USER: ${POSTGRES_USER}
      DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
      N8N_HOST: ${N8N_HOST}
      N8N_PORT: 5678
      N8N_PROTOCOL: https
      WEBHOOK_URL: https://${N8N_HOST}/
      GENERIC_TIMEZONE: Europe/Copenhagen
      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
    ports:
      - "127.0.0.1:5678:5678"
    volumes:
      - n8n_data:/home/node/.n8n
    networks: [ internal, web ]

volumes:
  pg_data:
  n8n_data:

networks:
  internal:
    internal: true
  web:
Postgres ligger på internal (intet internet), n8n på både internal og web. Porten bindes til 127.0.0.1 — kun nåelig via reverse-proxy.

Konfiguration (.env)

Læg hemmeligheder i en .env-fil ved siden af compose.yaml — aldrig i selve YAML'en.

.env
POSTGRES_USER=n8n
POSTGRES_PASSWORD=# generér: openssl rand -base64 24
POSTGRES_DB=n8n
N8N_HOST=n8n.defencia.dk
N8N_ENCRYPTION_KEY=# generér: openssl rand -hex 32
Kritisk — encryption key: N8N_ENCRYPTION_KEY bruges til at kryptere alle gemte credentials. Sættes den ikke eksplicit, autogenereres den i volumet — og mister du volumet uden at have nøglen, er alle credentials uigenkaldeligt tabt. Gem nøglen i Bitwarden sammen med dine andre hemmeligheder.
Vigtig env-variabelFunktion
N8N_ENCRYPTION_KEYKrypterer gemte credentials (gem den!)
WEBHOOK_URLPublic base-URL n8n bygger webhook-adresser fra
N8N_HOST / N8N_PROTOCOLHostname og protokol bag proxy
GENERIC_TIMEZONETidszone for cron/schedule-noder
N8N_SECURE_COOKIESæt true bag HTTPS (default)
EXECUTIONS_DATA_PRUNEAuto-ryd gamle execution-logs
N8N_RUNNERS_ENABLEDAktivér task runners (isoleret kodeudførelse)

Reverse-proxy (Nginx)

n8n bruger websockets til den live editor — proxy-blokken skal håndtere upgrade-headers.

/etc/nginx/sites-available/n8n.defencia.dk
server {
    listen 443 ssl;
    server_name n8n.defencia.dk;

    # ssl_certificate ... (Certbot indsætter)

    location / {
        proxy_pass http://127.0.0.1:5678;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 3600s;
    }
}
Det lange read_timeout forhindrer at langtkørende workflows afbrydes af proxyen.
Cert: sudo certbot --nginx -d n8n.defencia.dk — eller brug dit eksisterende wildcard for *.defencia.dk.

Skalering — queue mode

avanceret

Til mange samtidige eller tunge workflows kan n8n køre i queue mode: en main-instans håndterer UI/webhooks, og separate worker-containere afvikler jobs via Redis.

Komponenter: Tilføj en redis-service, sæt EXECUTIONS_MODE=queue og QUEUE_BULL_REDIS_HOST=redis på både main og workers, og start n workers med kommandoen n8n worker. Hver worker trækker jobs fra køen — skalér ved at øge antallet af worker-containere.
Hvornår: For din nuværende brug (RSS-screening, rapporter, WOD-generator) er single-instance fint. Queue mode bliver først relevant hvis du rammer eksekverings-flaskehalse eller vil isolere tunge AI-kald fra UI-responsiviteten.

Drift

Start & følg logs
docker compose up -d
docker compose logs -f n8n
Opdatér til nyeste
docker compose pull
docker compose up -d
Læs altid release-notes — n8n kan have breaking changes mellem majors.
Backup database
docker compose exec postgres \
  pg_dump -U n8n n8n > n8n_$(date +%F).sql
Eksportér workflows til fil
docker compose exec n8n \
  n8n export:workflow --all --output=/home/node/.n8n/backup.json
Til din backup-stack: Tag både et pg_dump (data + credentials, krypteret med encryption key) og en workflow-eksport (portabel JSON). Send begge til restic/pCloud. Husk: uden encryption key er credentials i dumpet ubrugelige.

Hærdning

KontrolAnbefaling
EksponeringBind til 127.0.0.1, kun via Nginx + HTTPS
DatabasePostgres på internal-netværk, ingen værts-port
Encryption keySæt eksplicit, gem i Bitwarden, backup adskilt fra volume
LoginAktivér brugerstyring/2FA; Fail2ban-jail på login-endpoint
WebhooksBrug webhook-auth/tokens; valider payloads i workflowet
Task runnersAktivér for at isolere Code-node-eksekvering
Execution-dataPrune gamle logs så de ikke hober følsomme data op
AdgangOvervej kun-VPN-adgang til editoren; webhooks separat
Husk Docker+UFW-fælden: Bind n8n til 127.0.0.1:5678 — ikke 0.0.0.0 — ellers kan porten være eksponeret mod internettet forbi UFW. Se Docker-guiden for detaljer.