n8n is a workflow automation tool — a self-hostable alternative to Zapier or Make. You connect apps (Gmail, Slack, Google Sheets, databases, HTTP APIs, AI models) in a visual editor, and workflows run on triggers or schedules. Self-hosting gives you unlimited executions, your data on your server, and the ability to run custom code.

n8n is released under a “fair-code” Sustainable Use License: free to self-host for your own business and internal use; check the license if you plan to resell it as a service.

Requirements

  • Docker and Docker Compose — see installing Docker on Ubuntu.
  • A domain such as n8n.example.com — webhooks need a stable public HTTPS URL.
  • 2 GB RAM is enough to start; heavy workflows (large files, many executions) need more.

1. Compose file

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

compose.yaml:

services:
  n8n:
    image: docker.n8n.io/n8nio/n8n:latest
    restart: unless-stopped
    environment:
      N8N_HOST: n8n.example.com
      N8N_PROTOCOL: https
      N8N_PORT: "5678"
      WEBHOOK_URL: https://n8n.example.com/
      N8N_PROXY_HOPS: "1"
      GENERIC_TIMEZONE: Asia/Hong_Kong
      TZ: Asia/Hong_Kong
      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: db
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: ${DB_PASSWORD}
      EXECUTIONS_DATA_PRUNE: "true"
      EXECUTIONS_DATA_MAX_AGE: "336"
    ports:
      - "127.0.0.1:5678:5678"
    volumes:
      - n8n-data:/home/node/.n8n
    depends_on:
      - db

  db:
    image: postgres:17
    restart: unless-stopped
    environment:
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: n8n
    volumes:
      - pg-data:/var/lib/postgresql/data

volumes:
  n8n-data:
  pg-data:

Create .env:

cat > .env <<EOF
N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)
DB_PASSWORD=$(openssl rand -base64 24)
EOF
chmod 600 .env
docker compose up -d

Back up N8N_ENCRYPTION_KEY. n8n encrypts stored credentials (API keys, OAuth tokens) with it; without the key, a restored database’s credentials are unusable.

Key settings:

  • WEBHOOK_URL — the public URL n8n uses when showing webhook and OAuth callback addresses. Wrong here = webhooks that point to localhost.
  • N8N_PROXY_HOPS: 1 — trust the reverse proxy’s forwarded headers.
  • EXECUTIONS_DATA_PRUNE / MAX_AGE (hours) — delete old execution logs so the database doesn’t grow forever.
  • SQLite is the default and fine for small setups; PostgreSQL scales better.

2. HTTPS reverse proxy

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

    client_max_body_size 50M;

    location / {
        proxy_pass http://127.0.0.1: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-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_buffering off;
        proxy_read_timeout 3600s;
    }
}

The editor uses WebSockets (or server-sent events) for live updates, hence the upgrade headers and disabled buffering.

sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d n8n.example.com

3. First login

Open https://n8n.example.com and create the owner account. Enable two-factor authentication in your user settings — this account holds credentials to everything you connect.

4. Build a first workflow

A classic: receive a webhook and post to Slack or Telegram.

  1. Add a Webhook trigger node — copy its production URL.
  2. Add a Slack (or Telegram) node, create credentials, map fields from the webhook payload.
  3. Activate the workflow.

Test with:

curl -X POST https://n8n.example.com/webhook/your-id -H "Content-Type: application/json" -d '{"text":"Hello from curl"}'

Other popular uses: syncing CRM and spreadsheets, processing form submissions, scheduled reports, monitoring RSS feeds, and AI agents that call LLM APIs with your tools and data.

5. Security

  • Keep n8n off the public internet except through the HTTPS proxy.
  • Restrict editor access if possible (VPN or IP allow-list) while leaving /webhook/ paths public.
  • Workflows can run code (Code node, Execute Command node). Treat n8n users as highly privileged, and consider disabling risky nodes with NODES_EXCLUDE.
  • Keep the image updated.

6. Scaling: queue mode

For heavy workloads, n8n’s queue mode splits the main process from workers using Redis, so executions run in parallel across containers or servers. Start with a single instance; move to queue mode when executions pile up.

7. Backups and updates

docker compose exec db pg_dump -U n8n n8n | gzip > n8n-$(date +%F).sql.gz

Also back up .env (the encryption key!) and the n8n-data volume. You can export workflows as JSON from the UI or with n8n export:workflow --all.

Update:

docker compose pull && docker compose up -d

Read release notes for breaking changes between major versions.

n8n runs well on a Docker VPS. If your workflows call AI APIs, our Tokyo VPS is in a region supported by the major AI providers.

  • n8n
  • Automation
  • Self-Hosting