n8n logoWorkflow Automation

n8n

A self-hosted workflow automation platform connecting hundreds of services as an alternative to Zapier and Make.

Review notes

Use PostgreSQL for production instead of SQLite. Enable queue mode with Redis for many concurrent workflows.

Deployment guide

Run with Docker Compose using PostgreSQL. Optionally add Redis for queue mode.

  1. Create data directory and docker-compose file.
  2. Configure PostgreSQL as the main database.
  3. Run the n8n container with volumes for workflows and credentials.
  4. Create an admin account and start building workflows.
  5. Set the correct webhook URL if using webhook triggers.
Backup:Back up the PostgreSQL database and .n8n directory containing encrypted credentials.

Copy and run on your server

Use each block separately: save the compose file, or copy the bash script to create it and start the container.

docker-compose.ymlyaml
services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: CHANGEME_db_password # CHANGE THIS
      N8N_HOST: "n8n.example.com"
      WEBHOOK_URL: "https://n8n.example.com/"
    volumes:
      - ./data:/home/node/.n8n
    ports:
      - "5678:5678"
    depends_on:
      - postgres
    restart: unless-stopped

  postgres:
    image: postgres:16-alpine
    container_name: n8n_postgres
    environment:
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: CHANGEME_db_password # CHANGE THIS
      POSTGRES_DB: n8n
    volumes:
      - ./postgres:/var/lib/postgresql/data
    restart: unless-stopped
setup.shbash
#!/usr/bin/env bash
set -euo pipefail

sudo mkdir -p /opt/n8n
sudo chown "$USER":"$USER" /opt/n8n
cd /opt/n8n

cat > docker-compose.yml <<'COMPOSE'
services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: CHANGEME_db_password # CHANGE THIS
      N8N_HOST: "n8n.example.com"
      WEBHOOK_URL: "https://n8n.example.com/"
    volumes:
      - ./data:/home/node/.n8n
    ports:
      - "5678:5678"
    depends_on:
      - postgres
    restart: unless-stopped

  postgres:
    image: postgres:16-alpine
    container_name: n8n_postgres
    environment:
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: CHANGEME_db_password # CHANGE THIS
      POSTGRES_DB: n8n
    volumes:
      - ./postgres:/var/lib/postgresql/data
    restart: unless-stopped
COMPOSE

docker compose up -d
echo "n8n is running on http://SERVER_IP:5678"

Stack

TypeScriptNode.jsPostgreSQL