services: mockapi: image: wiremock/wiremock:3.9.1 ports: - '8088:8080' volumes: - ${MOCK_API_DATA_PATH}/mappings:/home/wiremock/mappings redis: image: redis:6-alpine restart: always ports: - 6379:6379 healthcheck: test: ['CMD', 'redis-cli', 'ping'] interval: 1s timeout: 3s postgres: image: postgres:16 restart: always environment: - POSTGRES_DB=n8n - POSTGRES_USER=postgres - POSTGRES_PASSWORD=password - PGDATA=/var/lib/postgresql/data/pgdata volumes: - ${RUN_DIR}/postgres:/var/lib/postgresql/data healthcheck: test: ['CMD-SHELL', 'pg_isready -U postgres'] interval: 5s timeout: 5s retries: 10 n8n_worker1: image: ghcr.io/n8n-io/n8n:${N8N_VERSION:-latest} environment: - N8N_DIAGNOSTICS_ENABLED=false - N8N_USER_FOLDER=/n8n/worker1 - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY} - N8N_LICENSE_CERT=${N8N_LICENSE_CERT} - N8N_LICENSE_ACTIVATION_KEY=${N8N_LICENSE_ACTIVATION_KEY} - N8N_LICENSE_TENANT_ID=${N8N_LICENSE_TENANT_ID} # Scaling mode config - EXECUTIONS_MODE=queue - QUEUE_BULL_REDIS_HOST=redis - QUEUE_HEALTH_CHECK_ACTIVE=true - N8N_CONCURRENCY_PRODUCTION_LIMIT=10 # DB config - DB_TYPE=postgresdb - DB_POSTGRESDB_HOST=postgres - DB_POSTGRESDB_PASSWORD=password command: worker volumes: - ${RUN_DIR}/n8n-worker1:/n8n depends_on: postgres: condition: service_healthy redis: condition: service_healthy healthcheck: test: ['CMD-SHELL', 'wget --spider -q http://localhost:5678/healthz || exit 1'] interval: 5s timeout: 5s retries: 10 n8n_worker2: image: ghcr.io/n8n-io/n8n:${N8N_VERSION:-latest} environment: - N8N_DIAGNOSTICS_ENABLED=false - N8N_USER_FOLDER=/n8n/worker2 - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY} - N8N_LICENSE_CERT=${N8N_LICENSE_CERT} - N8N_LICENSE_ACTIVATION_KEY=${N8N_LICENSE_ACTIVATION_KEY} - N8N_LICENSE_TENANT_ID=${N8N_LICENSE_TENANT_ID} # Scaling mode config - EXECUTIONS_MODE=queue - QUEUE_BULL_REDIS_HOST=redis - QUEUE_HEALTH_CHECK_ACTIVE=true - N8N_CONCURRENCY_PRODUCTION_LIMIT=10 # DB config - DB_TYPE=postgresdb - DB_POSTGRESDB_HOST=postgres - DB_POSTGRESDB_PASSWORD=password command: worker volumes: - ${RUN_DIR}/n8n-worker2:/n8n depends_on: # We let the worker 1 start first so it can run the DB migrations n8n_worker1: condition: service_healthy postgres: condition: service_healthy redis: condition: service_healthy healthcheck: test: ['CMD-SHELL', 'wget --spider -q http://localhost:5678/healthz || exit 1'] interval: 5s timeout: 5s retries: 10 n8n_main2: image: ghcr.io/n8n-io/n8n:${N8N_VERSION:-latest} environment: - N8N_DIAGNOSTICS_ENABLED=false - N8N_USER_FOLDER=/n8n - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY} - N8N_LICENSE_CERT=${N8N_LICENSE_CERT} - N8N_LICENSE_ACTIVATION_KEY=${N8N_LICENSE_ACTIVATION_KEY} - N8N_LICENSE_TENANT_ID=${N8N_LICENSE_TENANT_ID} # Scaling mode config - EXECUTIONS_MODE=queue - QUEUE_BULL_REDIS_HOST=redis - N8N_MULTI_MAIN_SETUP_ENABLED=true # DB config - DB_TYPE=postgresdb - DB_POSTGRESDB_HOST=postgres - DB_POSTGRESDB_PASSWORD=password volumes: - ${RUN_DIR}/n8n-main2:/n8n depends_on: n8n_worker1: condition: service_healthy n8n_worker2: condition: service_healthy postgres: condition: service_healthy redis: condition: service_healthy mockapi: condition: service_started healthcheck: test: ['CMD-SHELL', 'wget --spider -q http://n8n_main2:5678/healthz || exit 1'] interval: 5s timeout: 5s retries: 10 n8n_main1: image: ghcr.io/n8n-io/n8n:${N8N_VERSION:-latest} environment: - N8N_DIAGNOSTICS_ENABLED=false - N8N_USER_FOLDER=/n8n - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY} - N8N_LICENSE_CERT=${N8N_LICENSE_CERT} - N8N_LICENSE_ACTIVATION_KEY=${N8N_LICENSE_ACTIVATION_KEY} - N8N_LICENSE_TENANT_ID=${N8N_LICENSE_TENANT_ID} # Scaling mode config - EXECUTIONS_MODE=queue - QUEUE_BULL_REDIS_HOST=redis - N8N_MULTI_MAIN_SETUP_ENABLED=true # DB config - DB_TYPE=postgresdb - DB_POSTGRESDB_HOST=postgres - DB_POSTGRESDB_PASSWORD=password volumes: - ${RUN_DIR}/n8n-main1:/n8n depends_on: n8n_worker1: condition: service_healthy n8n_worker2: condition: service_healthy postgres: condition: service_healthy redis: condition: service_healthy mockapi: condition: service_started healthcheck: test: ['CMD-SHELL', 'wget --spider -q http://n8n_main1:5678/healthz || exit 1'] interval: 5s timeout: 5s retries: 10 # Load balancer that acts as an entry point for n8n n8n: image: nginx:latest ports: - '5678:80' volumes: - ./nginx.conf:/etc/nginx/nginx.conf depends_on: n8n_main1: condition: service_healthy n8n_main2: condition: service_healthy benchmark: image: ghcr.io/n8n-io/n8n-benchmark:${N8N_BENCHMARK_VERSION:-latest} depends_on: - n8n environment: - N8N_BASE_URL=http://n8n:80 - K6_API_TOKEN=${K6_API_TOKEN} - BENCHMARK_RESULT_WEBHOOK_URL=${BENCHMARK_RESULT_WEBHOOK_URL} - BENCHMARK_RESULT_WEBHOOK_AUTH_HEADER=${BENCHMARK_RESULT_WEBHOOK_AUTH_HEADER}