Royzero
2026. 1. 6. 10:58
TL;DR
Table of Contents
- text
- 1) How to ‘design’ n8n self-hosting from an operational perspective
- 2) Template #1: Fastest operational (official Docker Compose + TLS)
- 3) Template #2: Postgres + (optional) Redis Queue mode operation template
- 4) Queue mode (scalable execution) design points
- 5) Practical Docker Compose example (operational template)
- 6) N8N_ENCRYPTION_KEY: A value that must ‘never’ be lost during operation.
- 7) Execution data storage/organization policy
- 8) Observation: Prometheus Metrics and Queue Metrics
- 9) Backup/Recovery: Save workflow/credentials as ‘files’
- 10) TLS/Certificate: HTTP-01 requires port 80 (practical tip)
- 11) Operation checklist (for practical use)
- Conclusion (Summary)
- To self-host n8n “like a real service”, you need to: Persistent data (Workflow/Execution/Credential), Webhook URL consistency, Encryption Key Management, Logs/Metrics/Pruning You need to set it up to .
- For small businesses, the official Docker Compose (traffic + TLS) configuration is fast, and if you want scalability/durability, Postgres + (optional) Redis queue modeIt is the norm to go to .
- Issues that frequently arise in operation are “Webhook URL is twisted behind the reverse proxy”, “N8N_ENCRYPTION_KEY is lost”, and “Execution data explosion”. This article provides a template and checklist to prevent those three things first.
text
1) How to ‘design’ n8n self-hosting from an operational perspective
n8n is basically SQLiteUse to store workflow/execution history/credentials, etc., and in self-hosting, PostgreSQLYou can switch to .
Also n8n is in v1.0 Deprecate MySQL/MariaDB support(To be discontinued/not recommended) Now that we’ve taken care of it, if you’re designing something new, I recommend going with Postgres.
To simplify operational design, you only need to “decide” four things:
| decision item | Choice | Practice recommendation |
|---|---|---|
| DB | SQLite / Postgres | Operated by Postgres |
| How it runs | Basic / Queue mode | Queue when traffic/parallel is required |
| Reverse proxy/TLS | Traefik / Nginx / LB | Standardize on one thing |
| Data Pruning | Default/Tuning | Must tune |
Why it matters: In self-hosting, most failures occur not in “functions” but in “operational fundamentals (persistence/security/observability).” If you get these four things fixed from the beginning, subsequent workflow development will be much easier.
2) Template #1: Fastest operational (official Docker Compose + TLS)
The n8n official documentation provides procedures for running Docker Compose on a Linux server, with examples: n8n + Traefik (Certificate/TLS/Routing) We will guide you through configuring two containers.
Additionally, the official example shows that n8n data (e.g. SQLite DB file, encryption key) is Save to volumeIt is stated that this is possible.
Point: “Start small, but install HTTPS/TLS and persistent volume.”
2-1) Values to keep in mind in the formula flow (.env core)
The official Compose guide is .envProvides an example of placing domain/subdomain/time zone/certificate email, etc.
Additional values that are frequently used (or must be fixed) in practice are listed below.
# n8n Base URL 정합성(리버스 프록시 뒤에서 특히 중요)
N8N_PROTOCOL=https
N8N_HOST=n8n.example.com
N8N_PORT=5678
# 외부 웹훅 URL(외부 시스템이 콜백할 주소를 강제)
WEBHOOK_URL=
N8N_HOST / N8N_PORT / N8N_PROTOCOL and WEBHOOK_URLis documented as a deployment/endpoint configuration variable in n8n.
Why it matters: If URLs are messed up behind a reverse proxy, webhook callbacks from services like Slack/Stripe/GitHub will fail, or the editor UI will generate incorrect URLs. This is the most common “self-hosting pitfall” in operations.
3) Template #2: Postgres + (optional) Redis Queue mode operation template
3-1) Reasons to change to Postgres (based on facts)
- n8n in basic SQLite Can switch to Postgresand provides documentation of the environment variables required when using Postgres.
- The DB environment variable page is based on v1.0. MySQL/MariaDB 지원 deprecateSpecifies.
3-2) Minimum set of Postgres environment variables
Postgres configuration variables in the n8n document are organized as follows.
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n
DB_POSTGRESDB_USER=n8n
DB_POSTGRESDB_PASSWORD=change-me
DB_POSTGRESDB_SCHEMA=public
Why it matters: As the workflow increases, the DB grows faster, including execution history/log/binary data (attached). If you start with SQLite, there will soon be limitations in “capacity/performance/backup”.
4) Queue mode (scalable execution) design points
Queue mode-related environment variables are separately organized in the n8n document, including Redis connection information (host/port/password, etc.) and execution method (e.g. EXECUTIONS_MODE = queueThe cluster setup behavior is documented.
Example (.env):
# 실행 모드
EXECUTIONS_MODE=queue
# Redis (Bull queue) 연결
QUEUE_BULL_REDIS_HOST=redis
QUEUE_BULL_REDIS_PORT=6379
QUEUE_BULL_REDIS_PASSWORD=change-me
Note: Worker/main separation execution method in queue mode is covered in the n8n “Configuring queue mode” document (configuration philosophy/scaling perspective).
Why it matters: As traffic grows, the structure of “one container handles all web UI + execution” becomes a bottleneck. Queue mode is a direction that separates execution to enable horizontal expansion.
5) Practical Docker Compose example (operational template)
The compose below is Postgres + Redis + n8nThis is a minimal operational example. (This is an example based on the environment variable definitions in the official document. In actual operation, please modify it to suit your network/security policy.)
services:
postgres:
image: postgres:16
environment:
POSTGRES_DB: n8n
POSTGRES_USER: n8n
POSTGRES_PASSWORD: change-me
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7
command: ["redis-server", "--requirepass", "change-me"]
volumes:
- redis_data:/data
n8n:
image: docker.n8n.io/n8nio/n8n
ports:
- "5678:5678"
environment:
# Base URL / Webhook
- N8N_PROTOCOL=https
- N8N_HOST=n8n.example.com
- N8N_PORT=5678
- WEBHOOK_URL=
# Encryption key (반드시 고정)
- N8N_ENCRYPTION_KEY=replace-with-32+chars-secret
# Database (Postgres)
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=change-me
# Queue mode + Redis
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_BULL_REDIS_PORT=6379
- QUEUE_BULL_REDIS_PASSWORD=change-me
# Execution pruning (기본 활성화지만, 운영에서는 정책을 명시)
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=336
- EXECUTIONS_DATA_PRUNE_MAX_COUNT=10000
# Metrics (Prometheus)
- N8N_METRICS=true
- N8N_METRICS_INCLUDE_QUEUE_METRICS=true
# Queue mode에서는 filesystem 바이너리 모드를 지원하지 않음 → database 권장
- N8N_DEFAULT_BINARY_DATA_MODE=database
volumes:
- n8n_data:/home/node/.n8n
depends_on:
- postgres
- redis
volumes:
postgres_data:
redis_data:
n8n_data:
- The default port for n8n (e.g. 5678) and running examples appear repeatedly in the Docker documentation examples.
N8N_DEFAULT_BINARY_DATA_MODEis connected to a strategy of storing binary data (files) instead of memory, and in Queue modefilesystemThe documentation clearly states that it does not support .- n8n cleans up execution data. Enable pruning by defaultAnd the default values (e.g., 14 days/10,000 cases) are provided in writing.
- Prometheus metrics are default inactiveand it is documented how to enable it with an environment variable.
Why it matters: There are three operational incidents that this template prevents: (1) Credential decryption is not possible due to loss of encryption key, (2) DB disk is depleted due to excessive execution history, (3) External linkage fails due to twisted webhook URL. All can be prevented in “initial settings”.
6) N8N_ENCRYPTION_KEY: A value that must ‘never’ be lost during operation.
n8n encrypts credentials, and the key generated during installation is ~/.n8n(volume/directory mount), and in operation Pin custom keysWe provide documentation on how to do this.
# 예시: 사용자 지정 키를 고정
N8N_ENCRYPTION_KEY=replace-with-strong-secret
Why it matters: If the key changes when you redeploy a container or replace a volume, the stored credentials will become “cannot open even though they exist.” It directly leads to operational accidents.
7) Execution data storage/organization policy
n8n says that as execution data accumulates, the DB may grow and storage may become insufficient, and it is recommended to reduce unnecessary storage and enable pruning.
Additionally, according to the documentation, pruning is a default activation, and pruning is based on default conditions (e.g. 336 hours after completion/>10,000 total).
Examples of policies frequently used in operations:
# 성공 실행은 저장하지 않고, 에러만 남기는 식으로 튜닝 가능
EXECUTIONS_DATA_SAVE_ON_ERROR=all
EXECUTIONS_DATA_SAVE_ON_SUCCESS=none
EXECUTIONS_DATA_SAVE_ON_PROGRESS=false
EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=false
The above variables are provided as examples in the “Execution data” document.
Why it matters: Execution data can be “stacked” faster regardless of whether the workflow is successful or not (scheduling/polling/webhook traffic). Without a cleanup policy, disk exhaustion is only a matter of time.
8) Observation: Prometheus Metrics and Queue Metrics
n8n can activate Prometheus metrics as an environment variable, and also provides a separate option to include queue-related metrics.
N8N_METRICS=true
N8N_METRICS_INCLUDE_QUEUE_METRICS=true
Simple check:
curl -s | head
Why it matters: Logs alone aren’t enough to tell you “what’s going well.” If you can see the queue length/throughput/failure rate, response such as increasing workers will be faster.
9) Backup/Recovery: Save workflow/credentials as ‘files’
n8n provides commands to export/import workflows/credentials/users, etc. through CLI.
In operations, apart from DB backup, it is recommended to export files at least periodically for workflow.
# 워크플로 내보내기 예시(환경에 맞게 경로/옵션 조정)
n8n export:workflow --all --output=/backups/workflows.json
# 크레덴셜 내보내기(민감 정보 주의)
n8n export:credentials --all --output=/backups/credentials.json
Also, the official Docker Compose guide states that n8n data is /home/node/.n8n(volume mounted), and that this can be the SQLite DB/key storage location.
Why it matters: If you “back up only the DB”, the recovery time/permissions/settings may be misaligned and the restoration time may be longer. Workflow export is the fastest recovery card.
10) TLS/Certificate: HTTP-01 requires port 80 (practical tip)
According to Let’s Encrypt documentation, the HTTP-01 challenge is Only on port 80 It states that this can be done and that random ports are not allowed.
In other words, “automatic certificate issuance” to HTTP-01 usually requires 80/443 port path design.
The official n8n Docker Compose example handles TLS with Traefik, and the example configuration states that it is “accessible only via HTTPS”.
Why it matters: When certificate automation is blocked, operations become manual tasks (renewal/expiration), and expiration incidents quickly become obstacles. It is important to design ports/routing early on.
11) Operation checklist (for practical use)
| division | check | standard |
|---|---|---|
| URL/webhook | WEBHOOK_URL fix |
Reverse proxy/external callback normal |
| port | Internal 5678 (standard) | Proxy forwards upstream |
| encryption key | N8N_ENCRYPTION_KEY Fixed/Backup |
Credential recovery possible |
| DB | Postgres conversion | MySQL/MariaDB deprecate |
| cue mode | Check Redis connection variables | Scaling/parallel processing |
| binary | Fashionable tail database |
file system not supported |
| organize | Specifies execution pruning policy | Basic 14 days/10,000 cases, etc. |
| observation | Enable Prometheus metrics | Fault detection/capacity planning |
| backup | CLI export + volume/DB backup | Fast recovery path |
| security | User management premise after v1.0 | Don’t just trust basic auth |
Why it matters: Checklists are intended to prevent “operational failure points,” not “features.” If the above 10 are correct, most self-hosting failures (integration failure/data loss/capacity exhaustion/lack of observation) can be greatly reduced.
Conclusion (Summary)
- It’s safe to get started quickly on a small scale with the official Docker Compose (including TLS), and then move your design to Postgres + (optional) Redis Queue mode as you scale up your operations.
- The most important value in operation is
WEBHOOK_URL,N8N_ENCRYPTION_KEYExecution pruning policy. - Prometheus metrics and CLI export are immediate means of increasing “failure response speed.”
References
- (Docker-Compose, 2026-01-06)[[[[
- (Supported databases and settings, 2026-01-06)[[[[
- (Database environment variables, 2026-01-06)[[[[
- (Endpoints environment variables, 2026-01-06)[[[[
- (Queue mode environment variables, 2026-01-06)[[[[
- (Configuring queue mode, 2026-01-06)[[[[
- (Execution data, 2026-01-06)[[[[
- (Set a custom encryption key, 2026-01-06)[[[[
- (Scaling binary data in n8n, 2026-01-06)[[[[
- (Enable Prometheus metrics, 2026-01-06)[[[[
- (Challenge Types – HTTP-01 on port 80, 2026-01-06)[[[[
