A basic n8n container is useful for testing. It is not the same as an operational deployment.
Once workflows become part of real operations, the deployment needs explicit decisions about persistence, execution handling, startup order, retention, credentials and network exposure. This project documents those decisions in the Compose configuration itself.
The scope is deliberately narrow: this is a single-server Docker Compose stack. It does not claim high availability, managed backups, external monitoring or a reverse-proxy implementation that is not present in the deployment files.
The deployment needed clear operational boundaries.
Persistent state
Database, Redis and n8n application data each receive an explicit named volume.
Separated execution
n8n main handles the application surface while a dedicated worker consumes queued executions.
Controlled startup
Services use health checks and dependency conditions instead of relying only on container start order.
Bounded history
Execution records are pruned by both age and maximum stored count to prevent indefinite growth.
Four services with explicit responsibilities.
This diagram reflects the Docker Compose stack. External ingress or TLS termination is intentionally outside the boundary because it is not defined in this Compose file.
External endpoint configuration
WEBHOOK_URL / N8N_EDITOR_BASE_URL
127.0.0.1:5678
↓
n8n main
editor · API · webhooks · queue producer
↓
Redis 7
queue transport · AOF persistence
↓
n8n worker
worker command · concurrency default: 3
↓
workflow execution
n8n main + n8n worker
└── PostgreSQL 17 image with pgvector
Local binding, external endpoint configuration.
The n8n port is bound to 127.0.0.1:5678 by default. The environment file defines HTTPS host and webhook URLs, but no reverse proxy, Cloudflare Tunnel or ingress service is included in the Compose stack.
n8n → redis
n8n-worker → postgres
n8n-worker → redis
Each container has a defined role.
Application surface
Runs the editor, API and webhook-facing application process. It creates jobs for queue-mode execution and connects to both PostgreSQL and Redis.
Queued execution
Runs the n8n worker command against the same database, Redis queue and shared n8n data volume. Default configured concurrency is 3 within one worker container — not three worker containers.
Persistent application data
Uses the pgvector/pgvector:pg17 image, with dedicated persistent storage and a readiness check using pg_isready.
Queue transport
Redis 7 is configured for password authentication, append-only persistence, appendfsync everysec and a noeviction memory policy.
The interface process and execution process are separated.
Both n8n services explicitly use EXECUTIONS_MODE=queue. Redis carries queued work, while the worker container starts with a configurable concurrency value.
n8n-worker:
image: docker.n8n.io/n8nio/n8n:2.36.8
command: worker --concurrency=${N8N_WORKER_CONCURRENCY:-3}
environment:
EXECUTIONS_MODE: queue
QUEUE_BULL_REDIS_HOST: redis
DB_TYPE: postgresdb
Startup is gated by service health, not just container order.
Redis healthy ───────┴──→ n8n main starts
n8n main readiness check
n8n main healthy ───────→ n8n worker starts
Configured checks and dependencies
- PostgreSQL uses
pg_isready. - Redis uses authenticated
redis-cli ping. - n8n main and worker definitions include readiness health checks.
- n8n waits for PostgreSQL and Redis to be healthy.
- The worker additionally waits for n8n main to be healthy.
- All service definitions use
restart: unless-stopped.
Stateful services do not rely on ephemeral container filesystems.
postgres_data
Mounted at PostgreSQL’s data directory. The database also sets PGDATA to a subdirectory within that persistent path.
redis_data
Mounted at /data for Redis persistence, alongside append-only file configuration.
n8n_data
Mounted by both n8n main and the worker at /home/node/.n8n.
Execution history is retained with explicit limits.
Pruning is enabled in n8n. Historical execution data is limited by both maximum age and a maximum record count, making retention a visible infrastructure decision rather than an unbounded default.
Enabled
Automatic execution-data pruning is active.
168h
Seven-day configured retention window.
10,000
Configured upper bound for stored executions.
Sensitive configuration is externalised, and the application binds locally by default.
Loopback binding by default
The published port defaults to 127.0.0.1:5678, rather than binding n8n directly to all network interfaces.
Credentials are supplied through environment variables
PostgreSQL credentials, Redis password and the n8n encryption key are referenced from the environment file rather than hard-coded in the Compose definition.
Application-level safeguards
The configuration enforces settings-file permissions, provides an encryption key, enables the secure-cookie setting, and disables n8n diagnostics.
Conservative defaults in the example environment
The supplied environment example sets community packages and n8n metrics to false. It also specifies HTTPS protocol and public URLs without defining the external ingress component itself.
Containers are configured to stop with time to finish cleanly.
init: true
Applied to both n8n main and worker service definitions.
60 seconds
Configured graceful-shutdown timeout for both n8n services.
75 seconds
Stop grace period configured on main and worker containers.
Evidence belongs beside the architecture.
Replace the slots below with real, anonymised deployment screenshots. Do not show passwords, encryption keys, hostnames, webhook URLs, container IDs or workflow data.
Service status
Anonymised Docker Compose service overview.
Queue-mode configuration
Redacted Compose excerpt for main, Redis and worker.
n8n instance
Anonymised instance or execution view.
Operational configuration
Redacted evidence of persistence, health or retention settings.
Deliberately useful, not falsely over-engineered.
- This Compose stack runs within a single-server failure domain.
- Named volumes provide persistence, but the Compose file does not define a backup process or restore procedure.
- No high-availability topology, multi-worker replica configuration or orchestration platform is defined.
- No reverse proxy, Cloudflare Tunnel, TLS termination or external ingress service appears in this Compose file.
- Metrics are set to false in the supplied environment example; no external observability stack is defined here.
Infrastructure decisions made explicit.
Production-minded n8n architecture
A separation between application surface, queue transport, execution worker and persistent data services.
Operational configuration
Health-gated dependencies, restart policies, graceful shutdown settings and bounded execution retention.
Honest technical scope
Clear distinction between what the Compose stack implements and what would need to be added for a broader production platform.
Self-hosting n8n with Docker Compose
A practical guide to the deployment decisions behind a self-hosted n8n environment.
