I run n8n with Docker in an LXC container.
n8n runs in worker mode, which means that at least two containers are started rather than just one.
The first container handles the web UI and delegates pipeline runs.
The second container only executes pipeline runs.
If a pipeline is started manually in the web UI, it runs through the web UI container. The worker container is configured to execute up to four pipelines in parallel.
Worker mode requires a Redis server to distribute job data.
Redis is the third container in my setup.
Because my n8n instance needs to access services with custom SSL certificates, I mounted my own CA certificate in the containers.
I moved the n8n database to a Postgres server. Since I already run a Postgres server on my network, I do not need a separate database container in this Docker setup.
The docker-compose.yml File
x-n8n: &service-n8n image: n8nio/n8n:1.74.3 env_file: n8n.env networks: - default user: node volumes: - n8n-data:/home/node/.n8n - "./MuenchCA.pem:/MuenchCA.pem:ro" restart: unless-stopped services: n8n: <<: *service-n8n container_name: n8n ports: - 5678:5678 depends_on: redis: condition: service_healthy n8n_worker: <<: *service-n8n container_name: n8n_worker command: worker --concurrency=6 depends_on: - n8n # Webhook container is starting but not working. # Ever webhook call results in a 404 http status. #n8n_webhook: # <<: *service-n8n # container_name: n8n_webhook # command: webhook # depends_on: # - n8n redis: container_name: n8n_redis image: redis:7-alpine restart: unless-stopped networks: - default volumes: - redis-data:/data healthcheck: test: ['CMD', 'redis-cli', 'ping'] interval: 5s timeout: 5s retries: 10 volumes: n8n-data: redis-data:
My .n8n.env File
(Sensitive parameters have been masked)
DB_TYPE=postgresdb DB_POSTGRESDB_DATABASE=n8n DB_POSTGRESDB_HOST=postgres.muench.lan DB_POSTGRESDB_PORT=5432 DB_POSTGRESDB_USER=n8n DB_POSTGRESDB_PASSWORD=xxxxxxxxxxxxxxxxxxxxxxxxxxxx DB_POSTGRESDB_SCHEMA=n8n DB_POSTGRESDB_SSL_REJECT_UNAUTHORIZED=true EXECUTIONS_MODE=queue N8N_DISABLE_PRODUCTION_MAIN_PROCESS=false N8N_CONCURRENCY_PRODUCTION_LIMIT=20 # https://docs.n8n.io/hosting/scaling/execution-data/#reduce-saved-data -> in hours EXECUTIONS_DATA_PRUNE=true EXECUTIONS_DATA_MAX_AGE=168 EXECUTIONS_DATA_PRUNE_MAX_COUNT=10000 QUEUE_BULL_REDIS_HOST=redis QUEUE_HEALTH_CHECK_ACTIVE=true N8N_BASIC_AUTH_ACTIVE=true N8N_BASIC_AUTH_USER=xxxxxxxxxxxxxxxxxxxxxxxxxxxx N8N_BASIC_AUTH_PASSWORD=xxxxxxxxxxxxxxxxxxxxxxxxxxxx N8N_ENCRYPTION_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxx N8N_DIAGNOSTICS_ENABLED=false N8N_HOST=foo.example.com N8N_PORT=5678 N8N_PROTOCOL=https NODE_OPTIONS=--max_old_space_size=4096 NODE_ENV=production WEBHOOK_URL=https://foo.example.com GENERIC_TIMEZONE=Europe/Berlin TZ=Europe/Berlin # required to get DB SSL connection running NODE_EXTRA_CA_CERTS=/MuenchCA.pem # Install custom package dependencies #N8N_CUSTOM_EXTENSIONS=/home/node/.n8n/custom N8N_REINSTALL_MISSING_PACKAGES=true N8N_COMMUNITY_PACKAGES_ENABLED=true # Trust traefik proxy -> See: https://community.n8n.io/t/x-forwarded-for-header-is-set-but-the-express-trust-proxy-s/51208/6 EXPRESS_TRUST_PROXY=true N8N_PROXY_HOPS=1 N8N_LOG_LEVEL=debug