services: n8n: image: n8nio/n8n:latest restart: unless-stopped environment: - NODE_ENV=production - N8N_HOST=${N8N_HOST} - N8N_PORT=${N8N_PORT} - N8N_PROTOCOL=https # Database - DB_TYPE=postgresdb - DB_POSTGRESDB_HOST=postgres - DB_POSTGRESDB_USER=${POSTGRES_USER} - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD} # Configuration - N8N_DIAGNOSTICS_ENABLED=false - N8N_PERSONALIZATION_ENABLED=true - N8N_ENCRYPTION_KEY=${ENCRYPTION_KEY} - N8N_USER_MANAGEMENT_JWT_SECRET - N8N_SECURE_COOKIE=true - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true - N8N_BLOCK_ENV_ACCESS_IN_NODE=true - N8N_PROXY_HOPS=${PROXY_HOPS:-1} - WEBHOOK_URL=https://${N8N_HOST}/ - GENERIC_TIMEZONE=${GENERIC_TIMEZONE} - N8N_TEMPLATES_ENABLED=true - N8N_HIRING_BANNER_ENABLED=false - OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true # Ollama - OLLAMA_HOST=${OLLAMA_HOST:-ollama:11434} # Runners - N8N_RUNNERS_ENABLED=true - N8N_RUNNERS_MODE=external - N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0 - N8N_RUNNERS_AUTH_TOKEN=${N8N_RUNNERS_SECRET} - N8N_NATIVE_PYTHON_RUNNER=true - N8N_RUNNERS_MAX_CONCURRENCY=50 # Logging - EXECUTIONS_DATA_PRUNE=true - EXECUTIONS_DATA_MAX_AGE=7 # Redis - EXECUTIONS_MODE=queue - QUEUE_BULL_REDIS_HOST=redis - QUEUE_BULL_REDIS_PORT=6379 # Emails # - N8N_SMTP_HOST=${SMTP_HOST} # - N8N_SMTP_PORT=${SMTP_PORT} # - N8N_SMTP_USER=${SMTP_USER} # - N8N_SMTP_PASS=${SMTP_PASS} volumes: - n8n_data:/home/node/.n8n depends_on: postgres: condition: service_healthy redis: condition: service_healthy n8n-worker: image: docker.n8n.io/n8nio/n8n:latest restart: always command: worker environment: - NODE_ENV=production - N8N_HOST=${N8N_HOST} - N8N_PORT=${N8N_PORT} - N8N_PROTOCOL=https - EXECUTIONS_MODE=queue - DB_TYPE=postgresdb - DB_POSTGRESDB_HOST=postgres - DB_POSTGRESDB_USER=${POSTGRES_USER} - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD} - N8N_ENCRYPTION_KEY=${ENCRYPTION_KEY} - N8N_SECURE_COOKIE=true - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true - N8N_BLOCK_ENV_ACCESS_IN_NODE=true - N8N_PROXY_HOPS=${PROXY_HOPS} - WEBHOOK_URL=https://${N8N_HOST}/ - GENERIC_TIMEZONE=${GENERIC_TIMEZONE} - QUEUE_BULL_REDIS_HOST=redis - QUEUE_BULL_REDIS_PORT=6379 depends_on: - n8n - redis n8n-runner: image: n8nio/runners:nightly restart: always environment: - N8N_RUNNERS_TASK_BROKER_URI=http://n8n:5679 - N8N_RUNNERS_AUTH_TOKEN=${N8N_RUNNERS_SECRET} - N8N_ENCRYPTION_KEY=${ENCRYPTION_KEY} - GENERIC_TIMEZONE=${GENERIC_TIMEZONE} - N8N_RUNNERS_MAX_CONCURRENCY=50 depends_on: - n8n ollama: image: ollama/ollama:latest restart: unless-stopped volumes: - ollama_storage:/home/node/.ollama init-ollama: image: ollama/ollama:latest volumes: - ollama_storage:/home/node/.ollama entrypoint: /bin/sh environment: - OLLAMA_HOST=ollama:11434 command: - "-c" - "sleep 3; ollama pull llama3.2:latest; ollama pull gemma3:latest" redis: image: redis:7-alpine restart: unless-stopped command: redis-server --appendonly yes healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 volumes: - redis_storage:/data postgres: image: postgres:17-alpine hostname: postgres restart: unless-stopped 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 localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}'] interval: 5s timeout: 5s retries: 10 volumes: n8n_data: postgres_storage: ollama_storage: redis_storage: