Skip to Content

How to Self-Host n8n: Build Unlimited AI Automation Workflows

A complete guide to deploying n8n on your own server with Docker, connecting integrations, and building your first AI workflow
n8n workflow automation

n8n has exploded in 2026 — 85k+ GitHub stars, 400+ integrations, and native AI workflow support that makes it the go-to automation platform for developers who are done paying per-execution cloud fees. This self-host n8n guide gets you from zero to a production-ready deployment with HTTPS, PostgreSQL, and your first AI-powered workflow.

1. Why Self-Host n8n?

n8n Cloud is convenient, but the execution limits hit fast once your automations scale — and at $20–$50/month for modest usage, costs compound quickly. Self-hosting removes those caps entirely: unlimited workflows, unlimited executions, no throttling. More importantly, your data never leaves your infrastructure, which matters when you're piping customer records, internal Slack messages, or API keys through automation nodes. With a $5–$10/month VPS, the math is obvious.

2. Prerequisites

Option A — Docker (recommended)

  • Docker Engine 24+ and Docker Compose v2
  • A Linux VPS (Ubuntu 22.04/24.04 or Debian 12) with at least 1 vCPU / 1 GB RAM
  • A domain or subdomain pointed at your server's IP

Option B — Node.js (bare metal)

  • Node.js 18 or 20 LTS
  • npm or pnpm

3. Quick Start with Docker

Fastest way to get n8n running. Uses SQLite by default — fine for testing, not for production.

docker run -d   --name n8n   -p 5678:5678   -e N8N_BASIC_AUTH_ACTIVE=true   -e N8N_BASIC_AUTH_USER=admin   -e N8N_BASIC_AUTH_PASSWORD=changeme   -v n8n_data:/home/node/.n8n   docker.n8n.io/n8nio/n8n

Visit http://<your-server-ip>:5678. Don't stop here — move to section 4 before you put anything real on this instance.

4. Production Setup with PostgreSQL + Docker Compose

Create the project directory

mkdir -p /opt/n8n && cd /opt/n8n

Create .env

POSTGRES_USER=n8n
POSTGRES_PASSWORD=supersecretpassword
POSTGRES_DB=n8n

N8N_HOST=n8n.yourdomain.com
N8N_PORT=5678
N8N_PROTOCOL=https
WEBHOOK_URL=https://n8n.yourdomain.com/

N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=changeme

# Generate with: openssl rand -hex 32
N8N_ENCRYPTION_KEY=a-long-random-string-generate-with-openssl-rand-hex-32

Create docker-compose.yml

version: '3.8'

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

  n8n:
    image: docker.n8n.io/n8nio/n8n
    restart: unless-stopped
    ports:
      - "5678:5678"
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
      - DB_POSTGRESDB_USER=${POSTGRES_USER}
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      - N8N_HOST=${N8N_HOST}
      - N8N_PORT=${N8N_PORT}
      - N8N_PROTOCOL=${N8N_PROTOCOL}
      - WEBHOOK_URL=${WEBHOOK_URL}
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy

volumes:
  postgres_data:
  n8n_data:

Start it up

docker compose up -d
docker compose logs -f n8n

5. Reverse Proxy with Nginx + HTTPS

Never expose port 5678 directly. Use Nginx and Let's Encrypt.

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

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

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

    location / {
        proxy_pass http://localhost:5678;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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_read_timeout 300s;
        proxy_send_timeout 300s;
        client_max_body_size 50M;
    }
}
ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
certbot --nginx -d n8n.yourdomain.com
Tip: The proxy_read_timeout 300s is critical — some n8n workflow executions run long and the default 60s Nginx timeout will silently kill them.

6. Your First AI Workflow

Webhook → OpenAI → response. Classic pattern. Takes 2 minutes to wire up.

  1. Go to Settings → Credentials → Add Credential → OpenAI → paste your API key
  2. Create a new workflow, add a Webhook trigger (Method: POST)
  3. Add an OpenAI node → Message a Model → Model: gpt-4o → Prompt: {{ $json.body.prompt }}
  4. Add Respond to Webhook → Body: {{ $json.message.content }}
  5. Activate and test:
curl -X POST https://n8n.yourdomain.com/webhook/your-webhook-id   -H "Content-Type: application/json"   -d '{"prompt": "Summarize the benefits of self-hosting in one sentence."}'

n8n's AI-native nodes — AI Agent, Chat Memory, Vector Store, Embeddings — let you build a full RAG pipeline or multi-step agent visually, no Python needed.

7. Essential Environment Variables

VariableDescriptionExample
N8N_HOSTPublic hostnamen8n.yourdomain.com
N8N_PROTOCOLhttp or httpshttps
WEBHOOK_URLFull public URL for webhookshttps://n8n.yourdomain.com/
N8N_ENCRYPTION_KEYAES key for stored credentials — back this up!32-byte hex string
N8N_BASIC_AUTH_ACTIVEEnable basic authtrue
DB_TYPEDatabase backendpostgresdb
EXECUTIONS_DATA_PRUNEAuto-prune old execution logstrue
EXECUTIONS_DATA_MAX_AGEDays to keep execution logs30

8. Tips: Webhooks, Backup, Updates

Webhooks in production

Always set WEBHOOK_URL to your public HTTPS domain. Without it, n8n generates incorrect webhook URLs that don't work externally.

Backup your encryption key

If you lose N8N_ENCRYPTION_KEY, all stored credentials are permanently gone. Store it in a password manager or secrets vault immediately.

Backup workflows and credentials

# Backup postgres data
docker exec n8n-postgres-1 pg_dump -U n8n n8n > n8n_backup_$(date +%Y%m%d).sql

# Or export workflows via n8n CLI
docker exec -it n8n-n8n-1 n8n export:workflow --all --output=/home/node/.n8n/workflows_backup.json

Updating n8n

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

Need Help Deploying at Scale?

Whether you're setting up n8n for a team, integrating it with enterprise systems, or building custom AI automation workflows, we can help you get it right the first time.

Talk to Us →
How to Set Up OpenClaw: The Open-Source AI Personal Assistant
A step-by-step guide to installing and configuring OpenClaw on Linux, macOS, and connecting to your messaging apps