Skip to main content
Lifetime license included with every purchase
n8n self-hostedn8n docker setupn8n tutorialworkflow automation

The Complete Guide to Self-Hosting n8n in 2026

Step-by-step guide to self-hosting n8n. Covers Docker setup, environment variables, security hardening, SSL, backups, and scaling for production workloads.

Nn8n Marketplace Team·April 29, 2026·6 min read

Self-hosting n8n gives you full control over your automation infrastructure. No per-execution billing, no vendor lock-in, and no limits on which nodes you can use. This guide covers everything you need to go from zero to a production-ready self-hosted n8n instance.

Why Self-Host n8n?

The math is straightforward. n8n Cloud starts at €20/month. A Hetzner or DigitalOcean VPS that comfortably runs n8n costs $5-10/month — and you can run unlimited executions on it.

Beyond cost, self-hosting means:

  • Full data sovereignty — your workflow data and credentials never leave your server
  • No rate limits — run as many executions as your hardware allows
  • Custom nodes — install community nodes or build your own without restrictions
  • Direct database access — query the SQLite or Postgres backend for custom reporting

The tradeoff is that you own the operational burden: updates, backups, SSL certificates, and monitoring. The rest of this guide handles each of those.

Docker Setup

Docker is the recommended way to run n8n. Here's a production-ready docker-compose.yml:

services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    ports:
      - "5678:5678"
    environment:
      - N8N_HOST=n8n.yourdomain.com
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_URL=https://n8n.yourdomain.com/
      - GENERIC_TIMEZONE=America/New_York
      - TZ=America/New_York
      - N8N_SECURE_COOKIE=true
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${DB_PASSWORD}
      - N8N_ENCRYPTION_KEY=${ENCRYPTION_KEY}
      - EXECUTIONS_DATA_PRUNE=true
      - EXECUTIONS_DATA_MAX_AGE=168
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "wget --spider -q http://localhost:5678/healthz || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3

  postgres:
    image: postgres:16-alpine
    container_name: n8n-postgres
    restart: unless-stopped
    environment:
      - POSTGRES_DB=n8n
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  n8n_data:
  postgres_data:
Don't skip the encryption key

The N8N_ENCRYPTION_KEY encrypts your stored credentials at rest. Generate one with openssl rand -hex 32 and store it in a .env file. If you lose this key, you cannot recover saved credentials. Back it up somewhere safe.

Key environment variables explained

  • WEBHOOK_URL — must match your external URL, otherwise webhook-based triggers (Stripe, Slack, etc.) will fail
  • EXECUTIONS_DATA_PRUNE=true — automatically cleans old execution logs (set MAX_AGE in hours; 168 = 7 days)
  • DB_TYPE=postgresdb — SQLite works for small setups, but Postgres handles concurrent executions better and supports larger histories
  • N8N_SECURE_COOKIE=true — forces secure cookie flag in production

Create a .env file next to your compose file:

DB_PASSWORD=$(openssl rand -hex 16)
ENCRYPTION_KEY=$(openssl rand -hex 32)

Run it:

docker compose up -d

n8n will be available at http://your-server-ip:5678. The first visit creates your owner account.

Security Checklist

Before exposing n8n to the internet, lock down these items:

  • Change the default port or better yet, don't expose 5678 directly — use a reverse proxy
  • Set N8N_SECURE_COOKIE=true to prevent cookie theft over HTTP
  • Use strong passwords for the n8n owner account
  • Restrict SSH access — key-based auth only, disable password login
  • Keep Docker images updated — subscribe to n8n release notes and pull regularly
  • Store secrets in .env, never in the compose file committed to git
  • Enable a firewall (ufw or cloud provider security groups) — only allow 80, 443, and 22
Never commit .env files

Add .env to your .gitignore immediately. If credential secrets end up in git history, rotate them — even git rm leaves them in history. Use a vault or secret manager for team environments.

SSL and Reverse Proxy

Use Caddy for the simplest SSL setup, or Nginx if you need more control.

Caddy (recommended — automatic HTTPS)

# Add to your docker-compose.yml
  caddy:
    image: caddy:2
    container_name: n8n-caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config
    depends_on:
      - n8n

volumes:
  caddy_data:
  caddy_config:

Create a Caddyfile:

n8n.yourdomain.com {
    reverse_proxy n8n:5678
}

Caddy automatically provisions and renews Let's Encrypt certificates. Point your domain's DNS to the server, start the containers, and you're on HTTPS.

Backups

n8n stores two things you need to back up: credentials (encrypted in the database) and workflow definitions. With Postgres, back up the database volume:

# One-off backup
docker exec n8n-postgres pg_dump -U n8n n8n > backup_$(date +%Y%m%d).sql

# Automated daily backup via cron
0 3 * * * docker exec n8n-postgres pg_dump -U n8n n8n | gzip > /backups/n8n_$(date +\%Y\%m\%d).sql.gz

Also back up the .env file containing your encryption key — without it, the database backup is useless for credential recovery.

For disaster recovery, test your restore process at least once:

docker exec -i n8n-postgres psql -U n8n n8n < backup_20260429.sql

Scaling Tips

A single n8n instance handles most workloads fine. When you start hitting limits:

  • Switch to Postgres (done above) — SQLite becomes a bottleneck under concurrent webhook traffic
  • Increase N8N_PAYLOAD_SIZE_MAX if workflows process large payloads (default is 16MB)
  • Use queue mode — set EXECUTIONS_MODE=queue with Redis to distribute executions across multiple n8n worker containers
  • Monitor resource usage — add deploy.resources.limits to your compose file to prevent n8n from consuming all server memory
  • Prune execution data aggressively — set EXECUTIONS_DATA_MAX_AGE=72 for high-volume instances

Queue mode is the biggest scaling lever. It separates the n8n web UI from execution workers, letting you scale workers independently.

When to Use n8n Cloud Instead

Self-hosting isn't always the right call. Consider n8n Cloud if:

  • You don't want to manage server updates, SSL renewals, or backups
  • Your team needs SSO, audit logs, or shared credentials out of the box
  • You want guaranteed uptime without building it yourself
  • You're running fewer than 5,000 executions/month — the cost difference is minimal

The sweet spot for self-hosting is high-volume automation where per-execution pricing from any cloud provider becomes expensive, or when compliance requirements mandate on-premise data.

You can switch later

Started on n8n Cloud? You can export workflows as JSON and import them into a self-hosted instance. Started self-hosted? n8n Cloud can import those same JSON files. Don't overthink the initial choice — pick what works today and migrate when your needs change.

Next Steps

Once your n8n instance is running, the next step is actually building workflows. Skip the blank canvas — grab a pre-built template and customize it:

Browse 50+ n8n Templates Explore Decision Support Workflows

Every template includes the workflow JSON, a setup guide, and configuration details. Import, add your credentials, and you're automating in minutes instead of hours.

FAQ

Common questions

How much does it cost to self-host n8n?
n8n itself is free (fair-code license). You only pay for your server — a $5-10/month VPS handles most workloads. Compare that to Zapier's $20-600/month pricing.
Is self-hosted n8n secure enough for production?
Yes, when configured properly. Use HTTPS, environment variable secrets, a reverse proxy, and keep n8n updated. Many companies run n8n in production handling sensitive data.
Can I migrate from n8n Cloud to self-hosted?
Yes. Export your workflows as JSON from n8n Cloud and import them into your self-hosted instance. Credential values need to be re-entered for security.
Stop reading. Start running.

Get the workflow templates this guide is built on

Import-ready n8n JSON, step-by-step setup, and tested end-to-end. One-time payment, own it forever.