For: James / AgentsOPS / FreshFlip Date: 2026-02-05 Status: DRAFT v0 (approve infra choices before provisioning)
Goal: a production-safe self-hosted n8n that’s easy to upgrade, backed up, and locked down.
automations.agentsops.net (or similar)Optional (later): separate VPS for Postgres if workloads grow.
Must set: - N8N_ENCRYPTION_KEY (32+ chars; do not lose)
- N8N_USER_MANAGEMENT_DISABLED=false (use built-in
users)
Store in .env with strict permissions or a secret
manager.
N8N_HOST=automations.agentsops.netN8N_PROTOCOL=httpsWEBHOOK_URL=https://automations.agentsops.net/EXECUTIONS_DATA_PRUNE=trueEXECUTIONS_DATA_MAX_AGE=168 (hours) (adjust)Note: This is a starting template. Confirm proxy choice (Caddy vs Traefik) before using.
Create a folder: /opt/n8n with: -
docker-compose.yml - .env -
caddy/Caddyfile (if using Caddy)
.env (example)# n8n
N8N_HOST=automations.agentsops.net
N8N_PROTOCOL=https
WEBHOOK_URL=https://automations.agentsops.net/
N8N_ENCRYPTION_KEY=REPLACE_WITH_LONG_RANDOM_SECRET
GENERIC_TIMEZONE=America/New_York
# postgres
POSTGRES_DB=n8n
POSTGRES_USER=n8n
POSTGRES_PASSWORD=REPLACE_WITH_STRONG_PASSWORDdocker-compose.yml
(example)services:
postgres:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
depends_on:
- postgres
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_PROTOCOL: ${N8N_PROTOCOL}
WEBHOOK_URL: ${WEBHOOK_URL}
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
# retention / hygiene
EXECUTIONS_DATA_PRUNE: "true"
EXECUTIONS_DATA_MAX_AGE: "168"
volumes:
- n8n_data:/home/node/.n8n
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
- n8n
volumes:
postgres_data:
n8n_data:
caddy_data:
caddy_config:caddy/Caddyfile
(example)automations.agentsops.net {
reverse_proxy n8n:5678
}
/home/node/.n8n) (encryption key
must be preserved too)pg_dump to a dated fileOnce per month: - Restore DB dump to a staging instance - Verify at least 1 workflow executes successfully
N8N_ENCRYPTION_KEY is stored safely