name: n8n services: # =========================================================================== # n8n Postgres (required for reliable production deployments) # =========================================================================== n8n-db: image: postgres:15-alpine restart: unless-stopped environment: POSTGRES_USER: ${DB_USERNAME} POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_DB: ${DB_DATABASE} volumes: - ./n8n-db-data:/var/lib/postgresql/data healthcheck: test: [ "CMD", "pg_isready", "-h", "n8n-db", "-U", "${DB_USERNAME:-n8n}", "-d", "${DB_DATABASE:-n8n}", ] interval: 5s timeout: 3s retries: 30 networks: - n8n # =========================================================================== # n8n Redis (queue broker) # =========================================================================== n8n-redis: image: redis:7-alpine restart: unless-stopped command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD} volumes: - ./n8n-redis-data:/data healthcheck: test: [ "CMD-SHELL", "redis-cli -a ${REDIS_PASSWORD:-change-me} ping | grep -q PONG", ] interval: 5s timeout: 3s retries: 30 networks: - n8n # =========================================================================== # n8n main process (UI + API + scheduler) # =========================================================================== n8n-main: image: docker.n8n.io/n8nio/n8n:${N8N_VERSION:-stable} restart: unless-stopped depends_on: n8n-db: condition: service_healthy n8n-redis: condition: service_healthy ports: - ${EXPOSE_N8N_PORT:-5678}:5678 environment: NODE_ENV: ${NODE_ENV:-production} TZ: ${GENERIC_TIMEZONE:-UTC} GENERIC_TIMEZONE: ${GENERIC_TIMEZONE:-UTC} N8N_LOG_LEVEL: ${N8N_LOG_LEVEL:-info} N8N_DIAGNOSTICS_ENABLED: ${N8N_DIAGNOSTICS_ENABLED:-false} N8N_VERSION_NOTIFICATIONS_ENABLED: ${N8N_VERSION_NOTIFICATIONS_ENABLED:-false} N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: ${N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS:-true} N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY} N8N_HOST: ${N8N_HOST:-n8n.ld50.xyz} N8N_PROTOCOL: ${N8N_PROTOCOL:-https} N8N_PORT: ${N8N_PORT:-5678} N8N_EDITOR_BASE_URL: ${N8N_EDITOR_BASE_URL:-https://n8n.ld50.xyz} WEBHOOK_URL: ${WEBHOOK_URL:-https://n8n.ld50.xyz/} EXECUTIONS_MODE: ${EXECUTIONS_MODE:-queue} DB_TYPE: postgresdb DB_POSTGRESDB_HOST: ${DB_HOST:-n8n-db} DB_POSTGRESDB_PORT: ${DB_PORT:-5432} DB_POSTGRESDB_DATABASE: ${DB_DATABASE:-n8n} DB_POSTGRESDB_USER: ${DB_USERNAME:-n8n} DB_POSTGRESDB_PASSWORD: ${DB_PASSWORD} QUEUE_BULL_REDIS_HOST: ${QUEUE_BULL_REDIS_HOST:-n8n-redis} QUEUE_BULL_REDIS_PORT: ${QUEUE_BULL_REDIS_PORT:-6379} QUEUE_BULL_REDIS_PASSWORD: ${REDIS_PASSWORD} QUEUE_HEALTH_CHECK_ACTIVE: ${QUEUE_HEALTH_CHECK_ACTIVE:-true} # OpenTelemetry — export traces to the otel-lgtm pipeline OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://lgtm:4318} OTEL_EXPORTER_OTLP_PROTOCOL: ${OTEL_EXPORTER_OTLP_PROTOCOL:-http/protobuf} OTEL_SERVICE_NAME: ${OTEL_SERVICE_NAME:-n8n-main} OTEL_RESOURCE_ATTRIBUTES: ${OTEL_RESOURCE_ATTRIBUTES:-deployment.environment=production} volumes: - ./n8n-data:/home/node/.n8n - ./n8n-files:/files networks: - n8n # - external_network - pipeline # =========================================================================== # n8n worker (executes queued jobs) # Scale this service out with: docker compose up -d --scale n8n-worker=3 # =========================================================================== n8n-worker: image: docker.n8n.io/n8nio/n8n:${N8N_VERSION:-stable} restart: unless-stopped command: worker --concurrency=${N8N_WORKER_CONCURRENCY:-10} depends_on: n8n-db: condition: service_healthy n8n-redis: condition: service_healthy environment: NODE_ENV: ${NODE_ENV:-production} TZ: ${GENERIC_TIMEZONE:-UTC} GENERIC_TIMEZONE: ${GENERIC_TIMEZONE:-UTC} N8N_LOG_LEVEL: ${N8N_LOG_LEVEL:-info} N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: ${N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS:-true} N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY} EXECUTIONS_MODE: ${EXECUTIONS_MODE:-queue} DB_TYPE: postgresdb DB_POSTGRESDB_HOST: ${DB_HOST:-n8n-db} DB_POSTGRESDB_PORT: ${DB_PORT:-5432} DB_POSTGRESDB_DATABASE: ${DB_DATABASE:-n8n} DB_POSTGRESDB_USER: ${DB_USERNAME:-n8n} DB_POSTGRESDB_PASSWORD: ${DB_PASSWORD} QUEUE_BULL_REDIS_HOST: ${QUEUE_BULL_REDIS_HOST:-n8n-redis} QUEUE_BULL_REDIS_PORT: ${QUEUE_BULL_REDIS_PORT:-6379} QUEUE_BULL_REDIS_PASSWORD: ${REDIS_PASSWORD} QUEUE_HEALTH_CHECK_ACTIVE: ${QUEUE_HEALTH_CHECK_ACTIVE:-true} # OpenTelemetry — export traces to the otel-lgtm pipeline OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://lgtm:4318} OTEL_EXPORTER_OTLP_PROTOCOL: ${OTEL_EXPORTER_OTLP_PROTOCOL:-http/protobuf} OTEL_SERVICE_NAME: ${OTEL_SERVICE_NAME:-n8n-worker} OTEL_RESOURCE_ATTRIBUTES: ${OTEL_RESOURCE_ATTRIBUTES:-deployment.environment=production} volumes: - ./n8n-data:/home/node/.n8n - ./n8n-files:/files networks: - n8n - pipeline networks: n8n: name: n8n driver: bridge # external_network: # name: ${NETWORKS_EXTERNAL_NAME:-swag} # external: true pipeline: name: pipeline external: true