n8n Workflow Automation on Linux with Postgres and Queue Mode
Automation

n8n Workflow Automation on Linux with Postgres and Queue Mode

  • AuthorTimothy M.
  • Date
  • Time19 minutes

n8n is an open-source workflow automation platform that connects APIs, webhooks, databases, and internal tools without forcing every integration into custom code. A single-container demo is fine for testing; production needs PostgreSQL, encryption keys, HTTPS, and preferably queue mode so long-running jobs do not block the UI process.

Prerequisites

  • Linux server with Docker and Compose (4 GB RAM recommended)
  • DNS for n8n.example.com
  • SMTP credentials if you want email notifications and invites

Step 1: Generate Secrets

bash
mkdir -p /opt/n8n && cd /opt/n8n
ENCRYPTION_KEY=$(openssl rand -hex 24)
POSTGRES_PASSWORD=$(openssl rand -hex 16)
echo "N8N_ENCRYPTION_KEY=$ENCRYPTION_KEY" > .env
echo "POSTGRES_PASSWORD=$POSTGRES_PASSWORD" >> .env
chmod 600 .env
cat .env

Step 2: Docker Compose with Queue Mode

bash
tee docker-compose.yml >/dev/null <<'EOF'
services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: \${POSTGRES_PASSWORD}
      POSTGRES_DB: n8n
    volumes:
      - n8n_postgres:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: ["redis-server", "--appendonly", "yes"]
    volumes:
      - n8n_redis:/data

  n8n:
    image: n8nio/n8n:1.72.1
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_started
    ports:
      - "127.0.0.1:5678:5678"
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: \${POSTGRES_PASSWORD}
      N8N_ENCRYPTION_KEY: \${N8N_ENCRYPTION_KEY}
      N8N_HOST: n8n.example.com
      N8N_PROTOCOL: https
      WEBHOOK_URL: https://n8n.example.com/
      N8N_PORT: 5678
      EXECUTIONS_MODE: queue
      QUEUE_BULL_REDIS_HOST: redis
      N8N_RUNNERS_ENABLED: "true"
    volumes:
      - n8n_data:/home/node/.n8n

  n8n-worker:
    image: n8nio/n8n:1.72.1
    restart: unless-stopped
    command: worker
    depends_on:
      - n8n
      - redis
      - postgres
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: \${POSTGRES_PASSWORD}
      N8N_ENCRYPTION_KEY: \${N8N_ENCRYPTION_KEY}
      EXECUTIONS_MODE: queue
      QUEUE_BULL_REDIS_HOST: redis
      N8N_RUNNERS_ENABLED: "true"
    volumes:
      - n8n_data:/home/node/.n8n

volumes:
  n8n_postgres:
  n8n_redis:
  n8n_data:
EOF
docker compose up -d
docker compose ps

Step 3: Reverse Proxy and TLS

bash
sudo tee /etc/nginx/sites-available/n8n >/dev/null <<'EOF'
server {
    listen 80;
    server_name n8n.example.com;

    location / {
        proxy_pass http://127.0.0.1:5678;
        proxy_http_version 1.1;
        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_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        client_max_body_size 50M;
    }
}
EOF
sudo ln -sf /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/n8n
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d n8n.example.com --redirect

Step 4: Owner Account and First Workflow

Open https://n8n.example.com, create the owner account, then build a simple webhook workflow. Confirm queue mode by checking that executions appear while the worker container stays healthy under load.

bash
docker compose logs -f n8n-worker
curl -X POST https://n8n.example.com/webhook-test/health-check

Step 5: Backup Credentials and Database

bash
docker compose exec -T postgres pg_dump -U n8n n8n | gzip > /var/backups/n8n-$(date +%F).sql.gz
# Keep .env and n8n_data volume backups together — encryption key loss means credential loss.

Production Checklist

  • Never lose N8N_ENCRYPTION_KEY; store it offline as well as in .env.
  • Use queue mode for webhook-heavy or long-running automations.
  • Restrict public webhook paths and authenticate where possible.
  • Pin n8n image versions and test upgrades on a staging stack first.
  • Monitor Postgres size and Redis memory as execution history grows.

"Automation platforms fail quietly until credentials, webhooks, and queue workers are treated like production services."

Technical Author

Timothy M.

Timothy M.

Support and server administration. Writes the work on the host: packages, services, and what to check when a machine misbehaves.