@yyoussef11 Let me try it on my environment.
1 Like
Hey, here is compose file which works for me:
x-n8n: &service-n8n
image: n8nio/n8n:latest
networks:
- n8n
environment:
# Required security settings
- N8N_USER_MANAGEMENT_JWT_SECRET=${N8N_USER_MANAGEMENT_JWT_SECRET}
# Task runners configuration
- N8N_RUNNERS_ENABLED=true
- N8N_QUEUE_MODE=redis
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_BULL_REDIS_PORT=6379
# File permissions enforcement
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=false
# Database configuration
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
# Host configuration
- N8N_HOST=n8n.example.com
- WEBHOOK_URL=https://n8n.example.com/
# Security settings
- N8N_DIAGNOSTICS_ENABLED=false
- N8N_PERSONALIZATION_ENABLED=false
- N8N_SECURE_COOKIE=false
- NODE_FUNCTION_ALLOW_EXTERNAL=*
restart: unless-stopped
volumes:
- n8n_storage:/home/node/.n8n:rw
- ./n8n/backup:/backup
- ./shared:/data/shared
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
services:
# Database
postgres:
image: postgres:17-alpine
container_name: postgres
networks:
- n8n
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
volumes:
- postgres_storage:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -h postgres -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 10
# Redis
redis:
image: redis:7-alpine
container_name: n8n-redis
networks:
- n8n
volumes:
- redis_storage:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 5s
retries: 10
# Data Importer
n8n-import:
<<: *service-n8n
container_name: n8n-import
entrypoint: /bin/sh
command:
- "-c"
- |
# Create backup directory if missing
mkdir -p /backup/credentials /backup/workflows
# Import only if files exist
if [ -n "$(ls -A /backup/credentials)" ]; then
n8n import:credentials --separate --input=/backup/credentials
fi
if [ -n "$(ls -A /backup/workflows)" ]; then
n8n import:workflow --separate --input=/backup/workflows
fi
echo "Import completed successfully"
volumes:
- ./n8n/backup:/backup
depends_on:
postgres:
condition: service_healthy
restart: "no"
# Main Service
n8n:
<<: *service-n8n
container_name: n8n-main
environment:
- N8N_EXECUTIONS_MODE=own
- N8N_HOST=n8n.example.com
- WEBHOOK_URL=https://n8n.example.com/
ports:
- "5678:5678"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
n8n-import:
condition: service_completed_successfully
# Webhook Service (Scale via: docker compose up -d --scale n8n-webhook=3)
n8n-webhook:
<<: *service-n8n
environment:
- N8N_EXECUTIONS_MODE=queue
- N8N_HOST=n8n.example.com
- WEBHOOK_URL=https://n8n.example.com/
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
# Worker Service (Scale via: docker compose up -d --scale n8n-worker=5)
n8n-worker:
<<: *service-n8n
entrypoint: /bin/sh
command:
- "-c"
- |
# Create config directory if it doesn't exist
mkdir -p /home/node/.n8n
# Ensure the encryption key is properly set in the config file in JSON format
echo "{\"encryptionKey\": \"${N8N_ENCRYPTION_KEY}\"}" > /home/node/.n8n/config
chmod 600 /home/node/.n8n/config
# Run n8n in queue mode
exec tini -- node /usr/local/lib/node_modules/n8n/bin/n8n start
environment:
- N8N_EXECUTIONS_MODE=queue
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
volumes:
- n8n_storage:/home/node/.n8n:rw
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
n8n:
condition: service_started
# Qdrant Vector Store
qdrant:
image: qdrant/qdrant:latest
container_name: qdrant
networks:
- n8n
ports:
- "6333:6333"
volumes:
- qdrant_storage:/qdrant/storage
networks:
n8n:
driver: bridge
volumes:
n8n_storage:
postgres_storage:
redis_storage:
qdrant_storage:
thanks a lot