← Back to Work CASE STUDY 02 / INFRASTRUCTURE
PRODUCTION INFRASTRUCTURE

Production n8n Infrastructure.

A self-hosted n8n deployment configured around PostgreSQL, Redis, queue-mode execution and a separate worker process — designed as an operational platform rather than a single-container installation.

Docker Compose · n8n 2.36.8 · PostgreSQL 17 · Redis 7 · Queue Mode
TYPE

Self-hosted infrastructure

ORCHESTRATION

n8n queue mode

DATA LAYER

PostgreSQL 17 + Redis 7

DEPLOYMENT

Docker Compose

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.

01

Persistent state

Database, Redis and n8n application data each receive an explicit named volume.

02

Separated execution

n8n main handles the application surface while a dedicated worker consumes queued executions.

03

Controlled startup

Services use health checks and dependency conditions instead of relying only on container start order.

04

Bounded history

Execution records are pruned by both age and maximum stored count to prevent indefinite growth.

VERIFIED ARCHITECTURE

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 LAYER — OUTSIDE THIS COMPOSE
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
COMPOSE BOUNDARY

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 → postgres
n8n → redis
n8n-worker → postgres
n8n-worker → redis
SERVICE RESPONSIBILITIES

Each container has a defined role.

N8N MAIN

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.

N8N WORKER

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.

POSTGRESQL

Persistent application data

Uses the pgvector/pgvector:pg17 image, with dedicated persistent storage and a readiness check using pg_isready.

REDIS

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.

01

Webhook, editor or API reaches n8n main.

02

Main creates work for the Redis-backed queue.

03

The dedicated worker consumes queued executions.

04

Execution state is persisted through PostgreSQL.

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 & HEALTH

Startup is gated by service health, not just container order.

PostgreSQL healthy ──┐
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.
PERSISTENCE

Stateful services do not rely on ephemeral container filesystems.

VOLUME 01

postgres_data

Mounted at PostgreSQL’s data directory. The database also sets PGDATA to a subdirectory within that persistent path.

VOLUME 02

redis_data

Mounted at /data for Redis persistence, alongside append-only file configuration.

VOLUME 03

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.

PRUNING

Enabled

Automatic execution-data pruning is active.

MAX AGE

168h

Seven-day configured retention window.

MAX COUNT

10,000

Configured upper bound for stored executions.

SECURITY & EXPOSURE

Sensitive configuration is externalised, and the application binds locally by default.

NETWORK EXPOSURE

Loopback binding by default

The published port defaults to 127.0.0.1:5678, rather than binding n8n directly to all network interfaces.

SECRETS

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.

N8N SETTINGS

Application-level safeguards

The configuration enforces settings-file permissions, provides an encryption key, enables the secure-cookie setting, and disables n8n diagnostics.

OPTIONAL FEATURES

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.

PROCESS INIT

init: true

Applied to both n8n main and worker service definitions.

N8N TIMEOUT

60 seconds

Configured graceful-shutdown timeout for both n8n services.

COMPOSE WINDOW

75 seconds

Stop grace period configured on main and worker containers.

DEPLOYMENT EVIDENCE

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.

EVIDENCE SLOT 01

Service status

Anonymised Docker Compose service overview.

EVIDENCE SLOT 02

Queue-mode configuration

Redacted Compose excerpt for main, Redis and worker.

EVIDENCE SLOT 03

n8n instance

Anonymised instance or execution view.

EVIDENCE SLOT 04

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.
WHAT THIS PROJECT DEMONSTRATES

Infrastructure decisions made explicit.

01

Production-minded n8n architecture

A separation between application surface, queue transport, execution worker and persistent data services.

02

Operational configuration

Health-gated dependencies, restart policies, graceful shutdown settings and bounded execution retention.

03

Honest technical scope

Clear distinction between what the Compose stack implements and what would need to be added for a broader production platform.

RELATED TECHNICAL NOTE

Self-hosting n8n with Docker Compose

A practical guide to the deployment decisions behind a self-hosted n8n environment.

NEXT CASE STUDY

Infrastructure is only useful when it supports real workflows.

See how this technical foundation supports a practical automation system built around incoming email operations.