How to Install n8n: Step-by-Step Guide (Docker, Docker Compose, and Node.js)

n8n hosting - n8nhost.io

Learn how to install n8n fast and reliably. This step-by-step guide covers the recommended Docker Compose setup (with and without PostgreSQL), a quick Docker run one-liner, and a local Node.js method. You’ll also get best practices for SSL, environment variables, and updates so your n8n instance stays secure and stable.

Quick answer

  • Best for production: Docker Compose behind a reverse proxy with SSL.
  • Best for testing: Docker run one-liner or Node.js (npm) install locally.
  • Must-set env vars: N8N_HOST, N8N_PORT, N8N_PROTOCOL, WEBHOOK_URL, and a strong N8N_ENCRYPTION_KEY.

Prerequisites

  • A server or VM (Ubuntu 22.04+ recommended) or a local machine (macOS/Windows/Linux)
  • Docker and Docker Compose (or Docker Desktop)
  • A domain/subdomain for production (e.g., automation.example.com)
  • Optional but recommended: reverse proxy (Nginx, Caddy, or Traefik) with SSL

Method 1: Install n8n with Docker Compose (recommended)

This setup is durable, easy to update, and production-friendly. You can use the built-in SQLite database (simpler) or PostgreSQL (more scalable and robust).

Option A: Simple Docker Compose (SQLite)

Create a project folder and a minimal docker-compose.yml:

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

cat > docker-compose.yml <<'YAML'
services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    ports:
      - "5678:5678"
    environment:
      - N8N_HOST=automation.example.com
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://automation.example.com/
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - GENERIC_TIMEZONE=UTC
    volumes:
      - ./n8n_data:/home/node/.n8n
YAML

Set a strong encryption key and start:

export N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)
docker compose up -d

Point your reverse proxy at http://SERVER_IP:5678 (see SSL section below). Visit your domain to complete the first-user setup.

Option B: Docker Compose with PostgreSQL (production)

For teams or heavier workloads, use PostgreSQL. Create docker-compose.yml:

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

cat > docker-compose.yml <<'YAML'
services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    depends_on:
      - postgres
    ports:
      - "5678:5678"
    environment:
      - N8N_HOST=automation.example.com
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://automation.example.com/
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - GENERIC_TIMEZONE=UTC
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
    volumes:
      - ./n8n_data:/home/node/.n8n

  postgres:
    image: postgres:15
    container_name: n8n_postgres
    restart: unless-stopped
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=n8n
    volumes:
      - ./pg_data:/var/lib/postgresql/data
YAML

Set secrets and start:

export N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)
export POSTGRES_PASSWORD=$(openssl rand -hex 24)

docker compose up -d

Add SSL with Nginx (example)

Point DNS for automation.example.com to your server. Then install Nginx and Certbot, and proxy to n8n:

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

sudo tee /etc/nginx/sites-available/n8n > /dev/null <<'NGINX'
server {
  server_name automation.example.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;
  }
}
NGINX

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

sudo certbot --nginx -d automation.example.com --redirect

Update your Docker env to reflect HTTPS:

N8N_HOST=automation.example.com
N8N_PORT=5678
N8N_PROTOCOL=https
WEBHOOK_URL=https://automation.example.com/

Restart n8n after changes:

docker compose down && docker compose up -d

Method 2: Quick test with Docker run

Good for local testing. Not ideal for production (no volumes, no SSL by default):

docker run -it --rm \
  -p 5678:5678 \
  -e N8N_HOST=localhost \
  -e N8N_PORT=5678 \
  -e N8N_PROTOCOL=http \
  -e WEBHOOK_URL=http://localhost:5678/ \
  -e N8N_ENCRYPTION_KEY=$(openssl rand -hex 32) \
  n8nio/n8n:latest

Method 3: Install n8n with Node.js (npm)

Use for local exploration. For production, prefer Docker. Requires Node.js 18+ and npm:

# install Node.js 18+ (example using nvm)
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.nvm/nvm.sh
nvm install --lts

# install and run n8n
npm install -g n8n
n8n start

Open http://localhost:5678 in your browser.

Post-install best practices

  • Security: keep N8N_ENCRYPTION_KEY secret; enable HTTPS; restrict the editor to trusted networks if needed.
  • Backups: back up ./n8n_data (and PostgreSQL if used).
  • Updates: periodically docker compose pull then up -d to update.
  • Environment: set GENERIC_TIMEZONE correctly; configure email (SMTP) for alerts if required.
  • Scaling: move to PostgreSQL and consider externalizing Redis/Queue if your workload grows.

Troubleshooting

  • Container won’t start: check logs with docker compose logs -f.
  • 404 on webhooks: ensure WEBHOOK_URL matches your public URL and protocol.
  • Mixed content/redirect loops: verify Nginx proxy headers and that N8N_PROTOCOL=https.
  • Permissions on volumes: ensure the Docker user can write to ./n8n_data.

FAQs

Is Docker mandatory for n8n?

No, but it’s the easiest and most reliable way to run n8n in production. You can also install via Node.js for local use.

Which database should I use?

SQLite is fine for single-user or light workloads. Use PostgreSQL for teams, reliability, and easier scaling.

How do I update n8n?

With Docker: docker compose pull followed by docker compose up -d. Always back up data first.

Can I put n8n behind Cloudflare or a tunnel?

Yes. Ensure your public URL (e.g., Cloudflare proxy or tunnel hostname) is set in WEBHOOK_URL and N8N_PROTOCOL is correct.

That’s it! You now have a secure, updatable n8n install. If you want, I can customize a production-ready docker-compose.yml for your domain and reverse proxy of choice.

Ready to Launch Your First Workflow?

Start your automation journey in under 60 seconds. No credit card required.

You May Also Like