n8nsetupinstallationself-hosteddocker

n8n Setup & Installation Guide (2026) | 2V Automation

A practical n8n setup guide - npm, Docker, Docker Compose, and production-ready deployments with Postgres, Redis, and queue mode.

SF
Sergey Furman Partner, 2V Automation
·
Jump to a section

The fastest way to install n8n is npx n8n - one command, runs locally on port 5678, ready in under a minute. The right way for production is Docker Compose with Postgres, Redis for queue mode, an encryption key you’ve backed up, and HTTPS in front. This guide walks both, plus everything in between.

n8n is source-available under the Sustainable Use License (since late 2022, replacing the earlier fair-code license). For internal business use, self-hosting is free. You pay only for the VM you run it on.

The four ways to run n8n

MethodBest forSetup time
npx n8nLocal laptop testing1 minute
npm global installLight single-user use5 minutes
Docker (single container)Small production setups10 minutes
Docker Compose (n8n + Postgres + Redis)Real production30-60 minutes
n8n CloudAnyone who doesn’t want to run a serverSign up

If you want the SaaS path, n8n Cloud is the right answer. Everything below assumes you’re self-hosting.

Method 1: npx n8n (the fastest demo)

The single-command approach. Best for evaluating n8n on your laptop before deciding anything.

Prerequisites: Node.js 20 or newer.

npx n8n

That’s it. n8n downloads, starts, and you get a URL like http://localhost:5678. Open it, complete the owner setup, and you have a working n8n instance.

Data lives in ~/.n8n/. Workflows, credentials, and the local SQLite database all sit in that folder. Killing the process and re-running npx n8n resumes where you left off.

This is not for production. SQLite, no queue mode, no HTTPS, no backups, no observability. It’s the right way to spend an afternoon kicking the tires.

Method 2: npm global install

A step up from npx. Same engine, but installed globally so you can manage it as a regular process.

npm install -g n8n
n8n start

Same data location (~/.n8n/), same SQLite default, same caveats about production-readiness. The advantage is that you can run n8n as a system service (systemd, launchd, pm2) and have it survive reboots.

Useful for personal use on a server you control. For business use, jump to Docker.

Method 3: Docker (single container)

The first real path. One Docker container running n8n with a mounted volume for persistence.

docker run -it --rm \
  --name n8n \
  -p 5678:5678 \
  -v n8n_data:/home/node/.n8n \
  docker.n8n.io/n8nio/n8n

The -v n8n_data:/home/node/.n8n mount means workflows and credentials persist across container restarts.

For a persistent setup (rather than the --rm ephemeral flag), use:

docker run -d \
  --name n8n \
  --restart unless-stopped \
  -p 5678:5678 \
  -v n8n_data:/home/node/.n8n \
  -e N8N_HOST=n8n.example.com \
  -e WEBHOOK_URL=https://n8n.example.com \
  -e N8N_PROTOCOL=https \
  -e GENERIC_TIMEZONE=Europe/London \
  -e N8N_ENCRYPTION_KEY=<your-strong-random-key> \
  docker.n8n.io/n8nio/n8n

A few important environment variables to set on any non-trivial deployment:

  • N8N_ENCRYPTION_KEY - encrypts credentials at rest. Generate a strong random string (32+ characters). If you lose this, your credentials are gone. Back it up properly, off-host.
  • N8N_HOST and WEBHOOK_URL - required if you’re putting n8n behind a domain. Webhook callers need to know the public URL.
  • N8N_PROTOCOL - https if you’re terminating TLS at a reverse proxy.
  • GENERIC_TIMEZONE - the timezone for scheduled triggers. Defaults to UTC.

This is workable for small production setups. The catch: still SQLite, still single-process, no queue mode. Fine for low-volume workloads (a few thousand executions per month). Past that, you want Compose.

Method 4: Docker Compose with Postgres and Redis (production)

The right setup for anything that matters. A docker-compose.yml that spins up n8n, a Postgres database, and a Redis instance for queue mode.

version: "3.8"

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

  redis:
    image: redis:7
    restart: unless-stopped
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 5s
      retries: 10

  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: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
      EXECUTIONS_MODE: queue
      QUEUE_BULL_REDIS_HOST: redis
      QUEUE_BULL_REDIS_PORT: 6379
      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
      N8N_HOST: ${N8N_HOST}
      WEBHOOK_URL: https://${N8N_HOST}
      N8N_PROTOCOL: https
      GENERIC_TIMEZONE: ${GENERIC_TIMEZONE:-UTC}
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy

  n8n-worker:
    image: docker.n8n.io/n8nio/n8n
    restart: unless-stopped
    command: worker
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_PORT: 5432
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
      EXECUTIONS_MODE: queue
      QUEUE_BULL_REDIS_HOST: redis
      QUEUE_BULL_REDIS_PORT: 6379
      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
    depends_on:
      n8n:
        condition: service_started

