install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/TerminalSkills/skills/n8n-self-host" ~/.claude/skills/comeonoliver-skillshub-n8n-self-host && rm -rf "$T"
manifest:
skills/TerminalSkills/skills/n8n-self-host/SKILL.mdsource content
n8n Self-Host
Overview
Install, configure, scale, and operate self-hosted n8n instances. Covers Docker Compose production setups, CLI administration, REST API automation, queue-mode scaling with Redis workers, backup/restore, monitoring, and troubleshooting. For building n8n workflows and configuring nodes, see the
n8n-workflow skill.
Instructions
Task A: Production Docker Compose Setup
Basic setup with PostgreSQL (recommended over default SQLite):
# docker-compose.yml services: postgres: image: postgres:16 restart: always environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - db_storage:/var/lib/postgresql/data healthcheck: test: ['CMD-SHELL', 'pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}'] interval: 5s timeout: 5s retries: 10 n8n: image: docker.n8n.io/n8nio/n8n restart: always ports: - "5678:5678" environment: - DB_TYPE=postgresdb - DB_POSTGRESDB_HOST=postgres - DB_POSTGRESDB_PORT=5432 - DB_POSTGRESDB_DATABASE=${POSTGRES_DB} - DB_POSTGRESDB_USER=${POSTGRES_USER} - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD} - N8N_ENCRYPTION_KEY=${ENCRYPTION_KEY} - WEBHOOK_URL=${WEBHOOK_URL} - GENERIC_TIMEZONE=${GENERIC_TIMEZONE:-UTC} - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true - N8N_RUNNERS_ENABLED=true volumes: - n8n_storage:/home/node/.n8n depends_on: postgres: condition: service_healthy volumes: db_storage: n8n_storage:
Create a
.env alongside with POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, ENCRYPTION_KEY (generate with openssl rand -hex 24), WEBHOOK_URL, and GENERIC_TIMEZONE. Start with docker compose up -d.
Task B: Scale with Queue Mode (Redis + Workers)
For high-volume workloads, add Redis and worker processes:
# Add to docker-compose.yml x-n8n-shared: &n8n-shared image: docker.n8n.io/n8nio/n8n restart: always environment: - DB_TYPE=postgresdb - DB_POSTGRESDB_HOST=postgres - DB_POSTGRESDB_DATABASE=${POSTGRES_DB} - DB_POSTGRESDB_USER=${POSTGRES_USER} - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD} - EXECUTIONS_MODE=queue - QUEUE_BULL_REDIS_HOST=redis - QUEUE_HEALTH_CHECK_ACTIVE=true - N8N_ENCRYPTION_KEY=${ENCRYPTION_KEY} volumes: - n8n_storage:/home/node/.n8n depends_on: postgres: condition: service_healthy redis: condition: service_healthy services: redis: image: redis:7-alpine restart: always volumes: - redis_storage:/data healthcheck: test: ['CMD', 'redis-cli', 'ping'] interval: 5s n8n: <<: *n8n-shared ports: - "5678:5678" n8n-worker: <<: *n8n-shared command: worker # Scale with: docker compose up -d --scale n8n-worker=3
Task C: CLI Administration
Run CLI commands inside Docker:
docker exec -u node -it n8n n8n <command>.
# Export/import workflows n8n export:workflow --backup --output=backups/ n8n export:workflow --id=<ID> --output=workflow.json n8n import:workflow --input=workflow.json n8n import:workflow --separate --input=backups/ # Export/import credentials (--decrypted for cross-instance migration) n8n export:credentials --backup --output=backups/ n8n export:credentials --all --decrypted --output=creds.json n8n import:credentials --input=creds.json # Full database backup/restore n8n export:entities --outputDir=./backup --includeExecutionHistoryDataTables=true n8n import:entities --inputDir=./backup --truncateTables=true # Execute a workflow by ID n8n execute --id=<ID> # Activate/deactivate workflows n8n update:workflow --id=<ID> --active=true n8n update:workflow --all --active=false # User management n8n user-management:reset # Reset to setup state (forgot password) n8n mfa:disable --email=user@x.com # Disable MFA for locked-out user # Security audit n8n audit # Database migration rollback n8n db:revert
Task D: REST API Automation
Enable the API at
/api/v1/docs. Authenticate with X-N8N-API-KEY header.
# List all workflows curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" http://localhost:5678/api/v1/workflows | jq '.data[].name' # Activate a workflow curl -X POST -H "X-N8N-API-KEY: $N8N_API_KEY" http://localhost:5678/api/v1/workflows/<ID>/activate # Deactivate a workflow curl -X POST -H "X-N8N-API-KEY: $N8N_API_KEY" http://localhost:5678/api/v1/workflows/<ID>/deactivate # Retry a failed execution curl -X POST -H "X-N8N-API-KEY: $N8N_API_KEY" http://localhost:5678/api/v1/executions/<ID>/retry # List failed executions curl -s -H "X-N8N-API-KEY: $N8N_API_KEY" "http://localhost:5678/api/v1/executions?status=error" | jq '.data[] | {id, workflowId, status}' # Create a variable curl -X POST -H "X-N8N-API-KEY: $N8N_API_KEY" -H "Content-Type: application/json" \ -d '{"key":"ENV","value":"production"}' http://localhost:5678/api/v1/variables
Task E: Key Environment Variables
| Variable | Default | Purpose |
|---|---|---|
| | or |
| random | Credential encryption (preserve across restarts) |
| auto | Public URL for webhooks behind reverse proxy |
| | or (for scaling) |
| | Auto-prune old execution data |
| | Max execution age in hours |
| | Enable Prometheus endpoint |
| | , , , |
| | , (comma-separated) |
| | Max concurrent production executions |
| | Enable task runners for Code nodes |
| | Timezone for schedule triggers |
Use
_FILE suffix for Docker Secrets (e.g., DB_POSTGRESDB_PASSWORD_FILE=/run/secrets/db_pass).
Examples
Example 1: Deploy n8n with PostgreSQL in production
User request: "Set up n8n in production with Docker Compose"
Actions taken:
$ mkdir n8n-production && cd n8n-production # Generate secrets $ openssl rand -hex 24 > a1b2c3d4e5f6... # Create .env with POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, # ENCRYPTION_KEY, WEBHOOK_URL, GENERIC_TIMEZONE # Create docker-compose.yml (Task A template) $ docker compose up -d > [+] Running 3/3 > ✔ Network n8n-production_default Created > ✔ Container postgres Started > ✔ Container n8n Started $ docker compose logs n8n --tail 5 > n8n | Editor is now accessible via: http://localhost:5678
Example 2: Back up and restore workflows
User request: "Back up all my n8n workflows and credentials"
Actions taken:
$ docker exec -u node n8n n8n export:workflow --backup --output=/home/node/.n8n/backups/ > Successfully exported 12 workflows $ docker exec -u node n8n n8n export:credentials --backup --output=/home/node/.n8n/backups/ > Successfully exported 8 credentials # Copy backups out of the container $ docker cp n8n:/home/node/.n8n/backups/ ./n8n-backups/ # Restore on a new instance $ docker cp ./n8n-backups/ n8n-new:/home/node/.n8n/backups/ $ docker exec -u node n8n-new n8n import:workflow --separate --input=/home/node/.n8n/backups/ > Successfully imported 12 workflows
Example 3: Troubleshoot a failing instance
User request: "My n8n instance is crashing after update"
Actions taken:
$ docker compose logs n8n --tail 30 > error: Migration failed: column "x" already exists # Rollback the last migration $ docker exec -u node n8n n8n db:revert > Reverted migration: AddColumnX1234567890 # Pin to previous working version in docker-compose.yml # image: docker.n8n.io/n8nio/n8n:1.80.0 $ docker compose up -d > n8n | Editor is now accessible via: http://localhost:5678
Guidelines
- Always set
explicitly and back it up. Without it, credentials cannot be decrypted on a new instance.N8N_ENCRYPTION_KEY - Use PostgreSQL for any instance running more than a few workflows. SQLite doesn't handle concurrent writes well.
- Set
when behind a reverse proxy — webhooks fail silently without it.WEBHOOK_URL - Use
when migrating between instances with different encryption keys.n8n export:credentials --decrypted - Enable execution pruning (
) to prevent database bloat.EXECUTIONS_DATA_PRUNE=true - In queue mode, all instances must share the same
and PostgreSQL database.N8N_ENCRYPTION_KEY - Scale workers with
.docker compose up -d --scale n8n-worker=N - Run
periodically to detect security issues in your instance configuration.n8n audit - For health checks, use
(basic) and/healthz
(DB-aware)./healthz/readiness - Use
temporarily when troubleshooting, then revert toN8N_LOG_LEVEL=debug
.info