Learn how to deploy a fully self-hosted n8n automation platform using Docker and Docker Compose — including SSL configuration, persistent storage, environment variables, and best DevOps practices for a secure and reliable setup
Customize Your Configuration
1.Modify the desired values in the Docker Compose file as needed
services:
postgres:
image: postgres:15
container_name: postgres
restart: always
environment:
POSTGRES_USER: n8nuser
POSTGRES_PASSWORD: $Tr0nGp@ssWord
POSTGRES_DB: n8n
volumes:
- ./postgres_data:/var/lib/postgresql/data
n8n:
image: n8nio/n8n:1.109.2-exp.0-amd64
container_name: n8n
restart: always
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_PORT: 5432
DB_POSTGRESDB_USER: n8nuser
DB_POSTGRESDB_PASSWORD: $Tr0nGp@ssWord
DB_POSTGRESDB_DATABASE: n8n
N8N_HOST: YOUR-DOMAIN.com
N8N_PORT: 5678
N8N_PROTOCOL: http
NODE_ENV: production
expose:
- "5678"
depends_on:
- postgres
nginx:
image: nginx:stable-alpine3.21
container_name: nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/certs:/etc/nginx/certs
depends_on:
- n8n
2.Adjust the necessary settings in the Nginx configuration file according to your needs
server {
listen 80;
server_name YOUR-DOMAIN.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name YOUR-DOMAIN.com;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
location / {
proxy_pass http://n8n:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
3.Directory tree structure
n8n/
├── docker-compose.yml
├── postgres_data/
└── nginx/
├── conf.d/
│ └── default.conf
└── certs/
├── fullchain.pem
└── privkey.pem