volumes:
  postgres_data:
  redis_data:
  n8n_data:

Drop this in a docker-compose.yml, create a .env file alongside:

POSTGRES_PASSWORD=<strong-random-password>
N8N_ENCRYPTION_KEY=<32-plus-character-random-string>
N8N_HOST=n8n.yourcompany.com
GENERIC_TIMEZONE=Europe/London

Then:

docker compose up -d

You now have n8n running in queue mode with Postgres as the metadata store and Redis as the queue broker. The n8n service handles the UI and API; the n8n-worker service picks executions off the queue and runs them. Add more workers by replicating the worker service block - each one consumes from the same queue.

Why queue mode matters: in regular mode, the n8n process runs workflow executions inline, which limits throughput and makes the UI feel slow under load. In queue mode, the main process queues work and workers consume it. You can scale workers horizontally without touching the main service.

For real production, add:

  • Managed Postgres (RDS, DigitalOcean Managed Postgres, etc.) instead of the in-Compose Postgres. Backups, snapshots, point-in-time recovery come for free.
  • Managed Redis instead of the in-Compose Redis. Same reasons.
  • A reverse proxy (Caddy, Nginx, Traefik) terminating TLS in front of n8n. Configure N8N_PROTOCOL=https and the WEBHOOK_URL to match.
  • Health checks and monitoring - Prometheus metrics are exposed at /metrics on the main service if N8N_METRICS=true. If you don’t have in-house capacity to run this in production, our n8n automation agency can set up and operate the full stack for you.

HTTPS with Caddy (the easy reverse-proxy path)

Caddy is the lowest-friction way to put HTTPS in front of n8n. Caddyfile:

n8n.yourcompany.com {
  reverse_proxy localhost:5678
}

Caddy handles cert issuance via Let’s Encrypt automatically. Point your DNS at the host, install Caddy, drop in the Caddyfile, restart Caddy, and you have HTTPS in five minutes.

For Nginx or Traefik, the same principle applies - terminate TLS at the proxy, forward to n8n on its internal port. Just make sure you set N8N_PROTOCOL=https and WEBHOOK_URL=https://... so n8n knows what public URL to use in webhook responses.

Backup strategy

The two things you absolutely must back up:

1. The encryption key (N8N_ENCRYPTION_KEY). Without it, your credentials are unrecoverable. Store it in your password manager, your secrets manager, and a sealed envelope in your CTO’s drawer. We are not joking - we have seen teams lose this and have to re-enter every credential by hand.

2. The Postgres database. Workflows, credentials (encrypted with the key above), execution history. A nightly pg_dump to S3 or equivalent is the minimum. If you’re using a managed Postgres, the provider’s automated backups cover this.

You technically should also back up the n8n_data volume (the ~/.n8n/ directory), but with Postgres holding the state, this is less critical. The volume holds binary data and some config; most of what matters is in the database.

A reasonable backup cadence:

  • Nightly Postgres dump, 30-day retention
  • Encryption key in a secrets manager with audit logging
  • Periodic disaster-recovery rehearsal (restore from backup into a fresh instance, verify workflows run)

Sizing the host

For a small-to-medium production setup:

  • 2 vCPU, 4 GB RAM - handles a few thousand executions/day comfortably
  • 20-40 GB SSD - Postgres data plus binary attachments
  • Managed Postgres with at least 1 vCPU and 2 GB RAM
  • Managed Redis with 256 MB-1 GB RAM (Redis is light for n8n’s queue use)

For high-volume setups (millions of executions/month):

  • 4-8 vCPU, 8-16 GB RAM for the main n8n service
  • Multiple worker services (start with 2-3, scale horizontally as needed)
  • Managed Postgres with 4+ vCPU, 8+ GB RAM
  • Managed Redis with 1-2 GB RAM
  • An HTTP load balancer in front for webhook traffic

Real client setups we run handle millions of executions per month on infrastructure under $300/month. For the full pricing breakdown, see n8n pricing 2025.

n8n Cloud: when not to self-host

Self-hosting isn’t always the right answer. Pick n8n Cloud if:

  • You don’t have ops capacity to run a Node.js service in production
  • Your execution volume is low enough that Cloud is cheap (under a few thousand executions/month)
  • You don’t have data residency or compliance constraints requiring on-prem
  • You want zero overhead - sign up, build, never think about infrastructure

The trade is a higher per-execution price for not having to operate anything. For most teams under ~10,000 monthly executions, Cloud is the right starting point. For higher volumes or compliance constraints, self-hosted wins on economics.

Common setup gotchas

Things that bite teams in the first week.

Webhook URL misconfigured. If WEBHOOK_URL doesn’t match the public URL n8n is reachable on, webhook nodes give you the wrong URL to register with external services. Set it correctly from day one.

