Self-Hosting n8n: Docker Setup in 10 Minutes
Step-by-step guide to self-hosting n8n with Docker, Postgres, HTTPS, and backups. Production-ready in under 30 minutes.
Key takeaways
- Use Docker Compose with three services: n8n, Postgres, Caddy.
- Always set N8N_ENCRYPTION_KEY before the first run — losing it bricks every saved credential.
- Back up Postgres daily; the n8n workflows table is your source of truth.
- Switch to queue mode with Redis once you exceed ~50 concurrent executions.
Self-hosting n8n means zero per-task billing, full data sovereignty, and the freedom to scale horizontally. This guide gets you from blank VPS to a production-grade n8n behind HTTPS with persistent Postgres storage and daily backups — using only Docker Compose and one Caddy file.
Choose your host
Any Linux VPS with 2 vCPU and 4 GB RAM handles a small team comfortably. Hetzner CX22, DigitalOcean Premium, and Hostinger VPS 2 are the favorite low-cost options. For Kubernetes shops, the official Helm chart is production-grade.
docker-compose.yml — the minimal production stack
Three services: postgres for persistence, n8n for the app, caddy for automatic HTTPS via Let's Encrypt. Pin n8n to a specific minor version (not latest) so upgrades are deliberate.
- Mount /home/node/.n8n as a named Docker volume so encryption keys survive restarts.
- Set DB_TYPE=postgresdb and point at the postgres service.
- Set WEBHOOK_URL to your public HTTPS URL so external services hit your webhooks correctly.
- Set GENERIC_TIMEZONE so cron schedules behave predictably.
The five environment variables that matter most
N8N_ENCRYPTION_KEY encrypts every credential at rest — generate once with openssl rand -hex 32 and store it in a password manager. N8N_HOST and WEBHOOK_URL must match your public hostname. N8N_PROTOCOL must be https. DB_POSTGRESDB_PASSWORD must be a real password, not the default.
HTTPS in one Caddy line
Caddy auto-renews Let's Encrypt certificates with a Caddyfile that's literally three lines: your-domain.com { reverse_proxy n8n:5678 }. No nginx, no certbot, no cron jobs.
Backups that actually restore
Run pg_dump nightly into a versioned S3 bucket (Backblaze B2 is the cheapest reliable option in 2026). Test the restore once per quarter into a staging compose stack — an untested backup is not a backup.
Scaling to queue mode
Once you cross ~50 concurrent executions or your main loop blocks long-running webhooks, flip to queue mode. Add Redis, set EXECUTIONS_MODE=queue, and run separate n8n-worker containers. Each worker picks jobs from Redis, so you scale horizontally by adding worker replicas.
Frequently asked questions
- Is self-hosting n8n hard?
- Docker Compose deployment is ~30 minutes. Operating it (backups, upgrades, monitoring) is the same workload as any small Postgres-backed web app.
- What happens if I lose my encryption key?
- Every saved credential becomes unreadable. You'll need to recreate them. Store the key in a password manager before first run.
- Can I self-host on a Raspberry Pi?
- Yes for hobby use. Use the arm64 image and SQLite. For production, use Postgres on x86_64.