This commit is contained in:
Mike McFetridge
2026-07-20 09:23:17 -04:00
parent c1315882da
commit 72272e4006
3179 changed files with 562960 additions and 14 deletions
+263
View File
@@ -0,0 +1,263 @@
services:
<%- if queue_enabled and not queue_redis_external -%>
redis:
image: redis:8-alpine
volumes:
- redis_data:/data
<%- if network_mode == 'bridge' -%>
networks:
- << network_name >>
<%- else -%>
network_mode: << network_mode >>
<%- endif -%>
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
<%- endif -%>
<< service_name >>:
image: n8nio/n8n:2.20.0
environment:
- N8N_LOG_LEVEL=<< container_loglevel >>
- GENERIC_TIMEZONE=<< container_timezone >>
- TZ=<< container_timezone >>
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
- N8N_RUNNERS_ENABLED=true
<%- if traefik_enabled -%>
- N8N_HOST=<< traefik_host >>.<< traefik_domain >>
<%- if traefik_tls_enabled -%>
- N8N_PROTOCOL=https
- N8N_EDITOR_BASE_URL=https://<< traefik_host >>.<< traefik_domain >>
<%- else -%>
- N8N_PROTOCOL=http
- N8N_EDITOR_BASE_URL=http://<< traefik_host >>.<< traefik_domain >>
<%- endif -%>
<%- endif -%>
- NODE_ENV=production
<%- if database_enabled -%>
<%- if database_type == 'postgres' -%>
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=<< database_host >>
- DB_POSTGRESDB_PORT=<< database_port >>
- DB_POSTGRESDB_DATABASE=<< database_name >>
- DB_POSTGRESDB_USER=<< database_user >>
- DB_POSTGRESDB_PASSWORD_FILE=/run/secrets/<< database_password_secret_name >>
<%- elif database_type == 'mysql' -%>
- DB_TYPE=mysqldb
- DB_MYSQLDB_HOST=<< database_host >>
- DB_MYSQLDB_PORT=<< database_port >>
- DB_MYSQLDB_DATABASE=<< database_name >>
- DB_MYSQLDB_USER=<< database_user >>
- DB_MYSQLDB_PASSWORD_FILE=/run/secrets/<< database_password_secret_name >>
<%- endif -%>
<%- endif -%>
- N8N_ENCRYPTION_KEY_FILE=/run/secrets/<< encryption_key_secret_name >>
<%- if webhook_url -%>
- WEBHOOK_URL=<< webhook_url >>
<%- endif -%>
- N8N_PROXY_HOPS=<< proxy_hops >>
<%- if metrics_enabled -%>
- N8N_METRICS=true
<%- if metrics_detailed -%>
- N8N_METRICS_INCLUDE_WORKFLOW_ID_LABELS=true
- N8N_METRICS_INCLUDE_NODE_TYPE_LABEL=true
- N8N_METRICS_INCLUDE_API_ENDPOINTS=true
- N8N_METRICS_INCLUDE_API_STATUS_CODE_LABELS=true
- N8N_METRICS_INCLUDE_CREDENTIAL_TYPE_LABEL=true
<%- endif -%>
<%- endif -%>
- EXECUTIONS_DATA_SAVE_ON_ERROR=<< execution_save_on_error >>
- EXECUTIONS_DATA_SAVE_ON_SUCCESS=<< execution_save_on_success >>
<%- if queue_enabled -%>
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=<< queue_redis_host >>
- QUEUE_BULL_REDIS_PORT=<< queue_redis_port >>
- QUEUE_HEALTH_CHECK_ACTIVE=true
<%- if metrics_enabled -%>
- N8N_METRICS_INCLUDE_QUEUE_METRICS=true
<%- endif -%>
<%- endif -%>
volumes:
- /etc/localtime:/etc/localtime:ro
- data:/home/node/.n8n
<%- if network_mode == 'bridge' -%>
networks:
<%- if traefik_enabled -%>
- << traefik_network >>
<%- endif -%>
- << network_name >>
<%- else -%>
network_mode: << network_mode >>
<%- endif -%>
<%- if not traefik_enabled and network_mode == 'bridge' -%>
ports:
- target: 5678
published: << ports_http >>
protocol: tcp
mode: host
<%- endif -%>
<%- if queue_enabled and not queue_redis_external -%>
depends_on:
redis:
condition: service_healthy
<%- endif -%>
<%- if traefik_enabled -%>
labels:
- traefik.enable=true
<%- if network_mode == 'bridge' -%>
- traefik.docker.network=<< traefik_network >>
<%- endif -%>
<%- if traefik_webhook_host -%>
- traefik.http.routers.<< service_name >>.rule=Host(`<< traefik_host >>.<< traefik_domain >>`) || Host(`<< traefik_webhook_host >>`)
<%- else -%>
- traefik.http.routers.<< service_name >>.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
<%- endif -%>
<%- if traefik_tls_enabled -%>
- traefik.http.routers.<< service_name >>.entrypoints=<< traefik_tls_entrypoint >>
- traefik.http.routers.<< service_name >>.tls=true
- traefik.http.routers.<< service_name >>.tls.certresolver=<< traefik_tls_certresolver >>
<%- else -%>
- traefik.http.routers.<< service_name >>.entrypoints=<< traefik_entrypoint >>
<%- endif -%>
- traefik.http.services.<< service_name >>-web.loadbalancer.server.port=5678
- traefik.http.routers.<< service_name >>.service=<< service_name >>-web
<%- endif -%>
deploy:
replicas: << swarm_replicas >>
<%- if swarm_placement_host -%>
placement:
constraints:
- node.hostname == << swarm_placement_host >>
<%- endif -%>
<%- if traefik_enabled -%>
labels:
- traefik.enable=true
- traefik.docker.network=<< traefik_network >>
<%- if traefik_webhook_host -%>
- traefik.http.routers.<< service_name >>.rule=Host(`<< traefik_host >>.<< traefik_domain >>`) || Host(`<< traefik_webhook_host >>`)
<%- else -%>
- traefik.http.routers.<< service_name >>.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
<%- endif -%>
<%- if traefik_tls_enabled -%>
- traefik.http.routers.<< service_name >>.entrypoints=<< traefik_tls_entrypoint >>
- traefik.http.routers.<< service_name >>.tls=true
- traefik.http.routers.<< service_name >>.tls.certresolver=<< traefik_tls_certresolver >>
<%- else -%>
- traefik.http.routers.<< service_name >>.entrypoints=<< traefik_entrypoint >>
<%- endif -%>
- traefik.http.services.<< service_name >>-web.loadbalancer.server.port=5678
- traefik.http.routers.<< service_name >>.service=<< service_name >>-web
<%- endif -%>
secrets:
- << encryption_key_secret_name >>
<%- if database_enabled -%>
- << database_password_secret_name >>
<%- endif -%>
<%- if queue_enabled and queue_embedded_worker -%>
<< service_name >>-worker:
image: n8nio/n8n:2.20.0
command: worker
environment:
- N8N_LOG_LEVEL=<< container_loglevel >>
- GENERIC_TIMEZONE=<< container_timezone >>
- TZ=<< container_timezone >>
<%- if database_enabled -%>
<%- if database_type == 'postgres' -%>
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=<< database_host >>
- DB_POSTGRESDB_PORT=<< database_port >>
- DB_POSTGRESDB_DATABASE=<< database_name >>
- DB_POSTGRESDB_USER=<< database_user >>
- DB_POSTGRESDB_PASSWORD_FILE=/run/secrets/<< database_password_secret_name >>
<%- elif database_type == 'mysql' -%>
- DB_TYPE=mysqldb
- DB_MYSQLDB_HOST=<< database_host >>
- DB_MYSQLDB_PORT=<< database_port >>
- DB_MYSQLDB_DATABASE=<< database_name >>
- DB_MYSQLDB_USER=<< database_user >>
- DB_MYSQLDB_PASSWORD_FILE=/run/secrets/<< database_password_secret_name >>
<%- endif -%>
<%- endif -%>
- N8N_ENCRYPTION_KEY_FILE=/run/secrets/<< encryption_key_secret_name >>
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=<< queue_redis_host >>
- QUEUE_BULL_REDIS_PORT=<< queue_redis_port >>
- QUEUE_HEALTH_CHECK_ACTIVE=true
<%- if metrics_enabled -%>
- N8N_METRICS=true
<%- if metrics_detailed -%>
- N8N_METRICS_INCLUDE_WORKFLOW_ID_LABELS=true
- N8N_METRICS_INCLUDE_NODE_TYPE_LABEL=true
<%- endif -%>
<%- endif -%>
volumes:
- /etc/localtime:/etc/localtime:ro
- data:/home/node/.n8n
<%- if network_mode == 'bridge' -%>
networks:
- << network_name >>
<%- else -%>
network_mode: << network_mode >>
<%- endif -%>
<%- if not queue_redis_external -%>
depends_on:
redis:
condition: service_healthy
<%- endif -%>
deploy:
replicas: 1
<%- if swarm_placement_host -%>
placement:
constraints:
- node.hostname == << swarm_placement_host >>
<%- endif -%>
secrets:
- << encryption_key_secret_name >>
<%- if database_enabled -%>
- << database_password_secret_name >>
<%- endif -%>
<%- endif -%>
volumes:
data:
driver: local
<%- if queue_enabled and not queue_redis_external -%>
redis_data:
driver: local
<%- endif -%>
<%- if network_mode == 'bridge' -%>
networks:
<< network_name >>:
<%- if network_external -%>
external: true
<%- else -%>
driver: overlay
attachable: true
<%- endif -%>
<%- if traefik_enabled -%>
<< traefik_network >>:
<%- if traefik_network_external -%>
external: true
<%- else -%>
driver: overlay
attachable: true
<%- endif -%>
<%- endif -%>
<%- endif -%>
secrets:
<< encryption_key_secret_name >>:
external: true
<%- if database_enabled -%>
<< database_password_secret_name >>:
external: true
<%- endif -%>
+562
View File
@@ -0,0 +1,562 @@
{
"slug": "n8n-swarm",
"kind": "swarm",
"metadata": {
"name": "N8N",
"description": "Source-available workflow automation tool that connects apps and services to automate tasks through a visual drag-and-drop node editor.",
"tags": [
"traefik",
"database"
],
"icon": {
"provider": "selfhst",
"id": "n8n"
},
"draft": true,
"version": {
"name": "2.20.0",
"source_dep_name": "n8nio/n8n",
"source_dep_version": "2.20.0"
}
},
"variables": [
{
"title": "General",
"name": "general",
"items": [
{
"name": "service_name",
"type": "str",
"title": "Service Name",
"required": false,
"default": "n8n",
"config": {
"placeholder": "n8n"
}
},
{
"name": "container_timezone",
"type": "str",
"title": "Container Timezone",
"required": false,
"config": {
"placeholder": "Europe/Berlin"
}
},
{
"name": "container_loglevel",
"type": "enum",
"title": "Log Level",
"required": false,
"config": {
"options": [
"debug",
"info",
"warn",
"error"
]
}
},
{
"name": "traefik_tls_entrypoint",
"type": "str",
"title": "Traefik Tls Entrypoint",
"required": false,
"default": "",
"needs": [
"traefik_enabled=true",
"traefik_tls_enabled=true"
],
"config": {
"placeholder": "websecure"
}
},
{
"name": "database_password_secret_name",
"type": "str",
"title": "DB Password Secret",
"required": false,
"default": "",
"needs": [
"database_enabled=true"
],
"config": {
"placeholder": "n8n-db-password"
}
},
{
"name": "encryption_key_secret_name",
"type": "str",
"title": "Encryption Key Secret",
"required": false,
"default": "",
"config": {
"placeholder": "n8n-encryption-key"
}
},
{
"name": "traefik_entrypoint",
"type": "str",
"title": "Traefik Entrypoint",
"required": false,
"default": "",
"needs": [
"traefik_enabled=true",
"traefik_tls_enabled=false"
],
"config": {
"placeholder": "web"
}
}
]
},
{
"title": "Queue Mode",
"name": "queue",
"toggle": "queue_enabled",
"items": [
{
"name": "queue_enabled",
"type": "bool",
"title": "Queue Mode",
"required": false,
"default": false,
"description": "Enable queue mode (requires Redis)"
},
{
"name": "queue_redis_external",
"type": "bool",
"title": "External Redis",
"required": false,
"default": false,
"needs": [
"queue_enabled=true"
]
},
{
"name": "queue_redis_host",
"type": "str",
"title": "Redis host",
"required": false,
"default": "redis",
"needs": [
"queue_enabled=true"
],
"config": {
"placeholder": "redis"
}
},
{
"name": "queue_redis_port",
"type": "int",
"title": "Redis port",
"required": false,
"default": 6379,
"needs": [
"queue_enabled=true"
],
"config": {
"placeholder": "6379"
}
},
{
"name": "queue_embedded_worker",
"type": "bool",
"title": "Embedded Worker",
"required": false,
"default": false,
"description": "Include embedded worker in this deployment",
"needs": [
"queue_enabled=true"
]
}
]
},
{
"title": "Database",
"name": "database",
"toggle": "database_enabled",
"items": [
{
"name": "database_enabled",
"type": "bool",
"title": "External Database",
"required": false,
"default": false
},
{
"name": "database_type",
"type": "enum",
"title": "Database type",
"required": false,
"default": "postgres",
"needs": [
"database_enabled=true"
],
"config": {
"options": [
"postgres",
"mysql"
]
}
},
{
"name": "database_host",
"type": "str",
"title": "Database host",
"required": false,
"default": "postgres",
"needs": [
"database_enabled=true"
],
"config": {
"placeholder": "postgres"
}
},
{
"name": "database_port",
"type": "int",
"title": "Database port",
"required": false,
"default": 5432,
"needs": [
"database_enabled=true"
],
"config": {
"placeholder": "5432"
}
},
{
"name": "database_name",
"type": "str",
"title": "Database name",
"required": false,
"default": "n8n",
"needs": [
"database_enabled=true"
],
"config": {
"placeholder": "n8n"
}
},
{
"name": "database_user",
"type": "str",
"title": "Database username",
"required": false,
"default": "n8n",
"needs": [
"database_enabled=true"
],
"config": {
"placeholder": "n8n"
}
},
{
"name": "database_password",
"type": "secret",
"title": "Database password",
"required": false,
"needs": [
"database_enabled=true"
]
}
]
},
{
"title": "Security",
"name": "security",
"items": [
{
"name": "encryption_key",
"type": "secret",
"title": "Encryption Key",
"required": false,
"config": {
"autogenerated": {
"length": 64
}
}
},
{
"name": "proxy_hops",
"type": "int",
"title": "Proxy Hops",
"required": false,
"default": 1,
"description": "Number of proxy hops (X-Forwarded-For)",
"config": {
"placeholder": "1",
"unit": "hops"
}
}
]
},
{
"title": "Webhooks",
"name": "webhooks",
"items": [
{
"name": "webhook_url",
"type": "str",
"title": "Webhook base URL",
"required": false,
"default": "",
"description": "Base URL used for webhooks.",
"config": {
"placeholder": "https://n8n.home.arpa/"
}
}
]
},
{
"title": "Metrics",
"name": "metrics",
"toggle": "metrics_enabled",
"items": [
{
"name": "metrics_enabled",
"type": "bool",
"title": "Prometheus",
"required": false,
"default": false
},
{
"name": "metrics_detailed",
"type": "bool",
"title": "Detailed Metrics",
"required": false,
"default": false,
"description": "Include detailed metrics (workflows, nodes, API endpoints)",
"needs": [
"metrics_enabled=true"
]
}
]
},
{
"title": "Execution Settings",
"name": "execution",
"items": [
{
"name": "execution_save_on_error",
"type": "enum",
"title": "Save on Error",
"required": false,
"default": "all",
"description": "Save execution data on error",
"config": {
"options": [
"all",
"none"
]
}
},
{
"name": "execution_save_on_success",
"type": "enum",
"title": "Save on Success",
"required": false,
"default": "none",
"description": "Save execution data on success",
"config": {
"options": [
"all",
"none"
]
}
}
]
},
{
"title": "Network",
"name": "network",
"items": [
{
"name": "network_mode",
"type": "enum",
"title": "Network Mode",
"required": false,
"default": "bridge",
"config": {
"options": [
"bridge",
"host"
]
}
},
{
"name": "network_name",
"type": "str",
"title": "Network Name",
"required": false,
"default": "n8n_network",
"config": {
"placeholder": "n8n_network"
},
"needs": [
"network_mode=bridge"
]
},
{
"name": "network_external",
"type": "bool",
"title": "External Network",
"required": false,
"default": false,
"needs": [
"network_mode=bridge"
]
}
]
},
{
"title": "Traefik",
"name": "traefik",
"toggle": "traefik_enabled",
"items": [
{
"name": "traefik_enabled",
"type": "bool",
"title": "Traefik Enabled",
"required": false,
"default": false,
"needs": [
"network_mode=bridge"
]
},
{
"name": "traefik_host",
"type": "str",
"title": "Host",
"required": true,
"config": {
"placeholder": "n8n"
}
},
{
"name": "traefik_webhook_host",
"type": "str",
"title": "Webhook Host",
"required": false,
"default": "",
"description": "Separate hostname for webhooks (optional)",
"needs": [
"traefik_enabled=true"
],
"config": {
"placeholder": "hooks.n8n.home.arpa"
}
},
{
"name": "traefik_network",
"type": "str",
"title": "Traefik network name",
"required": false,
"default": "traefik",
"needs": [
"traefik_enabled=true"
],
"config": {
"placeholder": "traefik"
}
},
{
"name": "traefik_network_external",
"type": "bool",
"title": "External Traefik Network",
"required": false,
"default": true,
"needs": [
"traefik_enabled=true"
]
},
{
"name": "traefik_domain",
"type": "str",
"title": "Domain",
"required": true,
"config": {
"placeholder": "home.arpa"
}
}
]
},
{
"title": "Ports",
"name": "ports",
"items": [
{
"name": "ports_http",
"type": "int",
"title": "External HTTP port",
"required": false,
"default": 5678,
"needs": [
"traefik_enabled=false",
"network_mode=bridge"
],
"config": {
"placeholder": "5678"
}
}
]
},
{
"title": "Swarm",
"name": "swarm",
"items": [
{
"name": "swarm_replicas",
"type": "int",
"title": "Replicas",
"required": false,
"default": 1,
"config": {
"slider": true,
"min": 1,
"max": 20,
"step": 1,
"placeholder": "1",
"unit": "replicas"
}
},
{
"name": "swarm_placement_host",
"type": "str",
"title": "Placement Host",
"required": false,
"default": "",
"description": "Target hostname for placement constraint",
"config": {
"placeholder": "swarm-node-1"
}
}
]
},
{
"title": "Traefik TLS",
"name": "traefik-tls",
"toggle": "traefik_tls_enabled",
"items": [
{
"name": "traefik_tls_certresolver",
"type": "str",
"title": "Cert Resolver",
"required": true,
"default": "cloudflare",
"config": {
"placeholder": "cloudflare"
}
},
{
"name": "traefik_tls_enabled",
"type": "bool",
"title": "TLS",
"required": false,
"default": false
}
]
}
]
}