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.
Compose-stack
PostgreSQLEn komplet stack med n8n + Postgres på et isoleret netværk. Læg det i en mappe, fx ~/n8n/.
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:
Konfiguration (.env)
Læg hemmeligheder i en .env-fil ved siden af compose.yaml — aldrig i selve YAML'en.
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
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-variabel | Funktion |
|---|---|
N8N_ENCRYPTION_KEY | Krypterer gemte credentials (gem den!) |
WEBHOOK_URL | Public base-URL n8n bygger webhook-adresser fra |
N8N_HOST / N8N_PROTOCOL | Hostname og protokol bag proxy |
GENERIC_TIMEZONE | Tidszone for cron/schedule-noder |
N8N_SECURE_COOKIE | Sæt true bag HTTPS (default) |
EXECUTIONS_DATA_PRUNE | Auto-ryd gamle execution-logs |
N8N_RUNNERS_ENABLED | Aktivér task runners (isoleret kodeudførelse) |
Reverse-proxy (Nginx)
n8n bruger websockets til den live editor — proxy-blokken skal håndtere upgrade-headers.
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;
}
}
sudo certbot --nginx -d n8n.defencia.dk — eller brug dit eksisterende wildcard for *.defencia.dk.Skalering — queue mode
avanceretTil 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.
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.Drift
docker compose up -d
docker compose logs -f n8n
docker compose pull
docker compose up -d
docker compose exec postgres \
pg_dump -U n8n n8n > n8n_$(date +%F).sql
docker compose exec n8n \
n8n export:workflow --all --output=/home/node/.n8n/backup.json
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
| Kontrol | Anbefaling |
|---|---|
| Eksponering | Bind til 127.0.0.1, kun via Nginx + HTTPS |
| Database | Postgres på internal-netværk, ingen værts-port |
| Encryption key | Sæt eksplicit, gem i Bitwarden, backup adskilt fra volume |
| Login | Aktivér brugerstyring/2FA; Fail2ban-jail på login-endpoint |
| Webhooks | Brug webhook-auth/tokens; valider payloads i workflowet |
| Task runners | Aktivér for at isolere Code-node-eksekvering |
| Execution-data | Prune gamle logs så de ikke hober følsomme data op |
| Adgang | Overvej kun-VPN-adgang til editoren; webhooks separat |
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.