Hand-drawn illustration of self-hosted server infrastructure
Case Study

n8n Self-Hosted: Complete Setup Guide for 2026

9 min read

Quick Summary

  • Docker Compose is the fastest production-ready setup
  • Always set N8N_ENCRYPTION_KEY before storing real credentials
  • Switch from SQLite to PostgreSQL once you hit dozens of workflows

n8n Self-Hosted: Complete Setup Guide for 2026

Running n8n in the cloud is fine until you hit data limits, pricing tiers, or compliance requirements. Self-hosting puts you in control of your data, your costs, and your infrastructure. The trade-off? You become your own DevOps team.

This guide shows you how to set up n8n self-hosted from scratch. We will cover Docker (the fastest path), Docker Compose (production-friendly), reverse proxy setup with SSL, environment configuration, and the update process. No assumptions about your setup. Just the steps that work.

What Is n8n Self-Hosted?

**n8n self-hosted** means running the n8n automation platform on infrastructure you control instead of n8n's managed cloud. You own the data, set the resource limits, and decide when to update.

The self-hosted version includes the same visual workflow editor, 400+ integrations, and webhook support as cloud. The difference is infrastructure ownership. You handle backups, SSL certificates, and scaling. In return, you get unlimited workflows (no execution caps), full data privacy, and the ability to run n8n inside a VPN or air-gapped environment.

Why Self-Host n8n?

Cloud vs Self-Hosted n8n comparison

Control is the obvious reason. But there are specific scenarios where self-hosted wins:

- **Data compliance:** GDPR, HIPAA, SOC 2, or internal policies that prohibit third-party data processing

- **Execution volume:** Cloud plans charge per execution. Self-hosted removes that ceiling

- **Custom integrations:** Install community nodes or private packages without platform restrictions

- **Network access:** Reach internal APIs, databases, and services that cloud n8n cannot touch

- **Cost predictability:** Fixed infrastructure cost instead of per-workflow metering

The downside is operational overhead. If your server goes down, your automations stop. If you skip updates, you miss security patches. Self-hosting is a power move, not a convenience play.

Prerequisites

Before you start, you need:

- A server or VPS with at least 2 CPU cores, 4GB RAM, and 20GB storage

- Docker and Docker Compose installed

- A domain name pointed at your server IP

- Basic comfort with the command line

Recommended providers: Hetzner, DigitalOcean, Linode, or any VPS with Ubuntu 22.04 LTS. Bare metal works too if you already have a homelab or on-premise server.

Option 1: Docker Run (Fastest Setup)

This gets n8n running in under five minutes. Not recommended for production, but perfect for testing.

Create a directory for n8n data:

mkdir -p ~/.n8n && cd ~/.n8n

Run the container:

docker run -it --rm \
--name n8n \
-p 5678:5678 \
-v ~/.n8n:/home/node/.n8n \
-e N8N_BASIC_AUTH_ACTIVE=true \
-e N8N_BASIC_AUTH_USER=admin \
-e N8N_BASIC_AUTH_PASSWORD=your-secure-password \
n8nio/n8n:latest

Visit `http://YOUR_SERVER_IP:5678` and log in with the credentials you set.

This stores workflows and credentials in `~/.n8n` on your host. The container uses basic auth. For anything beyond a quick test, move to Docker Compose.

Option 2: Docker Compose (Production-Ready)

Docker Compose gives you persistent storage, environment variables in a file, and easier updates.

Create a project directory:

mkdir -p ~/n8n-docker && cd ~/n8n-docker

Create `docker-compose.yml`:

version: '3.8'

services:
n8n:
image: n8nio/n8n:latest
restart: always
ports:
- "127.0.0.1:5678:5678"
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=your-secure-password
- N8N_HOST=n8n.yourdomain.com
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://n8n.yourdomain.com/
- GENERIC_TIMEZONE=Europe/London
volumes:
- n8n_data:/home/node/.n8n

volumes:
n8n_data:

Key changes from the docker run command:

- Port binding is localhost-only (`127.0.0.1:5678`) so n8n is not exposed directly to the internet

- `WEBHOOK_URL` tells n8n the public URL for triggers

- `N8N_HOST` and `N8N_PROTOCOL` ensure generated links point to your domain

- A named Docker volume handles persistence

Start it:

docker compose up -d

Setting Up a Reverse Proxy with SSL

You need a reverse proxy to handle HTTPS and route traffic from port 443 to n8n on port 5678. Nginx is the standard choice.

Install Nginx:

sudo apt update && sudo apt install nginx certbot python3-certbot-nginx -y

Create `/etc/nginx/sites-available/n8n`:

