Operations14 min readUpdated 2026-06-29

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.
HomePathTemplatesBlogMy