Timezone confusion. Schedule triggers fire in the timezone set by GENERIC_TIMEZONE. Default is UTC. Forgetting to set this is the #1 reason “my schedule fires at the wrong time.”

Encryption key not backed up. Already mentioned, mentioning again. Back it up before you create your first credential.

SQLite in production. The default is SQLite, which works for testing and crumples under any real load. Switch to Postgres before going to production.

Queue mode not enabled at scale. Without EXECUTIONS_MODE=queue, the main process runs executions inline. Under load, the UI gets sluggish and the throughput ceiling is low. Switch to queue mode the moment you have meaningful traffic.

Firewall on webhook port. If n8n is on a VM and webhooks aren’t arriving, check the firewall and security group rules. Default port 5678 is closed on most cloud VMs by default.

Updates without a backup. docker compose pull && docker compose up -d is how you update. Always take a Postgres backup first. n8n is mature, but updates that touch schema do happen.

Updating n8n

n8n releases new versions roughly weekly. For Docker Compose setups:

docker compose pull
docker compose up -d

The new image starts; Postgres migrations run automatically; you’re upgraded. Workflows and credentials carry over without intervention.

We recommend pinning to a specific version (docker.n8n.io/n8nio/n8n:1.74.0 rather than :latest) in production. Test the version in staging before pushing to production, especially for major version bumps.

Where to go from here

You have an instance. Next:

  • Build your first real workflow. n8n automation guide covers the workflow primitives.
  • Set up credentials properly. Use environment-specific credential namespaces and rotate them.
  • Build an error workflow. Attach it to every production workflow so failures route to one place.
  • Add monitoring. Enable N8N_METRICS=true and scrape from Prometheus.
  • Plan custom nodes. If you have recurring internal patterns, see why your business needs its own n8n node.
  • Compare costs vs your current tool. Workflow cost calculator.

If you’re trying to figure out whether self-hosted, Cloud, or staying on your current tool makes the most sense - and where automation actually pays back first - our Efficiency Scorecard is the fastest answer. 15 minutes, free, you keep the output regardless.

From our YouTube channel

Watch the tutorials

Step-by-step n8n builds from our founder. For more, see the 2V Automation channel.

Advanced Interactive Slack App with n8n: Buttons and File Uploads
How to Handle Binary Files in n8n Sub-Workflows (Quick Guide)
Build a Facebook Messenger AI Agent in 15 Minutes with n8n

Frequently asked questions

How do I install n8n on Ubuntu?
The recommended path is Docker Compose. Install Docker and Docker Compose with `apt install docker.io docker-compose-plugin`, drop the Compose YAML from this guide into a directory, set the environment variables in a `.env` file, and run `docker compose up -d`. Put Caddy or Nginx in front for HTTPS.
Is n8n free to self-host?
Yes. The Community Edition is free for any internal business use under the Sustainable Use License (which replaced the earlier fair-code license in late 2022). You pay only for the VM, Postgres, and Redis instances you run it on - typically $30-$100/month for small-to-medium production setups.
What's the minimum hardware for n8n?
For light use, a 2 vCPU / 4 GB RAM VM handles n8n + SQLite comfortably. For real production, 2-4 vCPU and 4-8 GB RAM for the main service, plus separate managed Postgres (1+ vCPU, 2+ GB) and Redis (256 MB-1 GB). High-volume setups scale horizontally with additional worker containers.
Do I need Postgres for n8n?
For production, yes. The default SQLite database works for testing but doesn't handle real load well and is harder to back up cleanly. Postgres is the recommended database for any production deployment - managed Postgres (RDS, DigitalOcean Managed Postgres) is the easiest path.
What is queue mode in n8n?
Queue mode (`EXECUTIONS_MODE=queue`) separates workflow execution from the main n8n process. The main service handles the UI and API; worker services consume executions from a Redis queue. Required for high-throughput production setups; lets you scale workers horizontally without touching the main service.
How do I back up n8n?
Two things must be backed up: the encryption key (`N8N_ENCRYPTION_KEY` - without it your credentials are unrecoverable) and the Postgres database (workflows, credentials, execution history). Nightly `pg_dump` to S3 plus the encryption key in a secrets manager is the minimum viable backup strategy.
How do I update n8n?
For Docker Compose setups: `docker compose pull && docker compose up -d`. The new image starts, Postgres migrations run automatically, workflows and credentials persist. Pin to specific versions (not `:latest`) in production and test major version bumps in staging first.
Can I run n8n on Kubernetes?
Yes. The official Helm chart ([github.com/8gears/n8n-helm-chart](https://github.com/8gears/n8n-helm-chart), maintained by the community) covers most setups. For complex setups, queue mode with separate worker deployments scales well on Kubernetes. We've shipped client environments doing millions of executions/month on K8s.