server {
listen 80;
server_name n8n.yourdomain.com;

location / {
proxy_pass http://127.0.0.1:5678;
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_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

Enable the site:

sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl restart nginx

Obtain SSL via Let's Encrypt:

sudo certbot --nginx -d n8n.yourdomain.com

Certbot automatically updates your Nginx config for HTTPS and sets up renewal. Test it by visiting `https://n8n.yourdomain.com`.

Environment Variables You Should Know

Beyond the basics, these variables matter for production:

- `N8N_ENCRYPTION_KEY` — Encrypts credentials in the database. Set this once and back it up. Losing it means losing all stored credentials.

- `EXECUTIONS_MODE` — Set to `queue` if you plan to scale with multiple n8n workers. Default `regular` runs everything in the main process.

- `DB_TYPE` — Defaults to SQLite. For production, switch to PostgreSQL with `DB_TYPE=postgresdb` and add `DB_POSTGRESDB_HOST`, `DB_POSTGRESDB_DATABASE`, `DB_POSTGRESDB_USER`, `DB_POSTGRESDB_PASSWORD`.

- `N8N_METRICS` — Enables Prometheus metrics endpoint at `/metrics`.

If you store sensitive credentials in n8n, `N8N_ENCRYPTION_KEY` is non-negotiable. Generate one with:

openssl rand -base64 32

Database: When to Switch from SQLite to PostgreSQL

SQLite handles small workloads fine. Once you hit dozens of workflows with frequent executions, switch to PostgreSQL.

Add a database service to your `docker-compose.yml`:

postgres:
image: postgres:15-alpine
restart: always
environment:
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=your-db-password
- POSTGRES_DB=n8n
volumes:
- postgres_data:/var/lib/postgresql/data

n8n:
# ... existing n8n config ...
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=your-db-password
# ... other env vars ...
depends_on:
- postgres

volumes:
n8n_data:
postgres_data:

Run `docker compose up -d` again. n8n will migrate existing data automatically on first startup.

Updating n8n Self-Hosted

Updates are simple with Docker Compose:

cd ~/n8n-docker
docker compose pull
docker compose up -d

This pulls the latest image and recreates the container. Your data persists in the Docker volume.

For zero-downtime updates, run a second n8n instance behind a load balancer, or accept a 10-30 second restart window. Most automation workloads tolerate brief interruptions.

Always check the n8n changelog before major version jumps. Breaking changes are rare but documented.

Common Setup Failures and Fixes

**Webhook triggers return 404 or do not fire**

Check `WEBHOOK_URL` matches your public HTTPS domain. If it points to `http://localhost:5678`, external services cannot reach the webhook. Update the environment variable and restart.

**Cannot log in after restart**

If you removed the container without a persistent volume, your user database reset. Always use a named volume or bind mount for `~/.n8n`.

**SSL certificate errors**

Certbot might fail if port 80 is blocked or your DNS A record has not propagated. Verify with `dig n8n.yourdomain.com` and ensure port 80 is open for the HTTP challenge.

**Out of memory crashes**

n8n defaults to 2GB RAM usage. On a 1GB VPS, add swap or upgrade. Monitor with `docker stats`.

**Time zone issues**

Set `GENERIC_TIMEZONE` to your local zone. The Schedule Trigger node depends on this. Without it, cron jobs run in UTC and confuse everyone.

Security Checklist

Before you process real data:

☐ Change the default basic auth password

☐ Set `N8N_ENCRYPTION_KEY` and store it in a password manager

☐ Confirm HTTPS is enforced (no HTTP fallback)

☐ Restrict SSH access to your server (key auth only, disable root login)

☐ Enable automatic security updates on the host OS

☐ Set up backups for `~/.n8n` or your Docker volumes

☐ Consider a firewall (UFW) allowing only ports 22, 80, and 443

How Synta Fits In

Once your self-hosted n8n instance is running, you still have to build workflows manually. Synta connects Claude Code, Cursor, or another MCP client directly to your n8n instance via MCP. You describe what you want in plain English, and Synta generates, validates, and deploys workflows to your self-hosted setup.

Self-hosting gives you the infrastructure. Synta gives you the speed. Together, you get full control without the manual drag.

FAQ

**How much does n8n self-hosted cost?**

n8n itself is free and open-source under the Sustainable Use License. Your only costs are server hosting (typically $5-20/month for a VPS) and your time for maintenance.

**Can I run n8n self-hosted on a Raspberry Pi?**

Yes, for light workloads. Use Docker with a 64-bit OS. Performance degrades with heavy workflows or many concurrent executions.

**Does self-hosted n8n include all integrations?**

Yes. All 400+ nodes work the same as cloud. Community nodes install without restrictions.

**How do I back up n8n self-hosted?**

Back up the `~/.n8n` directory or the named Docker volume. For PostgreSQL, dump the database with `pg_dump`. Store backups off-site.

**What is the difference between n8n cloud and self-hosted?**

Cloud is managed by n8n with automatic updates, support, and per-execution pricing. Self-hosted is free to run but you manage infrastructure, updates, and scaling.

- Synta homepage CTA

- Synta MCP docs for technical readers who want MCP setup