I cannot run the Code node.
Here is my configuration and architecture: When I set OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS: “false”, the Code node works normally. However, when I set OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS: “true”, the workflow runs fine without a Code node. As soon as a Code node is present, the workflow hangs (spinning/loading indefinitely) at that node.
Please help me identify what might be wrong with my configuration.
# ============================================
# N8N PRODUCTION STACK
# Queue Mode + External Task Runners
# ============================================
# ============================================
# PHẦN 1: TEMPLATES & ANCHORS (Data Driven)
# ============================================
x-common: &common-config
restart: unless-stopped
networks:
- n8n_internal
x-security: &security-standard
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
x-logging: &logging-standard
driver: json-file
options:
max-size: "10m"
max-file: "3"
x-logging-extended: &logging-extended
driver: json-file
options:
max-size: "50m"
max-file: "5"
# Templates tài nguyên theo cấp độ
x-resources-tiny: &resources-tiny
limits:
cpus: "0.3"
memory: 128M
reservations:
cpus: "0.05"
memory: 32M
x-resources-micro: &resources-micro
limits:
cpus: "0.6"
memory: 384M
reservations:
cpus: "0.15"
memory: 96M
x-resources-minimal: &resources-minimal
limits:
cpus: "0.5"
memory: 256M
reservations:
cpus: "0.1"
memory: 64M
x-resources-small: &resources-small
limits:
cpus: "1"
memory: 512M
reservations:
cpus: "0.25"
memory: 128M
x-resources-medium: &resources-medium
limits:
cpus: "2"
memory: 2G
reservations:
cpus: "0.5"
memory: 512M
x-resources-large: &resources-large
limits:
cpus: "4"
memory: 4G
reservations:
cpus: "1"
memory: 1G
# Template biến môi trường n8n cơ bản
x-n8n-base-env: &n8n-base-env
NODE_ENV: production
GENERIC_TIMEZONE: ${GENERIC_TIMEZONE:-Asia/Ho_Chi_Minh}
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
N8N_TRUST_PROXY: "true"
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true"
N8N_BLOCK_ENV_ACCESS_IN_NODE: "true"
N8N_GIT_NODE_DISABLE_BARE_REPOS: "true"
# Template database config
x-db-config: &db-config
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_DATABASE: ${POSTGRES_N8N_DB}
DB_POSTGRESDB_USER: ${POSTGRES_N8N_USER}
DB_POSTGRESDB_PASSWORD: ${POSTGRES_N8N_PASSWORD}
# Template queue config
x-queue-config: &queue-config
EXECUTIONS_MODE: queue
QUEUE_BULL_REDIS_HOST: redis
QUEUE_BULL_REDIS_PASSWORD: ${REDIS_PASSWORD}
# Template runners config
x-runners-config: &runners-config
N8N_RUNNERS_ENABLED: "true"
N8N_RUNNERS_MODE: external
N8N_RUNNERS_AUTH_TOKEN: ${N8N_RUNNERS_AUTH_TOKEN}
# Template PostgreSQL tuning (VPS nhỏ)
x-postgres-tuning: &postgres-tuning
POSTGRES_MAX_CONNECTIONS: "50"
POSTGRES_SHARED_BUFFERS: "256MB"
POSTGRES_EFFECTIVE_CACHE_SIZE: "256MB"
POSTGRES_MAINTENANCE_WORK_MEM: "32MB"
POSTGRES_WORK_MEM: "2MB"
POSTGRES_WAL_BUFFERS: "4MB"
# Template N8N performance tuning
x-n8n-performance: &n8n-performance
N8N_CONCURRENCY_PRODUCTION_LIMIT: "5"
N8N_CACHE_ENABLED: "true"
N8N_CACHE_MAX_SIZE: "10"
EXECUTIONS_DATA_SAVE_ON_ERROR: "all"
EXECUTIONS_DATA_SAVE_ON_SUCCESS: "none"
EXECUTIONS_DATA_SAVE_ON_PROGRESS: "false"
EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS: "false"
EXECUTIONS_DATA_PRUNE: "true"
EXECUTIONS_DATA_MAX_AGE: "1080"
EXECUTIONS_DATA_PRUNE_MAX_COUNT: "50000"
# Template volume n8n
x-n8n-volumes: &n8n-volumes
- n8n_data:/home/node/.n8n
- ${LOCAL_DATA_FOLDER}/data/share:/data/share
# Template healthcheck intervals
x-healthcheck-standard: &healthcheck-standard
interval: 60s
timeout: 10s
retries: 3
x-healthcheck-fast: &healthcheck-fast
interval: 30s
timeout: 10s
retries: 3
# ============================================
# PHẦN 2: SERVICES
# ============================================
services:
# ------------------------------------------
# DATA LAYER
# ------------------------------------------
postgres:
<<: [*common-config, *security-standard]
image: postgres:17-alpine
container_name: ${COMPOSE_PROJECT_NAME:-n8n}_postgres
cap_add:
- CHOWN
- DAC_OVERRIDE
- SETGID
- SETUID
deploy:
resources: *resources-small
volumes:
- postgres_data:/var/lib/postgresql/data
- ./scripts/database:/docker-entrypoint-initdb.d:ro
environment:
<<: *postgres-tuning
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_N8N_DB: ${POSTGRES_N8N_DB}
POSTGRES_N8N_USER: ${POSTGRES_N8N_USER}
POSTGRES_N8N_PASSWORD: ${POSTGRES_N8N_PASSWORD}
POSTGRES_DATA_DB: ${POSTGRES_DATA_DB:-n8n_data}
POSTGRES_DATA_USER: ${POSTGRES_DATA_USER:-data_user}
POSTGRES_DATA_PASSWORD: ${POSTGRES_DATA_PASSWORD}
POSTGRES_INITDB_ARGS: "-E UTF8 --lc-collate=C --lc-ctype=C"
healthcheck:
<<: *healthcheck-fast
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
start_period: 30s
logging: *logging-standard
redis:
<<: [*common-config, *security-standard]
image: redis:7-alpine
container_name: ${COMPOSE_PROJECT_NAME:-n8n}_redis
cap_add:
- SETGID
- SETUID
deploy:
resources: *resources-tiny
volumes:
- redis_data:/data
command: >
redis-server
--requirepass ${REDIS_PASSWORD}
--maxmemory 100mb
--maxmemory-policy allkeys-lru
--save 900 1
--save 300 10
healthcheck:
<<: *healthcheck-fast
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
start_period: 10s
logging: *logging-standard
# ------------------------------------------
# N8N LAYER
# ------------------------------------------
n8n:
<<: [*common-config, *security-standard]
image: docker.n8n.io/n8nio/n8n:latest
container_name: ${COMPOSE_PROJECT_NAME:-n8n}_main
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
user: "1000:1000"
deploy:
resources: *resources-micro
volumes: *n8n-volumes
environment:
<<:
[
*n8n-base-env,
*db-config,
*queue-config,
*runners-config,
*n8n-performance,
]
# Cấu hình riêng cho main instance
N8N_HOST: ${N8N_SUBDOMAIN}.${N8N_DOMAIN_NAME}
N8N_PORT: 5678
N8N_PROTOCOL: https
WEBHOOK_URL: https://${N8N_SUBDOMAIN}.${N8N_DOMAIN_NAME}
# Vai trò: Broker cho task runners
N8N_RUNNERS_BROKER_LISTEN_ADDRESS: 0.0.0.0
OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS: "false"
healthcheck:
<<: *healthcheck-standard
test:
[
"CMD-SHELL",
"wget --no-verbose --tries=1 --spider http://localhost:5678/healthz || exit 1",
]
start_period: 60s
logging: *logging-extended
n8n-worker:
<<: [*common-config, *security-standard]
image: docker.n8n.io/n8nio/n8n:latest
container_name: ${COMPOSE_PROJECT_NAME:-n8n}_worker
command: worker
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
n8n:
condition: service_healthy
user: "1000:1000"
deploy:
replicas: 1
resources: *resources-small
volumes: *n8n-volumes
environment:
<<:
[
*n8n-base-env,
*db-config,
*queue-config,
*runners-config,
*n8n-performance,
]
# Vai trò: Requester - kết nối đến broker
N8N_RUNNERS_TASK_BROKER_URI: http://n8n:5679
logging: *logging-extended
n8n-runners:
<<: [*common-config, *security-standard]
image: n8nio/runners:latest # Image đặc thù
container_name: ${COMPOSE_PROJECT_NAME:-n8n}_runners
depends_on:
n8n:
condition: service_healthy
user: "1000:1000"
deploy:
resources: *resources-micro
environment:
NODE_FUNCTION_ALLOW_EXTERNAL: ${NODE_FUNCTION_ALLOW_EXTERNAL:-*}
# Kết nối đến broker
N8N_RUNNERS_TASK_BROKER_URI: http://n8n:5679
N8N_RUNNERS_AUTH_TOKEN: ${N8N_RUNNERS_AUTH_TOKEN}
N8N_LOG_LEVEL: ${N8N_LOG_LEVEL:-info}
logging: *logging-extended
# ------------------------------------------
# PROXY & TUNNEL LAYER
# ------------------------------------------
caddy:
<<: *common-config
image: caddy:2-alpine
container_name: ${COMPOSE_PROJECT_NAME:-n8n}_caddy
security_opt:
- no-new-privileges:true
cap_add:
- NET_BIND_SERVICE
cap_drop:
- ALL
deploy:
resources: *resources-tiny
volumes:
- caddy_data:/data
- caddy_config:/config
- caddy_logs:/data/logs
- ./Caddyfile:/etc/caddy/Caddyfile:ro
healthcheck:
<<: *healthcheck-standard
test:
[
"CMD",
"wget",
"--no-verbose",
"--tries=1",
"--spider",
"http://localhost/health",
]
start_period: 10s
logging: *logging-standard
labels:
com.${COMPOSE_PROJECT_NAME:-n8n}.service: "caddy"
cloudflared:
<<: [*common-config, *security-standard]
image: cloudflare/cloudflared:latest
container_name: ${COMPOSE_PROJECT_NAME:-n8n}_cloudflared
depends_on:
caddy:
condition: service_healthy
deploy:
resources: *resources-tiny
command: tunnel --no-autoupdate run --token ${TUNNEL_TOKEN}
healthcheck:
<<: *healthcheck-standard
test: ["CMD", "cloudflared", "tunnel", "info", "--log-level", "error"]
start_period: 30s
logging: *logging-standard
labels:
com.${COMPOSE_PROJECT_NAME:-n8n}.service: "cloudflared"
# ------------------------------------------
# BACKUP LAYER
# ------------------------------------------
backup:
<<: *common-config
image: prodrigestivill/postgres-backup-local:17-alpine
container_name: ${COMPOSE_PROJECT_NAME:-n8n}_backup
profiles:
- backup
depends_on:
postgres:
condition: service_healthy
volumes:
- ./backups:/backups
environment:
POSTGRES_HOST: postgres
POSTGRES_DB: ${POSTGRES_N8N_DB}
POSTGRES_USER: ${POSTGRES_N8N_USER}
POSTGRES_PASSWORD: ${POSTGRES_N8N_PASSWORD}
POSTGRES_EXTRA_OPTS: "-Z6 --schema=public --blobs"
SCHEDULE: "@daily"
BACKUP_KEEP_DAYS: "7"
BACKUP_KEEP_WEEKS: "4"
BACKUP_KEEP_MONTHS: "6"
HEALTHCHECK_PORT: "8080"
healthcheck:
<<: *healthcheck-standard
test: ["CMD", "wget", "--spider", "http://localhost:8080"]
start_period: 30s
labels:
com.${COMPOSE_PROJECT_NAME:-n8n}.service: "backup"
# ============================================
# PHẦN 3: VOLUMES & NETWORKS
# ============================================
volumes:
postgres_data:
driver: local
redis_data:
driver: local
n8n_data:
driver: local
caddy_data:
driver: local
caddy_config:
driver: local
caddy_logs:
driver: local
networks:
n8n_internal:
name: ${COMPOSE_PROJECT_NAME:-n8n}_network
driver: bridge