Install and run n8n with Docker -- quick start, production Docker Compose setup with PostgreSQL, and configuration.
Run n8n with a single command using the default SQLite database:
docker run -d \
--name n8n \
-p 5678:5678 \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n
Open http://localhost:5678 to access the n8n editor. This setup is suitable for testing and development only.
For production, use PostgreSQL as the database backend and configure persistent volumes, authentication, and a stable webhook URL.
Create a docker-compose.yml file:
version: "3.8"
services:
n8n:
image: docker.n8n.io/n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
- N8N_HOST=n8n.example.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://n8n.example.com/
- N8N_EDITOR_BASE_URL=https://n8n.example.com/
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=changeme
- N8N_ENCRYPTION_KEY=your-random-encryption-key
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=168
volumes:
- n8n_data:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
postgres:
image: postgres:16-alpine
container_name: n8n-postgres
restart: unless-stopped
environment:
- POSTGRES_DB=n8n
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=changeme
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n"]
interval: 10s
timeout: 5s
retries: 5
volumes:
n8n_data:
postgres_data:
Start the stack:
docker compose up -d
Warning: Change default passwords
Replace
changemewith strong passwords before deploying. SetN8N_ENCRYPTION_KEYto a random string -- this key encrypts stored credentials. If you lose it, all saved credentials become unrecoverable.
| Variable | Purpose | Example |
|---|---|---|
N8N_HOST |
Hostname for the n8n instance | n8n.example.com |
N8N_PROTOCOL |
http or https |
https |
WEBHOOK_URL |
Public URL for webhook endpoints | https://n8n.example.com/ |
DB_TYPE |
Database backend (sqlite or postgresdb) |
postgresdb |
N8N_ENCRYPTION_KEY |
Encrypts stored credentials | Random 32+ character string |
EXECUTIONS_DATA_PRUNE |
Auto-delete old execution data | true |
EXECUTIONS_DATA_MAX_AGE |
Hours to retain execution data | 168 (7 days) |
See the Environment Variables Reference for the full list.
Two volumes are required for a durable setup:
n8n_data -- stores n8n configuration, the SQLite database (if used), and encryption keys.postgres_data -- stores the PostgreSQL database files.Tip
Back up the
postgres_datavolume regularly. Usepg_dumpinside the container for logical backups, or snapshot the volume at the storage layer.
n8n should sit behind a reverse proxy (Nginx, Caddy, Traefik) that handles TLS termination. Key requirements:
Host header and X-Forwarded-* headers to n8n.Upgrade and Connection headers).WEBHOOK_URL to the public URL served by the proxy so that webhook paths resolve correctly.A minimal Caddy configuration:
n8n.example.com {
reverse_proxy n8n:5678
}
Pull the latest image and recreate the container:
docker compose pull n8n
docker compose up -d n8n
Note
Always check the n8n release notes before upgrading. Major version upgrades may include database migrations or breaking changes.
I build production n8n and Cloudflare automation for teams — the same engineering behind HarperFlow. Fixed-price, escrow-protected, US-based.