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
+97
View File
@@ -0,0 +1,97 @@
services:
<< service_name >>:
image: ghcr.io/gethomepage/homepage:v1.12.3
environment:
<%- if traefik_enabled %>
- HOMEPAGE_ALLOWED_HOSTS=<< traefik_host >>.<< traefik_domain >>
<%- else %>
- HOMEPAGE_ALLOWED_HOSTS=localhost:<< ports_http >>,127.0.0.1:<< ports_http >>
<%- endif %>
<%- if container_timezone %>
- TZ=<< container_timezone >>
<%- endif %>
<%- if container_loglevel %>
- LOG_LEVEL=<< container_loglevel >>
<%- endif %>
<%- if traefik_enabled %>
networks:
<< traefik_network >>:
<%- endif %>
<%- if not traefik_enabled %>
ports:
- << ports_http >>:3000
<%- endif %>
volumes:
<%- if volume_mode == 'local' %>
- << service_name >>_config:/app/config
- << service_name >>_images:/app/images
- << service_name >>_icons:/app/icons
<%- elif volume_mode == 'mount' %>
- << volume_mount_path >>/<< service_name >>/config:/app/config
- << volume_mount_path >>/<< service_name >>/images:/app/images
- << volume_mount_path >>/<< service_name >>/icons:/app/icons
<%- elif volume_mode == 'nfs' %>
- << service_name >>_config:/app/config
- << service_name >>_images:/app/images
- << service_name >>_icons:/app/icons
<%- endif %>
deploy:
<%- if swarm_placement_mode == 'replicated' %>
replicas: << swarm_replicas >>
<%- if swarm_placement_host %>
placement:
constraints:
- node.hostname == << swarm_placement_host >>
<%- endif %>
<%- else %>
mode: global
<%- endif %>
<%- if traefik_enabled %>
labels:
- traefik.enable=true
- traefik.docker.network=<< traefik_network >>
- traefik.http.services.<< service_name >>-web.loadbalancer.server.port=3000
- traefik.http.routers.<< service_name >>-http.service=<< service_name >>-web
- traefik.http.routers.<< service_name >>-http.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>-http.entrypoints=<< traefik_entrypoint >>
<%- if traefik_tls_enabled %>
- traefik.http.routers.<< service_name >>-https.service=<< service_name >>-web
- traefik.http.routers.<< service_name >>-https.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>-https.entrypoints=<< traefik_tls_entrypoint >>
- traefik.http.routers.<< service_name >>-https.tls=true
- traefik.http.routers.<< service_name >>-https.tls.certresolver=<< traefik_tls_certresolver >>
<%- endif %>
<%- endif %>
<%- if traefik_enabled %>
networks:
<< traefik_network >>:
external: true
<%- endif %>
<%- if volume_mode == 'local' %>
volumes:
<< service_name >>_config:
<< service_name >>_images:
<< service_name >>_icons:
<%- elif volume_mode == 'nfs' %>
volumes:
<< service_name >>_config:
driver: local
driver_opts:
type: nfs
o: addr=<< volume_nfs_server >>,<< volume_nfs_options >>
device: ":<< volume_nfs_path >>/config"
<< service_name >>_images:
driver: local
driver_opts:
type: nfs
o: addr=<< volume_nfs_server >>,<< volume_nfs_options >>
device: ":<< volume_nfs_path >>/images"
<< service_name >>_icons:
driver: local
driver_opts:
type: nfs
o: addr=<< volume_nfs_server >>,<< volume_nfs_options >>
device: ":<< volume_nfs_path >>/icons"
<%- endif %>
+284
View File
@@ -0,0 +1,284 @@
{
"slug": "homepage-swarm",
"kind": "swarm",
"metadata": {
"name": "Homepage",
"description": "Modern, fully static, fast application dashboard with integrations for over 100 services and translations into multiple languages.",
"tags": [
"traefik",
"volume_modes"
],
"icon": {
"provider": "selfhst",
"id": "homepage"
},
"draft": false,
"version": {
"name": "v1.12.3",
"source_dep_name": "ghcr.io/gethomepage/homepage",
"source_dep_version": "v1.12.3"
}
},
"variables": [
{
"title": "General",
"name": "general",
"items": [
{
"name": "service_name",
"type": "str",
"title": "The service name",
"required": true,
"default": "homepage",
"config": {
"placeholder": "homepage"
}
},
{
"name": "container_timezone",
"type": "str",
"title": "The 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": "swarm_placement_mode",
"type": "enum",
"title": "Swarm Placement Mode",
"required": true,
"default": "replicated",
"config": {
"options": [
"replicated",
"global"
]
}
},
{
"name": "swarm_replicas",
"type": "int",
"title": "Swarm Replicas",
"required": false,
"default": 1,
"config": {
"slider": true,
"min": 1,
"max": 10,
"step": 1,
"placeholder": "1",
"unit": "replicas"
},
"needs": [
"swarm_placement_mode=replicated"
]
},
{
"name": "swarm_placement_host",
"type": "str",
"title": "Swarm Placement Host",
"required": false,
"default": "",
"needs": [
"swarm_placement_mode=replicated"
],
"config": {
"placeholder": "swarm-node-1"
}
}
]
},
{
"title": "Ports",
"name": "ports",
"items": [
{
"name": "ports_http",
"type": "int",
"title": "The HTTP port",
"required": true,
"default": 3000,
"needs": [
"traefik_enabled=false"
],
"config": {
"placeholder": "3000"
}
}
]
},
{
"title": "Traefik",
"name": "traefik",
"toggle": "traefik_enabled",
"items": [
{
"name": "traefik_enabled",
"type": "bool",
"title": "Traefik",
"required": false,
"default": false
},
{
"name": "traefik_entrypoint",
"type": "str",
"title": "Entrypoint",
"required": true,
"default": "web",
"config": {
"placeholder": "web"
}
},
{
"name": "traefik_host",
"type": "str",
"title": "Host",
"required": true,
"config": {
"placeholder": "homepage"
}
},
{
"name": "traefik_network",
"type": "str",
"title": "Network",
"required": true,
"default": "traefik",
"config": {
"placeholder": "traefik"
}
},
{
"name": "traefik_domain",
"type": "str",
"title": "Domain",
"required": true,
"config": {
"placeholder": "home.arpa"
}
}
]
},
{
"title": "Traefik TLS",
"name": "traefik-tls",
"toggle": "traefik_tls_enabled",
"items": [
{
"name": "traefik_tls_enabled",
"type": "bool",
"title": "TLS",
"required": false,
"default": false
},
{
"name": "traefik_tls_entrypoint",
"type": "str",
"title": "TLS Entrypoint",
"required": true,
"default": "websecure",
"config": {
"placeholder": "websecure"
}
},
{
"name": "traefik_tls_certresolver",
"type": "str",
"title": "Cert Resolver",
"required": true,
"default": "cloudflare",
"config": {
"placeholder": "cloudflare"
}
}
]
},
{
"title": "Volume",
"name": "volume",
"items": [
{
"name": "volume_mode",
"type": "enum",
"title": "Volume Mode",
"required": true,
"default": "local",
"config": {
"options": [
"local",
"mount",
"nfs"
]
}
},
{
"name": "volume_mount_path",
"type": "str",
"title": "Volume Mount Path",
"required": true,
"default": "/mnt/storage",
"needs": [
"volume_mode=mount"
],
"config": {
"placeholder": "/mnt/storage"
}
},
{
"name": "volume_nfs_options",
"type": "str",
"title": "NFS Options",
"required": false,
"default": "nfsvers=4,soft,timeo=180,intr",
"config": {
"placeholder": "nfsvers=4,soft,timeo=180,intr"
},
"needs": [
"volume_mode=nfs"
]
},
{
"name": "volume_nfs_path",
"type": "str",
"title": "NFS Path",
"required": false,
"default": "",
"needs": [
"volume_mode=nfs"
],
"config": {
"placeholder": "/path/to/export"
}
},
{
"name": "volume_nfs_server",
"type": "str",
"title": "NFS Server",
"required": false,
"default": "",
"needs": [
"volume_mode=nfs"
],
"config": {
"placeholder": "192.0.2.1"
}
}
]
}
]
}
+71
View File
@@ -0,0 +1,71 @@
---
# Homepage configuration
# See https://fontawesome.com/icons for icons options
title: "<< homer_title >>"
subtitle: "<< homer_subtitle >>"
logo: "<< homer_logo >>"
# icon: "fas fa-home" # Optional icon instead of logo
header: true
footer: false # Set to "<Message>" to enable footer with a custom message
# Optional theme customization
theme: default # Options: default, sui
# colors:
# light:
# highlight-primary: "#3367d6"
# highlight-secondary: "#4285f4"
# highlight-hover: "#5a95f5"
# background: "#f5f5f5"
# card-background: "#ffffff"
# text: "#363636"
# text-header: "#ffffff"
# dark:
# highlight-primary: "#3367d6"
# highlight-secondary: "#4285f4"
# highlight-hover: "#5a95f5"
# background: "#131313"
# card-background: "#2b2b2b"
# text: "#eaeaea"
# text-header: "#ffffff"
# Optional message displayed at the top
# message:
# style: "is-dark" # Options: is-dark, is-warning, is-info, is-success, is-danger
# title: "Welcome!"
# icon: "fa fa-grin"
# content: "This is your Homer dashboard. <br /> Add your services below."
# Optional navbar links
# links:
# - name: "GitHub"
# icon: "fab fa-github"
# url: "https://github.com"
# target: "_blank" # optional: open in new tab
# - name: "Documentation"
# icon: "fas fa-book"
# url: "https://github.com/bastienwirtz/homer/blob/main/docs/configuration.md"
# Services
# First level array represents a group.
# Leave only an "items" key if not using groups (group name, icon & tagstyle are optional)
services:
- name: "Applications"
icon: "fas fa-cloud"
# items:
# - name: "Example App"
# logo: "assets/tools/sample.png" # or use "icon: fas fa-server"
# subtitle: "Description of the app"
# tag: "app" # Optional tag
# tagstyle: "is-success" # Optional: is-success, is-warning, is-info, is-danger
# url: "https://example.com"
# target: "_blank" # optional: open in new tab
# - name: "Monitoring"
# icon: "fas fa-chart-line"
# items:
# - name: "Grafana"
# icon: "fas fa-chart-area"
# subtitle: "Metrics & dashboards"
# url: "https://grafana.example.com"
+60
View File
@@ -0,0 +1,60 @@
services:
<< service_name >>:
image: docker.io/b4bz/homer:v26.4.2
<%- if container_timezone %>
environment:
- TZ=<< container_timezone >>
<%- endif %>
<%- if traefik_enabled %>
networks:
<< traefik_network >>:
<%- endif %>
<%- if not traefik_enabled %>
ports:
- target: 8080
published: << ports_http >>
protocol: tcp
mode: host
<%- endif %>
volumes:
- ./assets:/www/assets
deploy:
mode: << swarm_placement_mode >>
<%- if swarm_placement_mode == 'replicated' %>
replicas: << swarm_replicas >>
<%- endif %>
<%- if swarm_placement_host %>
placement:
constraints:
- node.hostname == << swarm_placement_host >>
<%- endif %>
restart_policy:
condition: on-failure
<%- if traefik_enabled %>
labels:
- traefik.enable=true
- traefik.docker.network=<< traefik_network >>
- traefik.http.services.<< service_name >>-web.loadBalancer.server.port=8080
- traefik.http.routers.<< service_name >>-http.service=<< service_name >>-web
- traefik.http.routers.<< service_name >>-http.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>-http.entrypoints=<< traefik_entrypoint >>
<%- if authentik_enabled %>
- traefik.http.routers.<< service_name >>-http.middlewares=<< authentik_traefik_middleware >>
<%- endif %>
<%- if traefik_tls_enabled %>
- traefik.http.routers.<< service_name >>-https.service=<< service_name >>-web
- traefik.http.routers.<< service_name >>-https.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>-https.entrypoints=<< traefik_tls_entrypoint >>
- traefik.http.routers.<< service_name >>-https.tls=true
- traefik.http.routers.<< service_name >>-https.tls.certresolver=<< traefik_tls_certresolver >>
<%- if authentik_enabled %>
- traefik.http.routers.<< service_name >>-https.middlewares=<< authentik_traefik_middleware >>
<%- endif %>
<%- endif %>
<%- endif %>
<%- if traefik_enabled %>
networks:
<< traefik_network >>:
external: true
<%- endif %>
+259
View File
@@ -0,0 +1,259 @@
{
"slug": "homer-swarm",
"kind": "swarm",
"metadata": {
"name": "Homer",
"description": "Simple static homepage for your server to keep your services on hand, configured through a single YAML file.",
"tags": [
"traefik",
"authentik"
],
"icon": {
"provider": "selfhst",
"id": "homer"
},
"draft": false,
"version": {
"name": "v26.4.2",
"source_dep_name": "docker.io/b4bz/homer",
"source_dep_version": "v26.4.2"
}
},
"variables": [
{
"title": "General",
"name": "general",
"items": [
{
"name": "service_name",
"type": "str",
"title": "Service Name",
"required": false,
"default": "homer",
"config": {
"placeholder": "homer"
}
},
{
"name": "container_timezone",
"type": "str",
"title": "Container Timezone",
"required": false,
"config": {
"placeholder": "Europe/Berlin"
}
},
{
"name": "homer_title",
"type": "str",
"title": "Dashboard title",
"required": false,
"default": "Dashboard",
"config": {
"placeholder": "Dashboard"
}
},
{
"name": "homer_subtitle",
"type": "str",
"title": "Dashboard subtitle",
"required": false,
"default": "Dashboard",
"config": {
"placeholder": "Dashboard"
}
},
{
"name": "homer_logo",
"type": "str",
"title": "Logo Path",
"required": false,
"default": "logo-file.png",
"description": "Logo file path (relative to assets/)",
"config": {
"placeholder": "logo-file.png"
}
}
]
},
{
"title": "Ports",
"name": "ports",
"items": [
{
"name": "ports_http",
"type": "int",
"title": "HTTP Port",
"required": false,
"default": 8080,
"config": {
"placeholder": "8080"
}
}
]
},
{
"title": "Traefik",
"name": "traefik",
"toggle": "traefik_enabled",
"items": [
{
"name": "traefik_enabled",
"type": "bool",
"title": "Traefik",
"required": false,
"default": false
},
{
"name": "traefik_entrypoint",
"type": "str",
"title": "Entrypoint",
"required": true,
"default": "web",
"config": {
"placeholder": "web"
}
},
{
"name": "traefik_host",
"type": "str",
"title": "Host",
"required": true,
"config": {
"placeholder": "dashboard"
}
},
{
"name": "traefik_network",
"type": "str",
"title": "Network",
"required": true,
"default": "traefik",
"config": {
"placeholder": "traefik"
}
},
{
"name": "traefik_domain",
"type": "str",
"title": "Domain",
"required": true,
"config": {
"placeholder": "home.arpa"
}
}
]
},
{
"title": "Traefik Tls",
"name": "traefik-tls",
"toggle": "traefik_tls_enabled",
"items": [
{
"name": "traefik_tls_enabled",
"type": "bool",
"title": "TLS",
"required": false,
"default": false
},
{
"name": "traefik_tls_entrypoint",
"type": "str",
"title": "TLS Entrypoint",
"required": true,
"default": "websecure",
"config": {
"placeholder": "websecure"
}
},
{
"name": "traefik_tls_certresolver",
"type": "str",
"title": "Cert Resolver",
"required": true,
"default": "cloudflare",
"config": {
"placeholder": "cloudflare"
}
}
]
},
{
"title": "Docker Swarm",
"name": "swarm",
"items": [
{
"name": "swarm_placement_mode",
"type": "enum",
"title": "Swarm Placement Mode",
"required": true,
"default": "replicated",
"config": {
"options": [
"replicated",
"global"
]
}
},
{
"name": "swarm_replicas",
"type": "int",
"title": "Swarm Replicas",
"required": true,
"default": 1,
"needs": [
"swarm_placement_mode=replicated"
],
"config": {
"slider": true,
"min": 1,
"max": 10,
"step": 1,
"placeholder": "1",
"unit": "replicas"
}
},
{
"name": "swarm_placement_host",
"type": "str",
"title": "Swarm Placement Host",
"required": false,
"default": "",
"needs": [
"swarm_placement_mode=replicated"
],
"config": {
"placeholder": "swarm-node-1"
}
}
]
},
{
"title": "Authentik SSO",
"name": "authentik",
"toggle": "authentik_enabled",
"items": [
{
"name": "authentik_traefik_middleware",
"type": "str",
"title": "Authentik Traefik Middleware",
"required": true,
"default": "middleware@file",
"needs": [
"traefik_enabled=true"
],
"config": {
"placeholder": "middleware@file"
}
},
{
"name": "authentik_enabled",
"type": "bool",
"title": "Authentik SSO",
"required": false,
"default": false
}
]
}
]
}
+127
View File
@@ -0,0 +1,127 @@
---
services:
<< service_name >>:
image: ghcr.io/moghtech/komodo-core:2.1.2
hostname: << container_hostname >>
<%- if network_mode == 'host' %>
network_mode: host
<%- else %>
networks:
<%- if traefik_enabled %>
<< traefik_network >>:
<%- endif %>
<%- if network_mode == 'macvlan' %>
<< network_name >>:
ipv4_address: << network_macvlan_ipv4_address >>
<%- elif network_mode == 'bridge' %>
<< network_name >>:
<%- endif %>
<%- endif %>
<%- if network_mode == 'bridge' and not traefik_enabled %>
ports:
- target: 9120
published: << ports_http >>
protocol: tcp
mode: host
<%- endif %>
<%- if environment_enabled %>
environment:
KOMODO_DATABASE_ADDRESS: "<< environment_database_address >>"
KOMODO_DATABASE_DB_NAME: "<< environment_database_name >>"
<%- if environment_database_username %>
KOMODO_DATABASE_USERNAME: "<< environment_database_username >>"
<%- endif %>
<%- if environment_database_password %>
KOMODO_DATABASE_PASSWORD: "<< environment_database_password >>"
<%- endif %>
<%- if environment_jwt_secret %>
KOMODO_JWT_SECRET: "<< environment_jwt_secret >>"
<%- endif %>
LOG_LEVEL: "<< environment_log_level >>"
<%- endif %>
volumes:
<%- if volume_mode == 'mount' %>
- << volume_mount_path >>/data:/app/data:rw
- << volume_mount_path >>/repos:/app/repos:rw
<%- elif volume_mode == 'local' or volume_mode == 'nfs' %>
- << service_name >>-data:/app/data
- << service_name >>-repos:/app/repos
<%- endif %>
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: on-failure
<%- if resources_enabled %>
resources:
limits:
cpus: '<< resources_cpu_limit >>'
memory: << resources_memory_limit >>
reservations:
cpus: '<< resources_cpu_reservation >>'
memory: << resources_memory_reservation >>
<%- endif %>
<%- if traefik_enabled %>
labels:
- traefik.enable=true
- traefik.docker.network=<< traefik_network >>
- traefik.http.services.<< service_name >>-web.loadBalancer.server.port=9120
- traefik.http.routers.<< service_name >>-http.service=<< service_name >>-web
- traefik.http.routers.<< service_name >>-http.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>-http.entrypoints=<< traefik_entrypoint >>
<%- if traefik_tls_enabled %>
- traefik.http.routers.<< service_name >>-https.service=<< service_name >>-web
- traefik.http.routers.<< service_name >>-https.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>-https.entrypoints=<< traefik_tls_entrypoint >>
- traefik.http.routers.<< service_name >>-https.tls=true
- traefik.http.routers.<< service_name >>-https.tls.certresolver=<< traefik_tls_certresolver >>
<%- endif %>
<%- endif %>
<%- if volume_mode == 'local' %>
volumes:
<< service_name >>-data:
driver: local
<< service_name >>-repos:
driver: local
<%- elif volume_mode == 'nfs' %>
volumes:
<< service_name >>-data:
driver: local
driver_opts:
type: nfs
o: addr=<< volume_nfs_server >>,<< volume_nfs_options >>
device: ":<< volume_nfs_path >>/data"
<< service_name >>-repos:
driver: local
driver_opts:
type: nfs
o: addr=<< volume_nfs_server >>,<< volume_nfs_options >>
device: ":<< volume_nfs_path >>/repos"
<%- endif %>
<%- if network_mode != 'host' %>
networks:
<< network_name >>:
<%- if network_external %>
external: true
<%- else %>
<%- if network_mode == 'macvlan' %>
driver: macvlan
driver_opts:
parent: << network_macvlan_parent_interface >>
ipam:
config:
- subnet: << network_macvlan_subnet >>
gateway: << network_macvlan_gateway >>
name: << network_name >>
<%- else %>
driver: overlay
attachable: true
<%- endif %>
<%- endif %>
<%- if traefik_enabled %>
<< traefik_network >>:
external: true
<%- endif %>
<%- endif %>
+460
View File
@@ -0,0 +1,460 @@
{
"slug": "komodo-swarm",
"kind": "swarm",
"metadata": {
"name": "Komodo",
"description": "Build and deployment automation tool for managing Docker deployments, stacks, and builds across multiple servers. Features real-time container monitoring, batch operations, and a web-based management interface.",
"tags": [
"traefik",
"deployment",
"automation"
],
"icon": {
"provider": "selfhst",
"id": "komodo"
},
"draft": true,
"version": {
"name": "2.1.2",
"source_dep_name": "ghcr.io/moghtech/komodo-core",
"source_dep_version": "2.1.2"
}
},
"variables": [
{
"title": "General",
"name": "general",
"items": [
{
"name": "service_name",
"type": "str",
"title": "Service Name",
"required": false,
"default": "komodo",
"config": {
"placeholder": "komodo"
}
},
{
"name": "container_hostname",
"type": "str",
"title": "Container Hostname",
"required": false,
"default": "komodo",
"config": {
"placeholder": "komodo"
}
},
{
"name": "network_mode",
"type": "enum",
"title": "Network Mode",
"required": false,
"default": "bridge",
"config": {
"options": [
"bridge",
"macvlan",
"host"
]
}
},
{
"name": "network_macvlan_ipv4_address",
"type": "str",
"title": "IPv4 Address",
"required": false,
"default": "",
"needs": [
"network_mode=macvlan"
],
"config": {
"placeholder": "192.0.2.10"
}
},
{
"name": "network_external",
"type": "bool",
"title": "External Network",
"required": false,
"default": false
},
{
"name": "volume_mode",
"type": "enum",
"title": "Volume Mode",
"required": false,
"default": "local",
"config": {
"options": [
"local",
"mount",
"nfs"
]
}
},
{
"name": "volume_nfs_options",
"type": "str",
"title": "Volume Nfs Options",
"required": false,
"default": "",
"needs": [
"volume_mode=nfs"
],
"config": {
"placeholder": "rw,nolock,soft"
}
},
{
"name": "volume_mount_path",
"type": "str",
"title": "Volume Mount Path",
"required": false,
"default": "",
"needs": [
"volume_mode=mount"
],
"config": {
"placeholder": "/path/to/storage"
}
},
{
"name": "volume_nfs_server",
"type": "str",
"title": "Volume Nfs Server",
"required": false,
"default": "",
"needs": [
"volume_mode=nfs"
],
"config": {
"placeholder": "192.0.2.1"
}
},
{
"name": "volume_nfs_path",
"type": "str",
"title": "Volume Nfs Path",
"required": false,
"default": "",
"needs": [
"volume_mode=nfs"
],
"config": {
"placeholder": "/path/to/export"
}
},
{
"name": "network_macvlan_subnet",
"type": "str",
"title": "Subnet",
"required": false,
"default": "",
"needs": [
"network_mode=macvlan"
],
"config": {
"placeholder": "192.0.2.0/24"
}
},
{
"name": "network_name",
"type": "str",
"title": "Network Name",
"required": false,
"default": "komodo_network",
"config": {
"placeholder": "komodo_network"
}
},
{
"name": "network_macvlan_parent_interface",
"type": "str",
"title": "Parent Interface",
"required": false,
"default": "",
"needs": [
"network_mode=macvlan"
],
"config": {
"placeholder": "eth0"
}
},
{
"name": "network_macvlan_gateway",
"type": "str",
"title": "Gateway",
"required": false,
"default": "",
"needs": [
"network_mode=macvlan"
],
"config": {
"placeholder": "192.0.2.1"
}
}
]
},
{
"title": "Traefik",
"name": "traefik",
"toggle": "traefik_enabled",
"items": [
{
"name": "traefik_enabled",
"type": "bool",
"title": "Traefik",
"required": false,
"default": false
},
{
"name": "traefik_entrypoint",
"type": "str",
"title": "Entrypoint",
"required": true,
"default": "web",
"config": {
"placeholder": "web"
}
},
{
"name": "traefik_host",
"type": "str",
"title": "Host",
"required": true,
"config": {
"placeholder": "komodo"
}
},
{
"name": "traefik_network",
"type": "str",
"title": "Network",
"required": true,
"default": "traefik",
"config": {
"placeholder": "traefik"
}
},
{
"name": "traefik_domain",
"type": "str",
"title": "Domain",
"required": true,
"config": {
"placeholder": "home.arpa"
}
}
]
},
{
"title": "Traefik TLS",
"name": "traefik-tls",
"toggle": "traefik_tls_enabled",
"items": [
{
"name": "traefik_tls_enabled",
"type": "bool",
"title": "TLS",
"required": false,
"default": false
},
{
"name": "traefik_tls_entrypoint",
"type": "str",
"title": "TLS Entrypoint",
"required": true,
"default": "websecure",
"config": {
"placeholder": "websecure"
}
},
{
"name": "traefik_tls_certresolver",
"type": "str",
"title": "Cert Resolver",
"required": true,
"default": "cloudflare",
"config": {
"placeholder": "cloudflare"
}
}
]
},
{
"title": "Ports",
"name": "ports",
"items": [
{
"name": "ports_http",
"type": "int",
"title": "HTTP Port",
"required": false,
"default": 9120,
"needs": [
"traefik_enabled=false",
"network_mode=bridge"
],
"config": {
"placeholder": "9120"
}
}
]
},
{
"title": "Resource Limits",
"name": "resources",
"toggle": "resources_enabled",
"items": [
{
"name": "resources_enabled",
"type": "bool",
"title": "Resources Enabled",
"required": false,
"default": false
},
{
"name": "resources_cpu_limit",
"type": "str",
"title": "Resources Cpu Limit",
"required": true,
"default": 1,
"config": {
"placeholder": "1"
}
},
{
"name": "resources_cpu_reservation",
"type": "str",
"title": "Resources Cpu Reservation",
"required": true,
"default": 0.25,
"config": {
"placeholder": "0.25"
}
},
{
"name": "resources_memory_limit",
"type": "str",
"title": "Resources Memory Limit",
"required": true,
"default": "1G",
"config": {
"placeholder": "1G"
}
},
{
"name": "resources_memory_reservation",
"type": "str",
"title": "Resources Memory Reservation",
"required": true,
"default": "512M",
"config": {
"placeholder": "512M"
}
}
]
},
{
"title": "Environment Variables",
"name": "environment",
"toggle": "environment_enabled",
"items": [
{
"name": "environment_enabled",
"type": "bool",
"title": "Environment",
"required": false,
"default": true,
"description": "Configure environment variables (required)"
},
{
"name": "environment_database_address",
"type": "str",
"title": "Database Address",
"required": false,
"default": "mongodb://database:27017",
"description": "Database connection address (MongoDB or FerretDB)",
"needs": [
"environment_enabled=true"
],
"config": {
"placeholder": "mongodb://database:27017"
}
},
{
"name": "environment_database_name",
"type": "str",
"title": "Database name",
"required": false,
"default": "komodo",
"needs": [
"environment_enabled=true"
],
"config": {
"placeholder": "komodo"
}
},
{
"name": "environment_database_username",
"type": "str",
"title": "DB User",
"required": false,
"default": "",
"description": "Database username (optional)",
"needs": [
"environment_enabled=true"
],
"config": {
"placeholder": "komodo"
}
},
{
"name": "environment_database_password",
"type": "secret",
"title": "DB Password",
"required": false,
"default": "",
"description": "Database password (optional)",
"needs": [
"environment_enabled=true"
]
},
{
"name": "environment_jwt_secret",
"type": "secret",
"title": "JWT Secret",
"required": false,
"description": "JWT secret for authentication (auto-generated if empty)",
"needs": [
"environment_enabled=true"
],
"config": {
"autogenerated": {
"length": 64
}
}
},
{
"name": "environment_log_level",
"type": "enum",
"title": "Log level",
"required": false,
"default": "info",
"needs": [
"environment_enabled=true"
],
"config": {
"options": [
"debug",
"info",
"warn",
"error"
]
}
}
]
}
]
}
+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
}
]
}
]
}
+147
View File
@@ -0,0 +1,147 @@
services:
<< service_name >>-app:
image: docker.io/library/nextcloud:33.0.3-apache
environment:
- TZ=<< container_timezone >>
- NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER}
- NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}
- REDIS_HOST=<< service_name >>-redis
<%- if database_type == 'mysql' %>
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_DATABASE=<< database_name >>
- MYSQL_USER=<< database_user >>
- MYSQL_HOST=<< service_name >>-db
<%- elif database_type == 'postgres' %>
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=<< database_name >>
- POSTGRES_USER=<< database_user >>
- POSTGRES_HOST=<< service_name >>-db
<%- endif %>
<%- if traefik_enabled %>
- NEXTCLOUD_TRUSTED_DOMAINS=<< traefik_host >>.<< traefik_domain >>
- OVERWRITEHOST=<< traefik_host >>.<< traefik_domain >>
<%- if traefik_tls_enabled %>
- OVERWRITEPROTOCOL=https
<%- else %>
- OVERWRITEPROTOCOL=http
<%- endif %>
<%- endif %>
<%- if not traefik_enabled %>
ports:
- target: 80
published: << ports_http >>
protocol: tcp
mode: host
<%- endif %>
volumes:
- nextcloud-data:/var/www/html
networks:
- << service_name >>-backend
<%- if traefik_enabled %>
- << traefik_network >>
<%- endif %>
depends_on:
- << service_name >>-db
- << service_name >>-redis
deploy:
replicas: << swarm_replicas >>
<%- if traefik_enabled %>
labels:
- traefik.enable=true
- traefik.docker.network=<< traefik_network >>
- traefik.http.services.<< service_name >>-web.loadbalancer.server.port=80
- traefik.http.routers.<< service_name >>-web-http.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>-web-http.entrypoints=<< traefik_entrypoint >>
- traefik.http.routers.<< service_name >>-web-http.service=<< service_name >>-web
<%- if traefik_tls_enabled %>
- traefik.http.routers.<< service_name >>-web-https.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>-web-https.entrypoints=<< traefik_tls_entrypoint >>
- traefik.http.routers.<< service_name >>-web-https.tls=true
- traefik.http.routers.<< service_name >>-web-https.tls.certresolver=<< traefik_tls_certresolver >>
- traefik.http.routers.<< service_name >>-web-https.service=<< service_name >>-web
<%- endif %>
<%- endif %>
<< service_name >>-cron:
image: docker.io/library/nextcloud:33.0.3-apache
entrypoint: /cron.sh
environment:
- TZ=<< container_timezone >>
- REDIS_HOST=<< service_name >>-redis
<%- if database_type == 'mysql' %>
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_DATABASE=<< database_name >>
- MYSQL_USER=<< database_user >>
- MYSQL_HOST=<< service_name >>-db
<%- elif database_type == 'postgres' %>
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=<< database_name >>
- POSTGRES_USER=<< database_user >>
- POSTGRES_HOST=<< service_name >>-db
<%- endif %>
volumes:
- nextcloud-data:/var/www/html
networks:
- << service_name >>-backend
depends_on:
- << service_name >>-app
deploy:
replicas: 1
<< service_name >>-redis:
image: docker.io/library/redis:8-alpine
command: redis-server --appendonly yes
volumes:
- nextcloud-redis:/data
networks:
- << service_name >>-backend
deploy:
replicas: 1
<< service_name >>-db:
<%- if database_type == 'mysql' %>
# See compatibility matrix for Nextcloud 31
# https://docs.nextcloud.com/server/31/admin_manual/installation/system_requirements.html
image: docker.io/library/mariadb:10.11.16
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
environment:
- TZ=<< container_timezone >>
- MYSQL_RANDOM_ROOT_PASSWORD=true
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_DATABASE=<< database_name >>
- MYSQL_USER=<< database_user >>
volumes:
- nextcloud-db:/var/lib/mysql
networks:
- << service_name >>-backend
<%- elif database_type == 'postgres' %>
image: docker.io/library/postgres:17.9
environment:
- TZ=<< container_timezone >>
- POSTGRES_USER=<< database_user >>
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=<< database_name >>
volumes:
- nextcloud-db:/var/lib/postgresql/data
networks:
- << service_name >>-backend
<%- endif %>
deploy:
replicas: 1
volumes:
nextcloud-data:
driver: local
nextcloud-db:
driver: local
nextcloud-redis:
driver: local
networks:
<< service_name >>-backend:
driver: overlay
attachable: true
<%- if traefik_enabled %>
<< traefik_network >>:
external: true
<%- endif %>
+239
View File
@@ -0,0 +1,239 @@
{
"slug": "nextcloud-swarm",
"kind": "swarm",
"metadata": {
"name": "Nextcloud",
"description": "Self-hosted file sync and share platform, similar to Dropbox, with built-in collaboration tools, calendar, contacts, and extensible app ecosystem.",
"tags": [
"traefik"
],
"icon": {
"provider": "selfhst",
"id": "nextcloud"
},
"draft": false,
"version": {
"name": "33.0.3-apache",
"source_dep_name": "docker.io/library/nextcloud",
"source_dep_version": "33.0.3-apache"
}
},
"variables": [
{
"title": "Database",
"name": "database",
"items": [
{
"name": "database_type",
"type": "enum",
"title": "Database Type",
"required": false,
"default": "postgres",
"config": {
"options": [
"postgres",
"mysql"
]
}
},
{
"name": "database_name",
"type": "str",
"title": "Database Name",
"required": true
},
{
"name": "database_user",
"type": "str",
"title": "Database User",
"required": true
},
{
"name": "database_password",
"type": "secret",
"title": "Database Password",
"required": true
}
]
},
{
"title": "General",
"name": "general",
"items": [
{
"name": "service_name",
"type": "str",
"title": "Service Name",
"required": false,
"default": "nextcloud",
"config": {
"placeholder": "nextcloud"
}
},
{
"name": "container_timezone",
"type": "str",
"title": "Container Timezone",
"required": true,
"config": {
"placeholder": "Europe/Berlin"
}
},
{
"name": "traefik_entrypoint",
"type": "str",
"title": "Traefik Entrypoint",
"required": false,
"default": "",
"needs": [
"traefik_enabled=true"
],
"config": {
"placeholder": "web"
}
},
{
"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": "swarm_replicas",
"type": "int",
"title": "Swarm Replicas",
"required": false,
"default": 1,
"config": {
"slider": true,
"min": 1,
"max": 10,
"step": 1,
"placeholder": "1",
"unit": "replicas"
}
}
]
},
{
"title": "Ports",
"name": "ports",
"items": [
{
"name": "ports_http",
"type": "int",
"title": "HTTP Port",
"required": false,
"default": 80,
"config": {
"placeholder": "80"
},
"needs": [
"traefik_enabled=false"
]
}
]
},
{
"title": "Nextcloud",
"name": "nextcloud",
"items": [
{
"name": "admin_user",
"type": "str",
"title": "Nextcloud admin username",
"required": false,
"default": "admin",
"config": {
"placeholder": "admin"
}
},
{
"name": "admin_password",
"type": "secret",
"title": "Nextcloud admin password",
"required": false,
"config": {
"autogenerated": {
"length": 32
}
}
}
]
},
{
"title": "Traefik",
"name": "traefik",
"toggle": "traefik_enabled",
"items": [
{
"name": "traefik_host",
"type": "str",
"title": "Host",
"required": true,
"config": {
"placeholder": "nextcloud"
}
},
{
"name": "traefik_network",
"type": "str",
"title": "Network",
"required": true,
"default": "traefik",
"config": {
"placeholder": "traefik"
}
},
{
"name": "traefik_domain",
"type": "str",
"title": "Domain",
"required": true,
"config": {
"placeholder": "home.arpa"
}
},
{
"name": "traefik_enabled",
"type": "bool",
"title": "Traefik",
"required": false,
"default": false
}
]
},
{
"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
}
]
}
]
}
+53
View File
@@ -0,0 +1,53 @@
services:
<< service_name >>:
image: docker.io/library/nginx:1.30.0-alpine
<%- if traefik_enabled %>
networks:
<< traefik_network >>:
<%- endif %>
<%- if not traefik_enabled %>
ports:
- target: 80
published: << ports_http >>
protocol: tcp
mode: host
- target: 443
published: << ports_https >>
protocol: tcp
mode: host
<%- endif %>
# volumes:
# - ./config/default.conf:/etc/nginx/conf.d/default.conf:ro
# - ./data:/usr/share/nginx/html:ro
deploy:
mode: << swarm_placement_mode >>
<%- if swarm_placement_mode == 'replicated' %>
replicas: << swarm_replicas >>
<%- endif %>
<%- if swarm_placement_host %>
placement:
constraints:
- node.hostname == << swarm_placement_host >>
<%- endif %>
<%- if traefik_enabled %>
labels:
- traefik.enable=true
- traefik.docker.network=<< traefik_network >>
- traefik.http.services.<< service_name >>-web.loadbalancer.server.port=80
- traefik.http.routers.<< service_name >>-web-http.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>-web-http.entrypoints=<< traefik_entrypoint >>
- traefik.http.routers.<< service_name >>-web-http.service=<< service_name >>-web
<%- if traefik_tls_enabled %>
- traefik.http.routers.<< service_name >>-web-https.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>-web-https.entrypoints=<< traefik_tls_entrypoint >>
- traefik.http.routers.<< service_name >>-web-https.tls=true
- traefik.http.routers.<< service_name >>-web-https.tls.certresolver=<< traefik_tls_certresolver >>
- traefik.http.routers.<< service_name >>-web-https.service=<< service_name >>-web
<%- endif %>
<%- endif %>
<%- if traefik_enabled %>
networks:
<< traefik_network >>:
external: true
<%- endif %>
+9
View File
@@ -0,0 +1,9 @@
server {
listen 80;
server_name _;
location / {
root /usr/share/nginx/html;
index index.html;
access_log on;
}
}
+1
View File
@@ -0,0 +1 @@
this is a test website...
+208
View File
@@ -0,0 +1,208 @@
{
"slug": "nginx-swarm",
"kind": "swarm",
"metadata": {
"name": "Nginx",
"description": "High-performance web server, reverse proxy, and load balancer known for stability, low resource consumption, and simple configuration.",
"tags": [
"traefik"
],
"icon": {
"provider": "simple-icons",
"id": "nginx"
},
"draft": false,
"version": {
"name": "1.30.0-alpine",
"source_dep_name": "docker.io/library/nginx",
"source_dep_version": "1.30.0-alpine"
}
},
"variables": [
{
"title": "General",
"name": "general",
"items": [
{
"name": "service_name",
"type": "str",
"title": "Service Name",
"required": false,
"default": "nginx",
"config": {
"placeholder": "nginx"
}
},
{
"name": "traefik_tls_entrypoint",
"type": "str",
"title": "Traefik Tls Entrypoint",
"required": false,
"default": "",
"config": {
"placeholder": "websecure"
},
"needs": [
"traefik_enabled=true",
"traefik_tls_enabled=true"
]
},
{
"name": "traefik_tls_certresolver",
"type": "str",
"title": "Cert Resolver",
"required": false,
"default": "",
"config": {
"placeholder": "cloudflare"
},
"needs": [
"traefik_enabled=true",
"traefik_tls_enabled=true"
]
},
{
"name": "swarm_replicas",
"type": "int",
"title": "Replicas",
"required": false,
"default": 1,
"description": "Number of replicas for Swarm mode",
"config": {
"slider": true,
"min": 1,
"max": 20,
"step": 1,
"placeholder": "1",
"unit": "replicas"
}
},
{
"name": "swarm_placement_host",
"type": "str",
"title": "The placement host",
"required": false,
"default": "",
"config": {
"placeholder": "swarm-node-1"
}
},
{
"name": "swarm_placement_mode",
"type": "enum",
"title": "The placement mode",
"required": false,
"default": "replicated",
"description": "Placement mode for the service.",
"config": {
"options": [
"replicated",
"global"
]
}
}
]
},
{
"title": "Ports",
"name": "ports",
"items": [
{
"name": "ports_http",
"type": "int",
"title": "HTTP Port",
"required": false,
"default": 8080,
"config": {
"placeholder": "8080"
},
"needs": [
"traefik_enabled=false"
]
},
{
"name": "ports_https",
"type": "int",
"title": "HTTPS Port",
"required": false,
"default": 8443,
"config": {
"placeholder": "8443"
},
"needs": [
"traefik_enabled=false"
]
}
]
},
{
"title": "Traefik",
"name": "traefik",
"toggle": "traefik_enabled",
"items": [
{
"name": "traefik_enabled",
"type": "bool",
"title": "Traefik Enabled",
"required": false,
"default": false
},
{
"name": "traefik_network",
"type": "str",
"title": "Network",
"required": false,
"default": "traefik",
"config": {
"placeholder": "traefik"
}
},
{
"name": "traefik_host",
"type": "str",
"title": "Host",
"required": true,
"config": {
"placeholder": "nginx"
}
},
{
"name": "traefik_domain",
"type": "str",
"title": "Domain",
"required": true,
"config": {
"placeholder": "home.arpa"
}
},
{
"name": "traefik_entrypoint",
"type": "str",
"title": "Traefik Entrypoint",
"required": false,
"default": "web",
"config": {
"placeholder": "web"
},
"needs": [
"traefik_enabled=true"
]
}
]
},
{
"title": "Traefik TLS",
"toggle": "traefik_tls_enabled",
"name": "traefik-tls",
"items": [
{
"name": "traefik_tls_enabled",
"type": "bool",
"title": "TLS",
"required": false,
"default": false
}
]
}
]
}
@@ -0,0 +1 @@
<< webpassword >>
+157
View File
@@ -0,0 +1,157 @@
---
services:
<< service_name >>:
image: docker.io/pihole/pihole:2026.04.1
<%- if container_hostname %>
hostname: << container_hostname >>
<%- endif %>
environment:
- TZ=<< container_timezone >>
- PIHOLE_UID=<< user_uid >>
- PIHOLE_GID=<< user_gid >>
- WEBPASSWORD_FILE=<< service_name >>_webpassword
<%- if network_mode == 'bridge' %>
- FTLCONF_dns_listeningMode=all
<%- endif %>
<%- if network_mode == 'host' %>
network_mode: host
<%- elif network_mode == 'bridge' or network_mode == 'macvlan' or traefik_enabled %>
networks:
<%- if traefik_enabled %>
<< traefik_network >>:
<%- endif %>
<%- if network_mode == 'macvlan' %>
<< network_name >>:
ipv4_address: << network_macvlan_ipv4_address >>
<%- elif network_mode == 'bridge' %>
<< network_name >>:
<%- endif %>
<%- endif %>
<%- if network_mode == '' or network_mode == 'bridge' or traefik_enabled %>
ports:
<%- if not traefik_enabled %>
- target: 80
published: << ports_http >>
protocol: tcp
mode: host
- target: 443
published: << ports_https >>
protocol: tcp
mode: host
<%- endif %>
- target: 53
published: << ports_dns >>
protocol: tcp
mode: host
- target: 53
published: << ports_dns >>
protocol: udp
mode: host
- target: 123
published: << ports_ntp >>
protocol: udp
mode: host
<%- endif %>
volumes:
<%- if volume_mode == 'mount' %>
- << volume_mount_path >>/dnsmasq:/etc/dnsmasq.d:rw
- << volume_mount_path >>/pihole:/etc/pihole:rw
<%- else %>
- << service_name >>-dnsmasq:/etc/dnsmasq.d
- << service_name >>-pihole:/etc/pihole
<%- endif %>
cap_add:
- NET_ADMIN
- SYS_TIME
secrets:
- << service_name >>_webpassword
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.hostname == << swarm_placement_host >>
restart_policy:
condition: on-failure
<%- if traefik_enabled %>
labels:
- traefik.enable=true
- traefik.docker.network=<< traefik_network >>
- traefik.http.services.<< service_name >>-web.loadBalancer.server.port=80
- traefik.http.routers.<< service_name >>-http.service=<< service_name >>-web
- traefik.http.routers.<< service_name >>-http.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>-http.entrypoints=<< traefik_entrypoint >>
<%- if traefik_tls_enabled %>
- traefik.http.routers.<< service_name >>-https.service=<< service_name >>-web
- traefik.http.routers.<< service_name >>-https.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>-https.entrypoints=<< traefik_tls_entrypoint >>
- traefik.http.routers.<< service_name >>-https.tls=true
- traefik.http.routers.<< service_name >>-https.tls.certresolver=<< traefik_tls_certresolver >>
<%- endif %>
<%- endif %>
secrets:
<< service_name >>_webpassword:
file: ./.env.secret.webpassword
<%- if volume_mode == 'local' %>
volumes:
<< service_name >>-dnsmasq:
driver: local
<< service_name >>-pihole:
driver: local
<%- elif volume_mode == 'nfs' %>
volumes:
<< service_name >>-dnsmasq:
driver: local
driver_opts:
type: nfs
o: addr=<< volume_nfs_server >>,<< volume_nfs_options >>
device: ":<< volume_nfs_path >>/dnsmasq"
<< service_name >>-pihole:
driver: local
driver_opts:
type: nfs
o: addr=<< volume_nfs_server >>,<< volume_nfs_options >>
device: ":<< volume_nfs_path >>/pihole"
<%- endif %>
<%- if network_mode == 'bridge' or network_mode == 'macvlan' or traefik_enabled %>
networks:
<%- if network_mode == 'bridge' or network_mode == 'macvlan' %>
<< network_name >>:
<%- if network_external %>
external: true
<%- else %>
<%- if network_mode == 'macvlan' %>
driver: macvlan
driver_opts:
parent: << network_macvlan_parent_interface >>
ipam:
config:
- subnet: << network_macvlan_subnet >>
gateway: << network_macvlan_gateway >>
name: << network_name >>
<%- else %>
driver: overlay
attachable: true
<%- endif %>
<%- endif %>
<%- endif %>
<%- if traefik_enabled %>
<< traefik_network >>:
external: true
<%- endif %>
<%- endif %>
+407
View File
@@ -0,0 +1,407 @@
{
"slug": "pihole-swarm",
"kind": "swarm",
"metadata": {
"name": "Pihole",
"description": "Network-wide DNS-based ad and tracker blocker that acts as a DNS sinkhole. Filters content at the DNS level for all devices on your network.",
"tags": [
"traefik",
"network",
"volume"
],
"icon": {
"provider": "selfhst",
"id": "pi-hole"
},
"draft": false,
"version": {
"name": "2026.04.1",
"source_dep_name": "docker.io/pihole/pihole",
"source_dep_version": "2026.04.1"
}
},
"variables": [
{
"title": "General",
"name": "general",
"items": [
{
"name": "service_name",
"type": "str",
"title": "Service Name",
"required": false,
"default": "pihole",
"config": {
"placeholder": "pihole"
}
},
{
"name": "container_hostname",
"type": "str",
"title": "Container Hostname",
"required": false
},
{
"name": "container_timezone",
"type": "str",
"title": "Container Timezone",
"required": true,
"config": {
"placeholder": "Europe/Berlin"
}
},
{
"name": "user_uid",
"type": "int",
"title": "User Uid",
"required": false,
"default": 1000,
"config": {
"placeholder": "1000"
}
},
{
"name": "user_gid",
"type": "int",
"title": "User Gid",
"required": false,
"default": 1000,
"config": {
"placeholder": "1000"
}
}
]
},
{
"title": "Admin Settings",
"name": "admin-settings",
"items": [
{
"name": "webpassword",
"type": "secret",
"title": "Admin Password",
"required": false,
"config": {
"autogenerated": {
"length": 32
}
}
}
]
},
{
"title": "Ports",
"name": "ports",
"items": [
{
"name": "ports_dns",
"type": "int",
"title": "DNS Port",
"required": true,
"default": 53,
"config": {
"placeholder": "53"
}
},
{
"name": "ports_http",
"type": "int",
"title": "HTTP Port",
"required": false,
"default": 80,
"config": {
"placeholder": "80"
}
},
{
"name": "ports_https",
"type": "int",
"title": "HTTPS Port",
"required": false,
"default": 443,
"config": {
"placeholder": "443"
}
},
{
"name": "ports_ntp",
"type": "int",
"title": "External NTP port",
"required": true,
"default": 123,
"config": {
"placeholder": "123"
}
}
]
},
{
"title": "Traefik",
"name": "traefik",
"toggle": "traefik_enabled",
"items": [
{
"name": "traefik_host",
"type": "str",
"title": "Host",
"required": true,
"config": {
"placeholder": "pihole"
}
},
{
"name": "traefik_network",
"type": "str",
"title": "Network",
"required": true,
"default": "traefik",
"config": {
"placeholder": "traefik"
}
},
{
"name": "traefik_domain",
"type": "str",
"title": "Domain",
"required": true,
"config": {
"placeholder": "home.arpa"
}
},
{
"name": "traefik_enabled",
"type": "bool",
"title": "Traefik",
"required": false,
"default": false
},
{
"name": "traefik_entrypoint",
"type": "str",
"title": "Traefik Entrypoint",
"required": false,
"default": "web",
"config": {
"placeholder": "web"
},
"needs": [
"traefik_enabled=true"
]
}
]
},
{
"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
},
{
"name": "traefik_tls_entrypoint",
"type": "str",
"title": "Traefik Tls Entrypoint",
"required": false,
"default": "websecure",
"config": {
"placeholder": "websecure"
},
"needs": [
"traefik_tls_enabled=true"
]
}
]
},
{
"title": "Network",
"name": "network",
"items": [
{
"name": "network_mode",
"type": "enum",
"title": "Network Mode",
"required": false,
"default": "bridge",
"config": {
"options": [
"bridge",
"host",
"macvlan"
]
}
},
{
"name": "network_name",
"type": "str",
"title": "Network Name",
"required": false,
"default": "pihole_network",
"config": {
"placeholder": "pihole_network"
}
},
{
"name": "network_macvlan_ipv4_address",
"type": "str",
"title": "IPv4 Address",
"required": true,
"default": "IP_ADDRESS",
"needs": [
"network_mode=macvlan"
],
"config": {
"placeholder": "IP_ADDRESS"
}
},
{
"name": "network_macvlan_parent_interface",
"type": "str",
"title": "Parent Interface",
"required": true,
"default": "eth0",
"needs": [
"network_mode=macvlan"
],
"config": {
"placeholder": "eth0"
}
},
{
"name": "network_macvlan_subnet",
"type": "str",
"title": "Subnet",
"required": true,
"default": "IP_RANGE",
"needs": [
"network_mode=macvlan"
],
"config": {
"placeholder": "IP_RANGE"
}
},
{
"name": "network_macvlan_gateway",
"type": "str",
"title": "Gateway",
"required": true,
"default": "GATEWAY",
"needs": [
"network_mode=macvlan"
],
"config": {
"placeholder": "GATEWAY"
}
},
{
"name": "network_external",
"type": "bool",
"title": "External Network",
"required": false,
"default": false
}
]
},
{
"title": "Docker Swarm",
"name": "swarm",
"items": [
{
"name": "swarm_placement_host",
"type": "str",
"title": "Swarm Placement Host",
"required": true,
"config": {
"placeholder": "swarm-node-1"
}
}
]
},
{
"title": "Volume",
"name": "volume",
"items": [
{
"name": "volume_mode",
"type": "enum",
"title": "Volume Mode",
"required": true,
"default": "local",
"config": {
"options": [
"local",
"mount",
"nfs"
]
}
},
{
"name": "volume_mount_path",
"type": "str",
"title": "Volume Mount Path",
"required": true,
"default": "/data",
"needs": [
"volume_mode=mount"
],
"config": {
"placeholder": "/data"
}
},
{
"name": "volume_nfs_server",
"type": "str",
"title": "Volume Nfs Server",
"required": true,
"default": "NFS_SERVER",
"needs": [
"volume_mode=nfs"
],
"config": {
"placeholder": "NFS_SERVER"
}
},
{
"name": "volume_nfs_path",
"type": "str",
"title": "Volume Nfs Path",
"required": true,
"default": "/export",
"needs": [
"volume_mode=nfs"
],
"config": {
"placeholder": "/export"
}
},
{
"name": "volume_nfs_options",
"type": "str",
"title": "Volume Nfs Options",
"required": true,
"default": "rw,nolock,soft",
"needs": [
"volume_mode=nfs"
],
"config": {
"placeholder": "rw,nolock,soft"
}
}
]
}
]
}
+68
View File
@@ -0,0 +1,68 @@
services:
<< service_name >>:
image: docker.io/portainer/portainer-ce:2.41.0-alpine
environment:
- TZ=<< container_timezone >>
<%- if traefik_enabled %>
networks:
<< traefik_network >>:
<%- endif %>
ports:
<%- if not traefik_enabled %>
- "<< ports_http >>:9000"
- "<< ports_https >>:9443"
<%- endif %>
- "<< ports_edge >>:8000"
volumes:
- /run/docker.sock:/var/run/docker.sock
<%- if volume_mode == 'mount' %>
- << volume_mount_path >>/data:/data
<%- else %>
- << service_name >>_data:/data
<%- endif %>
deploy:
mode: replicated
replicas: 1
<%- if swarm_placement_host %>
placement:
constraints:
- node.hostname == << swarm_placement_host >>
<%- endif %>
restart_policy:
condition: on-failure
<%- if traefik_enabled %>
labels:
- traefik.enable=true
- traefik.docker.network=<< traefik_network >>
- traefik.http.services.<< service_name >>_web.loadBalancer.server.port=9000
- traefik.http.routers.<< service_name >>_http.service=<< service_name >>_web
- traefik.http.routers.<< service_name >>_http.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>_http.entrypoints=<< traefik_entrypoint >>
<%- if traefik_tls_enabled %>
- traefik.http.routers.<< service_name >>_https.service=<< service_name >>_web
- traefik.http.routers.<< service_name >>_https.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>_https.entrypoints=<< traefik_tls_entrypoint >>
- traefik.http.routers.<< service_name >>_https.tls=true
- traefik.http.routers.<< service_name >>_https.tls.certresolver=<< traefik_tls_certresolver >>
<%- endif %>
<%- endif %>
<%- if volume_mode == 'local' %>
volumes:
<< service_name >>_data:
driver: local
<%- elif volume_mode == 'nfs' %>
volumes:
<< service_name >>_data:
driver: local
driver_opts:
type: nfs
o: addr=<< volume_nfs_server >>,nfsvers=4,<< volume_nfs_options >>
device: ":<< volume_nfs_path >>/data"
<%- endif %>
<%- if traefik_enabled %>
networks:
<< traefik_network >>:
external: true
<%- endif %>
+266
View File
@@ -0,0 +1,266 @@
{
"slug": "portainer",
"kind": "swarm",
"metadata": {
"name": "Portainer",
"description": "Web-based management UI for Docker and Kubernetes environments. Simplifies container, image, network, and volume management through an intuitive interface.",
"tags": [
"traefik",
"volumes"
],
"icon": {
"provider": "selfhst",
"id": "portainer"
},
"draft": false,
"version": {
"name": "2.41.0-alpine",
"source_dep_name": "docker.io/portainer/portainer-ce",
"source_dep_version": "2.41.0-alpine"
}
},
"variables": [
{
"title": "General",
"name": "general",
"items": [
{
"name": "service_name",
"type": "str",
"title": "Service Name",
"required": false,
"default": "portainer",
"config": {
"placeholder": "portainer"
}
},
{
"name": "container_timezone",
"type": "str",
"title": "Container Timezone",
"required": true,
"config": {
"placeholder": "Europe/Berlin"
}
},
{
"name": "swarm_placement_host",
"type": "str",
"title": "Placement Host",
"required": false,
"default": "",
"description": "Target hostname for placement constraint",
"config": {
"placeholder": "swarm-node-1"
}
}
]
},
{
"title": "Ports",
"name": "ports",
"items": [
{
"name": "ports_http",
"type": "int",
"title": "HTTP Port",
"required": false,
"default": 9000,
"config": {
"placeholder": "9000"
},
"needs": [
"traefik_enabled=false"
]
},
{
"name": "ports_https",
"type": "int",
"title": "HTTPS Port",
"required": false,
"default": 9443,
"config": {
"placeholder": "9443"
},
"needs": [
"traefik_enabled=false"
]
},
{
"name": "ports_edge",
"type": "int",
"title": "Edge Port",
"required": true,
"default": 8000,
"config": {
"placeholder": "8000"
}
}
]
},
{
"title": "Traefik",
"name": "traefik",
"toggle": "traefik_enabled",
"items": [
{
"name": "traefik_host",
"type": "str",
"title": "Host",
"required": true,
"config": {
"placeholder": "portainer"
}
},
{
"name": "traefik_network",
"type": "str",
"title": "Network",
"required": true,
"default": "traefik",
"config": {
"placeholder": "traefik"
}
},
{
"name": "traefik_domain",
"type": "str",
"title": "Domain",
"required": true,
"config": {
"placeholder": "home.arpa"
}
},
{
"name": "traefik_enabled",
"type": "bool",
"title": "Traefik",
"required": false,
"default": false
},
{
"name": "traefik_entrypoint",
"type": "str",
"title": "Traefik Entrypoint",
"required": false,
"default": "web",
"config": {
"placeholder": "web"
},
"needs": [
"traefik_enabled=true"
]
}
]
},
{
"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
},
{
"name": "traefik_tls_entrypoint",
"type": "str",
"title": "Traefik Tls Entrypoint",
"required": false,
"default": "websecure",
"config": {
"placeholder": "websecure"
},
"needs": [
"traefik_tls_enabled=true"
]
}
]
},
{
"title": "Volume",
"name": "volume",
"items": [
{
"name": "volume_mode",
"type": "enum",
"title": "Volume Mode",
"required": true,
"default": "local",
"config": {
"options": [
"local",
"mount",
"nfs"
]
}
},
{
"name": "volume_mount_path",
"type": "str",
"title": "Volume Mount Path",
"required": true,
"default": "/data",
"needs": [
"volume_mode=mount"
],
"config": {
"placeholder": "/data"
}
},
{
"name": "volume_nfs_server",
"type": "str",
"title": "Volume Nfs Server",
"required": true,
"default": "NFS_SERVER",
"needs": [
"volume_mode=nfs"
],
"config": {
"placeholder": "NFS_SERVER"
}
},
{
"name": "volume_nfs_path",
"type": "str",
"title": "Volume Nfs Path",
"required": true,
"default": "/export",
"needs": [
"volume_mode=nfs"
],
"config": {
"placeholder": "/export"
}
},
{
"name": "volume_nfs_options",
"type": "str",
"title": "Volume Nfs Options",
"required": true,
"default": "rw,nolock,soft",
"needs": [
"volume_mode=nfs"
],
"config": {
"placeholder": "rw,nolock,soft"
}
}
]
}
]
}
+71
View File
@@ -0,0 +1,71 @@
services:
<< service_name >>:
image: docker.io/library/postgres:18.3
hostname: << container_hostname >>
environment:
- POSTGRES_INITDB_ARGS=<< postgres_initdb_args >>
<%- if postgres_host_auth_method %>
- POSTGRES_HOST_AUTH_METHOD=<< postgres_host_auth_method >>
<%- endif %>
- POSTGRES_USER=<< database_user >>
- POSTGRES_PASSWORD=<< database_password >>
- POSTGRES_DB=<< database_name >>
- TZ=<< container_timezone >>
<%- if network_mode == 'bridge' or network_mode == '' %>
networks:
<< network_name >>:
<%- endif %>
<%- if network_mode == 'bridge' or network_mode == '' %>
ports:
- target: 5432
published: << ports_postgres >>
protocol: tcp
mode: host
<%- endif %>
volumes:
<%- if volume_mode == 'mount' %>
- << volume_mount_path >>:/var/lib/postgresql:rw
<%- else %>
- << service_name >>-data:/var/lib/postgresql
<%- endif %>
healthcheck:
test: ["CMD-SHELL", "pg_isready -U << database_user >>"]
start_period: 30s
interval: 10s
timeout: 10s
retries: 5
deploy:
mode: replicated
replicas: 1
<%- if swarm_placement_host %>
placement:
constraints:
- node.hostname == << swarm_placement_host >>
<%- endif %>
restart_policy:
condition: on-failure
<%- if volume_mode == 'local' %>
volumes:
<< service_name >>-data:
driver: local
<%- elif volume_mode == 'nfs' %>
volumes:
<< service_name >>-data:
driver: local
driver_opts:
type: nfs
o: addr=<< volume_nfs_server >>,<< volume_nfs_options >>
device: ":<< volume_nfs_path >>"
<%- endif %>
<%- if network_mode == 'bridge' or network_mode == '' %>
networks:
<< network_name >>:
<%- if network_external %>
external: true
<%- else %>
driver: overlay
attachable: true
<%- endif %>
<%- endif %>
+238
View File
@@ -0,0 +1,238 @@
{
"slug": "postgres-swarm",
"kind": "swarm",
"metadata": {
"name": "PostgreSQL",
"description": "Powerful open-source object-relational database system with over 35 years of active development, known for reliability, feature robustness, and performance.",
"tags": [],
"icon": {
"provider": "selfhst",
"id": "postgresql"
},
"draft": false,
"version": {
"name": "18.3",
"source_dep_name": "docker.io/library/postgres",
"source_dep_version": "18.3"
}
},
"variables": [
{
"title": "General",
"name": "general",
"items": [
{
"name": "service_name",
"type": "str",
"title": "Service Name",
"required": false,
"default": "postgres",
"config": {
"placeholder": "postgres"
}
},
{
"name": "container_hostname",
"type": "str",
"title": "Container Hostname",
"required": true
},
{
"name": "container_timezone",
"type": "str",
"title": "Container Timezone",
"required": true,
"config": {
"placeholder": "Europe/Berlin"
}
},
{
"name": "postgres_initdb_args",
"type": "str",
"title": "Postgres Initdb Args",
"required": true,
"default": "",
"config": {
"placeholder": "--data-checksums"
}
},
{
"name": "postgres_host_auth_method",
"type": "str",
"title": "Host Auth",
"required": false,
"default": "",
"config": {
"placeholder": "scram-sha-256"
}
},
{
"name": "swarm_placement_host",
"type": "str",
"title": "The placement host",
"required": false,
"default": "",
"config": {
"placeholder": "swarm-node-1"
}
}
]
},
{
"title": "Ports",
"name": "ports",
"items": [
{
"name": "ports_postgres",
"type": "int",
"title": "PostgreSQL port",
"required": false,
"default": 5432,
"config": {
"placeholder": "5432"
},
"needs": [
"network_mode=bridge"
]
}
]
},
{
"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": "postgres_network",
"config": {
"placeholder": "postgres_network"
}
},
{
"name": "network_external",
"type": "bool",
"title": "External Network",
"required": false,
"default": false
}
]
},
{
"title": "Volume",
"name": "volume",
"items": [
{
"name": "volume_mode",
"type": "enum",
"title": "Volume Mode",
"required": false,
"default": "local",
"config": {
"options": [
"local",
"mount",
"nfs"
]
}
},
{
"name": "volume_mount_path",
"type": "str",
"title": "Bind Path",
"required": false,
"default": "/var/lib/postgresql/data",
"config": {
"placeholder": "/var/lib/postgresql/data"
},
"needs": [
"volume_mode=mount"
]
},
{
"name": "volume_nfs_server",
"type": "str",
"title": "NFS Server",
"required": false,
"default": "",
"needs": [
"volume_mode=nfs"
],
"config": {
"placeholder": "192.0.2.1"
}
},
{
"name": "volume_nfs_path",
"type": "str",
"title": "NFS Path",
"required": false,
"default": "",
"needs": [
"volume_mode=nfs"
],
"config": {
"placeholder": "/path/to/export"
}
},
{
"name": "volume_nfs_options",
"type": "str",
"title": "NFS Options",
"required": false,
"default": "rw",
"config": {
"placeholder": "rw"
},
"needs": [
"volume_mode=nfs"
]
}
]
},
{
"title": "Database",
"name": "database",
"items": [
{
"name": "database_name",
"type": "str",
"title": "Database Name",
"required": true
},
{
"name": "database_user",
"type": "str",
"title": "Database User",
"required": true
},
{
"name": "database_password",
"type": "secret",
"title": "Database password",
"required": true,
"config": {
"autogenerated": {
"length": 32
}
}
}
]
}
]
}
+64
View File
@@ -0,0 +1,64 @@
---
services:
<< service_name >>:
image: ghcr.io/mend/renovate-ce:14.5.0-full
hostname: << container_hostname >>
<%- if traefik_enabled %>
networks:
<< traefik_network >>:
<%- endif %>
<%- if not traefik_enabled %>
ports:
- "<< ports_http >>:8080"
<%- endif %>
environment:
- MEND_RNV_ACCEPT_TOS=y
- MEND_RNV_LICENSE_KEY=<< license_key >>
- MEND_RNV_PLATFORM=<< renovate_platform >>
- MEND_RNV_ENDPOINT=<< renovate_endpoint >>
- MEND_RNV_GITLAB_PAT=<< git_token >>
- MEND_RNV_WEBHOOK_SECRET=<< webhook_secret >>
- MEND_RNV_SERVER_PORT=8080
- RENOVATE_AUTODISCOVER=<< renovate_autodiscover | lower >>
<%- if container_timezone %>
- TZ=<< container_timezone >>
<%- endif %>
<%- if container_loglevel %>
- LOG_LEVEL=<< container_loglevel >>
<%- endif %>
deploy:
mode: << swarm_placement_mode >>
<%- if swarm_placement_mode == 'replicated' %>
replicas: << swarm_replicas >>
<%- endif %>
<%- if swarm_placement_host %>
placement:
constraints:
- node.hostname == << swarm_placement_host >>
<%- endif %>
<%- if traefik_enabled %>
labels:
- traefik.enable=true
- traefik.docker.network=<< traefik_network >>
- traefik.http.services.<< service_name >>.loadbalancer.server.port=8080
- traefik.http.routers.<< service_name >>-http.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>-http.entrypoints=<< traefik_entrypoint >>
<%- if traefik_tls_enabled %>
- traefik.http.routers.<< service_name >>-https.rule=Host(`<< traefik_host >>.<< traefik_domain >>`)
- traefik.http.routers.<< service_name >>-https.entrypoints=<< traefik_tls_entrypoint >>
- traefik.http.routers.<< service_name >>-https.tls=true
- traefik.http.routers.<< service_name >>-https.tls.certresolver=<< traefik_tls_certresolver >>
<%- endif %>
<%- endif %>
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
<%- if traefik_enabled %>
networks:
<< traefik_network >>:
external: true
<%- endif %>
+301
View File
@@ -0,0 +1,301 @@
{
"slug": "renovate-swarm",
"kind": "swarm",
"metadata": {
"name": "Renovate",
"description": "Self-hosted Mend Renovate CE worker for GitLab that scans repositories and opens dependency update merge requests.",
"tags": [
"traefik"
],
"icon": {
"provider": "selfhst",
"id": "mend-renovate"
},
"draft": false,
"version": {
"name": "14.5.0-full",
"source_dep_name": "ghcr.io/mend/renovate-ce",
"source_dep_version": "14.5.0-full"
}
},
"variables": [
{
"title": "General",
"name": "general",
"items": [
{
"name": "service_name",
"type": "str",
"title": "Service Name",
"required": false,
"default": "renovate",
"config": {
"placeholder": "renovate"
}
},
{
"name": "container_hostname",
"type": "str",
"title": "Container Hostname",
"required": false,
"default": "renovate",
"config": {
"placeholder": "renovate"
}
},
{
"name": "container_timezone",
"type": "str",
"title": "Container Timezone",
"required": false,
"default": "UTC",
"config": {
"placeholder": "UTC"
}
},
{
"name": "container_loglevel",
"type": "enum",
"title": "Log Level",
"required": false,
"config": {
"options": [
"debug",
"info",
"warn",
"error"
]
}
},
{
"name": "traefik_tls_certresolver",
"type": "str",
"title": "Cert Resolver",
"required": false,
"default": "",
"config": {
"placeholder": "cloudflare"
},
"needs": [
"traefik_enabled=true",
"traefik_tls_enabled=true"
]
},
{
"name": "traefik_tls_entrypoint",
"type": "str",
"title": "Traefik Tls Entrypoint",
"required": false,
"default": "",
"config": {
"placeholder": "websecure"
},
"needs": [
"traefik_enabled=true",
"traefik_tls_enabled=true"
]
}
]
},
{
"title": "Renovate Settings",
"name": "renovate-settings",
"items": [
{
"name": "renovate_platform",
"type": "enum",
"title": "Git Platform",
"required": false,
"default": "gitlab",
"config": {
"options": [
"gitlab"
]
}
},
{
"name": "renovate_endpoint",
"type": "str",
"title": "Git Endpoint",
"required": false,
"default": "https://gitlab.com/api/v4/",
"config": {
"placeholder": "https://gitlab.com/api/v4/"
}
},
{
"name": "renovate_autodiscover",
"type": "bool",
"title": "Auto-discover repositories",
"required": false,
"default": false
}
]
},
{
"title": "Authentication",
"name": "authentication",
"items": [
{
"name": "git_token",
"type": "secret",
"title": "Git Token",
"required": true
},
{
"name": "license_key",
"type": "secret",
"title": "License Key",
"required": true,
"description": "Mend Renovate CE License Key"
},
{
"name": "webhook_secret",
"type": "secret",
"title": "Webhook Secret",
"required": false,
"default": "renovate",
"description": "Webhook secret for platform integration",
"config": {
"placeholder": "renovate"
}
}
]
},
{
"title": "Ports",
"name": "ports",
"items": [
{
"name": "ports_http",
"type": "int",
"title": "HTTP Port",
"required": false,
"default": 8080,
"config": {
"placeholder": "8080"
}
}
]
},
{
"title": "Traefik",
"name": "traefik",
"toggle": "traefik_enabled",
"items": [
{
"name": "traefik_enabled",
"type": "bool",
"title": "Traefik Enabled",
"required": false,
"default": false
},
{
"name": "traefik_network",
"type": "str",
"title": "Network",
"required": false,
"default": "traefik",
"config": {
"placeholder": "traefik"
}
},
{
"name": "traefik_host",
"type": "str",
"title": "Host",
"required": true,
"config": {
"placeholder": "renovate"
}
},
{
"name": "traefik_domain",
"type": "str",
"title": "Domain",
"required": true,
"config": {
"placeholder": "home.arpa"
}
},
{
"name": "traefik_entrypoint",
"type": "str",
"title": "Traefik Entrypoint",
"required": false,
"default": "web",
"config": {
"placeholder": "web"
},
"needs": [
"traefik_enabled=true"
]
}
]
},
{
"title": "Traefik TLS",
"toggle": "traefik_tls_enabled",
"name": "traefik-tls",
"items": [
{
"name": "traefik_tls_enabled",
"type": "bool",
"title": "TLS",
"required": false,
"default": false
}
]
},
{
"title": "Swarm",
"name": "swarm",
"items": [
{
"name": "swarm_placement_mode",
"type": "enum",
"title": "Swarm Placement Mode",
"required": false,
"default": "replicated",
"config": {
"options": [
"replicated",
"global"
]
}
},
{
"name": "swarm_replicas",
"type": "int",
"title": "Swarm Replicas",
"required": false,
"default": 1,
"needs": [
"swarm_placement_mode=replicated"
],
"config": {
"slider": true,
"min": 1,
"max": 10,
"step": 1,
"placeholder": "1",
"unit": "replicas"
}
},
{
"name": "swarm_placement_host",
"type": "str",
"title": "Swarm Placement Host",
"required": false,
"default": "",
"needs": [
"swarm_placement_mode=replicated"
],
"config": {
"placeholder": "swarm-node-1"
}
}
]
}
]
}
@@ -0,0 +1,5 @@
<%- if traefik_tls_certresolver == 'route53' %>
[default]
aws_access_key_id = << traefik_tls_acme_token >>
aws_secret_access_key = << traefik_tls_acme_secret_key >>
<%- endif %>
@@ -0,0 +1 @@
<%- if traefik_tls_acme_consumer_key %><< traefik_tls_acme_consumer_key >><%- endif %>
+1
View File
@@ -0,0 +1 @@
<%- if traefik_tls_acme_token and traefik_tls_certresolver != 'route53' %><< traefik_tls_acme_token >><%- endif %>
@@ -0,0 +1 @@
<%- if traefik_tls_acme_secret_key and traefik_tls_certresolver != 'route53' %><< traefik_tls_acme_secret_key >><%- endif %>
+189
View File
@@ -0,0 +1,189 @@
---
services:
<< service_name >>:
image: docker.io/library/traefik:v3.6.15
command:
- "--global.checkNewVersion=false"
- "--global.sendAnonymousUsage=false"
- "--log.level=<< container_loglevel >>"
- "--ping=true"
- "--ping.entryPoint=ping"
<%- if accesslog_enabled %>
- "--accesslog=true"
<%- endif %>
<%- if dashboard_enabled %>
- "--api.dashboard=true"
- "--api.insecure=true"
<%- endif %>
<%- if prometheus_enabled %>
- "--metrics.prometheus=true"
- "--metrics.prometheus.entryPoint=metrics"
- "--metrics.prometheus.addRoutersLabels=true"
<%- endif %>
- "--entrypoints.ping.address=:8082"
<%- if prometheus_enabled %>
- "--entrypoints.metrics.address=:9090"
<%- endif %>
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.encodedCharacters.allowEncodedSlash=true"
<%- if traefik_tls_enabled and traefik_tls_redirect %>
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
<%- endif %>
<%- if traefik_tls_enabled %>
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.encodedCharacters.allowEncodedSlash=true"
- "--certificatesresolvers.<< traefik_tls_certresolver >>.acme.email=<< traefik_tls_acme_email >>"
- "--certificatesresolvers.<< traefik_tls_certresolver >>.acme.caServer=https://acme-v02.api.letsencrypt.org/directory"
- "--certificatesresolvers.<< traefik_tls_certresolver >>.acme.storage=/var/traefik/certs/acme.json"
- "--certificatesresolvers.<< traefik_tls_certresolver >>.acme.dnsChallenge.provider=<< traefik_tls_certresolver >>"
- "--certificatesresolvers.<< traefik_tls_certresolver >>.acme.dnsChallenge.resolvers=1.1.1.1:53,8.8.8.8:53"
- "--tls.options.default.minVersion=<< traefik_tls_min_version >>"
<%- endif %>
<%- if traefik_tls_secure_ciphers %>
- "--tls.options.default.cipherSuites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"
<%- endif %>
<%- if traefik_tls_skipverify %>
- "--serversTransport.insecureSkipVerify=true"
<%- endif %>
- "--providers.swarm.endpoint=unix:///var/run/docker.sock"
- "--providers.swarm.exposedByDefault=false"
- "--providers.swarm.network=<< traefik_network >>"
ports:
- target: 80
published: << ports_http >>
protocol: tcp
mode: << ports_publish_mode >>
- target: 443
published: << ports_https >>
protocol: tcp
mode: << ports_publish_mode >>
<%- if dashboard_enabled %>
- target: 8080
published: << ports_dashboard >>
protocol: tcp
mode: << ports_publish_mode >>
<%- endif %>
<%- if prometheus_enabled %>
- target: 9090
published: << ports_metrics >>
protocol: tcp
mode: << ports_publish_mode >>
<%- endif %>
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
<%- if volume_mode == 'mount' %>
- << volume_mount_path >>:/var/traefik/certs:rw
<%- elif volume_mode == 'local' or volume_mode == 'nfs' %>
- << service_name >>_certs:/var/traefik/certs:rw
<%- endif %>
environment:
- TZ=<< container_timezone >>
<%- if traefik_tls_enabled %>
<%- if traefik_tls_certresolver == 'cloudflare' %>
- CF_DNS_API_TOKEN_FILE=/run/secrets/<< service_name >>_token
<%- elif traefik_tls_certresolver == 'porkbun' %>
- PORKBUN_API_KEY_FILE=/run/secrets/<< service_name >>_token
- PORKBUN_SECRET_API_KEY_FILE=/run/secrets/<< service_name >>_token_key
<%- elif traefik_tls_certresolver == 'route53' %>
- AWS_SHARED_CREDENTIALS_FILE=/run/secrets/<< service_name >>_aws_credentials
- AWS_REGION=<< traefik_tls_acme_region >>
<%- elif traefik_tls_certresolver == 'digitalocean' %>
- DO_AUTH_TOKEN_FILE=/run/secrets/<< service_name >>_token
<%- elif traefik_tls_certresolver == 'godaddy' %>
- GODADDY_API_KEY_FILE=/run/secrets/<< service_name >>_token
- GODADDY_API_SECRET_FILE=/run/secrets/<< service_name >>_token_key
<%- elif traefik_tls_certresolver == 'azure' %>
- AZURE_CLIENT_ID_FILE=/run/secrets/<< service_name >>_token
- AZURE_CLIENT_SECRET_FILE=/run/secrets/<< service_name >>_token_key
- AZURE_TENANT_ID=<< traefik_tls_acme_tenant_id >>
- AZURE_SUBSCRIPTION_ID=<< traefik_tls_acme_subscription_id >>
- AZURE_RESOURCE_GROUP=<< traefik_tls_acme_resource_group >>
<%- elif traefik_tls_certresolver == 'namecheap' %>
- NAMECHEAP_API_KEY_FILE=/run/secrets/<< service_name >>_token
- NAMECHEAP_API_USER=<< traefik_tls_acme_username >>
<%- elif traefik_tls_certresolver == 'ovh' %>
- OVH_ENDPOINT=<< traefik_tls_acme_endpoint >>
- OVH_APPLICATION_KEY_FILE=/run/secrets/<< service_name >>_token
- OVH_APPLICATION_SECRET_FILE=/run/secrets/<< service_name >>_token_key
- OVH_CONSUMER_KEY_FILE=/run/secrets/<< service_name >>_consumer_key
<%- endif %>
<%- endif %>
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:8082/ping"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
networks:
- << traefik_network >>
<%- if traefik_tls_enabled %>
secrets:
<%- if traefik_tls_certresolver == 'route53' %>
- << service_name >>_aws_credentials
<%- else %>
- << service_name >>_token
<%- if traefik_tls_certresolver == 'azure' or traefik_tls_certresolver == 'godaddy' or traefik_tls_certresolver == 'ovh' or traefik_tls_certresolver == 'porkbun' %>
- << service_name >>_token_key
<%- endif %>
<%- if traefik_tls_certresolver == 'ovh' %>
- << service_name >>_consumer_key
<%- endif %>
<%- endif %>
<%- endif %>
deploy:
mode: << swarm_placement_mode >>
<%- if swarm_placement_mode == 'replicated' %>
replicas: << swarm_replicas >>
<%- endif %>
placement:
constraints:
- node.role == manager
<%- if swarm_placement_host %>
- node.hostname == << swarm_placement_host >>
<%- endif %>
restart_policy:
condition: any
<%- if traefik_tls_enabled %>
secrets:
<%- if traefik_tls_certresolver == 'route53' %>
<< service_name >>_aws_credentials:
file: ./.env.secret.aws_credentials
<%- else %>
<< service_name >>_token:
file: ./.env.secret.token
<%- if traefik_tls_certresolver == 'azure' or traefik_tls_certresolver == 'godaddy' or traefik_tls_certresolver == 'ovh' or traefik_tls_certresolver == 'porkbun' %>
<< service_name >>_token_key:
file: ./.env.secret.token_key
<%- endif %>
<%- if traefik_tls_certresolver == 'ovh' %>
<< service_name >>_consumer_key:
file: ./.env.secret.consumer_key
<%- endif %>
<%- endif %>
<%- endif %>
networks:
<< traefik_network >>:
<%- if traefik_network_external %>
external: true
<%- else %>
driver: overlay
attachable: true
name: << traefik_network >>
<%- endif %>
<%- if volume_mode == 'local' %>
volumes:
<< service_name >>_certs:
driver: local
<%- elif volume_mode == 'nfs' %>
volumes:
<< service_name >>_certs:
driver: local
driver_opts:
type: nfs
o: addr=<< volume_nfs_server >>,nfsvers=4,<< volume_nfs_options >>
device: ":<< volume_nfs_path >>"
<%- endif %>
+513
View File
@@ -0,0 +1,513 @@
{
"slug": "traefik-swarm",
"kind": "swarm",
"metadata": {
"name": "Traefik",
"description": "Swarm-only Traefik reverse proxy and load balancer with Docker Swarm service discovery, optional Let's Encrypt DNS challenge TLS, dashboard, and metrics support. For Traefik-managed ACME certificates, run a single replica; Traefik OSS ACME storage is not safe for active-active writes from multiple instances. References: Traefik Swarm provider https://doc.traefik.io/traefik/providers/swarm/ and Traefik ACME storage notes https://doc.traefik.io/traefik/https/acme/.",
"tags": [
"reverse-proxy",
"traefik"
],
"icon": {
"provider": "devicon",
"id": "traefikproxy",
"color": "sky"
},
"draft": false,
"version": {
"name": "v3.6.15",
"source_dep_name": "docker.io/library/traefik",
"source_dep_version": "v3.6.15"
}
},
"variables": [
{
"name": "general",
"title": "General",
"items": [
{
"name": "service_name",
"type": "str",
"title": "Service Name",
"required": false,
"default": "traefik",
"config": {
"placeholder": "traefik"
}
},
{
"name": "container_timezone",
"type": "str",
"title": "Container Timezone",
"required": true,
"default": "UTC",
"config": {
"placeholder": "UTC"
}
},
{
"name": "container_loglevel",
"type": "enum",
"title": "Log Level",
"required": false,
"default": "info",
"description": "Traefik log level.",
"config": {
"options": [
"debug",
"info",
"warn",
"error"
]
}
}
]
},
{
"name": "ports",
"title": "Ports",
"items": [
{
"name": "ports_http",
"type": "int",
"title": "HTTP Port",
"required": true,
"default": 80,
"description": "Published port for the web entrypoint.",
"config": {
"placeholder": "80"
}
},
{
"name": "ports_https",
"type": "int",
"title": "HTTPS Port",
"required": true,
"default": 443,
"description": "Published port for the websecure entrypoint.",
"config": {
"placeholder": "443"
}
},
{
"name": "ports_dashboard",
"type": "int",
"title": "Dashboard Port",
"required": true,
"default": 8080,
"description": "Published port for the insecure dashboard/API.",
"config": {
"placeholder": "8080"
},
"needs": [
"dashboard_enabled=true"
]
},
{
"name": "ports_metrics",
"type": "int",
"title": "Metrics Port",
"required": true,
"default": 9090,
"description": "Published port for Prometheus metrics.",
"config": {
"placeholder": "9090"
},
"needs": [
"prometheus_enabled=true"
]
},
{
"name": "ports_publish_mode",
"type": "enum",
"title": "Publish Mode",
"required": true,
"default": "host",
"description": "Swarm port publishing mode. Host mode is recommended for edge proxies.",
"config": {
"options": [
"host",
"ingress"
]
}
}
]
},
{
"name": "traefik",
"title": "Traefik",
"items": [
{
"name": "traefik_network",
"type": "str",
"title": "Network",
"required": true,
"default": "traefik",
"description": "Overlay network Traefik uses to reach routed Swarm services.",
"config": {
"placeholder": "traefik"
}
},
{
"name": "traefik_network_external",
"type": "bool",
"title": "External Network",
"required": false,
"default": false
},
{
"name": "accesslog_enabled",
"type": "bool",
"title": "Access Log",
"required": false,
"default": false
},
{
"name": "dashboard_enabled",
"type": "bool",
"title": "Dashboard",
"required": false,
"default": false,
"description": "Enable the insecure Traefik dashboard/API. Do not expose this in production."
},
{
"name": "prometheus_enabled",
"type": "bool",
"title": "Prometheus",
"required": false,
"default": false
}
]
},
{
"name": "traefik-tls",
"title": "Traefik TLS",
"toggle": "traefik_tls_enabled",
"items": [
{
"name": "traefik_tls_enabled",
"type": "bool",
"title": "TLS",
"required": false,
"default": false
},
{
"name": "traefik_tls_certresolver",
"type": "enum",
"title": "DNS Provider",
"required": true,
"default": "cloudflare",
"description": "ACME DNS challenge provider.",
"config": {
"options": [
"cloudflare",
"porkbun",
"godaddy",
"digitalocean",
"route53",
"azure",
"namecheap",
"ovh"
]
},
"needs": [
"traefik_tls_enabled=true"
]
},
{
"name": "traefik_tls_acme_email",
"type": "str",
"title": "ACME Email",
"required": true,
"description": "Email address used for ACME registration.",
"config": {
"placeholder": "admin@example.com"
},
"needs": [
"traefik_tls_enabled=true"
]
},
{
"name": "traefik_tls_acme_token",
"type": "secret",
"title": "API Token / ID",
"required": true,
"description": "DNS provider API token or access/client ID. Stored as a Swarm secret.",
"needs": [
"traefik_tls_enabled=true",
"traefik_tls_certresolver=azure,cloudflare,digitalocean,godaddy,namecheap,ovh,porkbun,route53"
]
},
{
"name": "traefik_tls_acme_secret_key",
"type": "secret",
"title": "Secret Key",
"required": true,
"description": "DNS provider secret key. Stored as a Swarm secret.",
"needs": [
"traefik_tls_enabled=true",
"traefik_tls_certresolver=azure,godaddy,ovh,porkbun,route53"
]
},
{
"name": "traefik_tls_acme_consumer_key",
"type": "secret",
"title": "Consumer Key",
"required": true,
"description": "OVH consumer key. Stored as a Swarm secret.",
"needs": [
"traefik_tls_enabled=true",
"traefik_tls_certresolver=ovh"
]
},
{
"name": "traefik_tls_acme_username",
"type": "str",
"title": "Username",
"required": true,
"description": "Namecheap API username.",
"config": {
"placeholder": "namecheap-user"
},
"needs": [
"traefik_tls_enabled=true",
"traefik_tls_certresolver=namecheap"
]
},
{
"name": "traefik_tls_acme_region",
"type": "str",
"title": "AWS Region",
"required": true,
"default": "us-east-1",
"description": "AWS region for Route53.",
"config": {
"placeholder": "us-east-1"
},
"needs": [
"traefik_tls_enabled=true",
"traefik_tls_certresolver=route53"
]
},
{
"name": "traefik_tls_acme_endpoint",
"type": "str",
"title": "OVH Endpoint",
"required": false,
"default": "ovh-eu",
"description": "OVH API endpoint.",
"config": {
"placeholder": "ovh-eu"
},
"needs": [
"traefik_tls_enabled=true",
"traefik_tls_certresolver=ovh"
]
},
{
"name": "traefik_tls_acme_tenant_id",
"type": "str",
"title": "Azure Tenant ID",
"required": true,
"needs": [
"traefik_tls_enabled=true",
"traefik_tls_certresolver=azure"
]
},
{
"name": "traefik_tls_acme_subscription_id",
"type": "str",
"title": "Azure Subscription ID",
"required": true,
"needs": [
"traefik_tls_enabled=true",
"traefik_tls_certresolver=azure"
]
},
{
"name": "traefik_tls_acme_resource_group",
"type": "str",
"title": "Azure Resource Group",
"required": true,
"description": "Azure DNS resource group.",
"needs": [
"traefik_tls_enabled=true",
"traefik_tls_certresolver=azure"
]
},
{
"name": "traefik_tls_redirect",
"type": "bool",
"title": "HTTP Redirect",
"required": false,
"default": true,
"description": "Redirect all HTTP traffic to HTTPS.",
"needs": [
"traefik_tls_enabled=true"
]
},
{
"name": "traefik_tls_min_version",
"type": "enum",
"title": "Minimum TLS Version",
"required": false,
"default": "VersionTLS12",
"config": {
"options": [
"VersionTLS12",
"VersionTLS13"
]
},
"needs": [
"traefik_tls_enabled=true"
]
},
{
"name": "traefik_tls_secure_ciphers",
"type": "bool",
"title": "Strict Ciphers",
"required": false,
"default": false,
"needs": [
"traefik_tls_enabled=true"
]
},
{
"name": "traefik_tls_skipverify",
"type": "bool",
"title": "Skip Backend Verify",
"required": false,
"default": false,
"description": "Skip TLS verification for backend servers.",
"needs": [
"traefik_tls_enabled=true"
]
}
]
},
{
"name": "swarm",
"title": "Docker Swarm",
"items": [
{
"name": "swarm_placement_mode",
"type": "enum",
"title": "Placement Mode",
"required": true,
"default": "replicated",
"description": "Swarm deployment mode. Traefik is constrained to manager nodes because the Swarm provider reads service state through the local Docker socket. Use replicated with one replica when Traefik manages ACME certificates. Global mode runs one task per eligible manager node, but Traefik OSS cannot safely coordinate active-active ACME writes to a shared acme.json. See https://doc.traefik.io/traefik/providers/swarm/ and https://doc.traefik.io/traefik/https/acme/.",
"config": {
"options": [
"global",
"replicated"
]
}
},
{
"name": "swarm_replicas",
"type": "int",
"title": "Replicas",
"required": false,
"default": 1,
"description": "Number of replicas when placement mode is replicated. Keep this at 1 when Traefik manages ACME certificates; use multiple replicas only with external/static certificate management.",
"config": {
"placeholder": "1",
"unit": "replicas",
"slider": true,
"min": 1,
"max": 10,
"step": 1
},
"needs": [
"swarm_placement_mode=replicated"
]
},
{
"name": "swarm_placement_host",
"type": "str",
"title": "Placement Host",
"required": false,
"default": "",
"description": "Optional manager-node hostname constraint. The selected node must be a Swarm manager.",
"config": {
"placeholder": "swarm-node-1"
}
}
]
},
{
"name": "volume",
"title": "Volume",
"items": [
{
"name": "volume_mode",
"type": "enum",
"title": "Volume Mode",
"required": true,
"default": "local",
"description": "Storage mode for ACME certificate data. Shared storage allows file access from multiple nodes, but it does not make Traefik-managed ACME safe with multiple active Traefik writers. Use one Traefik replica for ACME, or use external/static certificate management for multi-replica Traefik. See https://doc.traefik.io/traefik/https/acme/.",
"config": {
"options": [
"local",
"mount",
"nfs"
]
}
},
{
"name": "volume_mount_path",
"type": "str",
"title": "Bind Mount Path",
"required": true,
"default": "/data/traefik/certs",
"description": "Host path used for certificate storage.",
"config": {
"placeholder": "/data/traefik/certs"
},
"needs": [
"volume_mode=mount"
]
},
{
"name": "volume_nfs_server",
"type": "str",
"title": "NFS Server",
"required": true,
"default": "NFS_SERVER",
"config": {
"placeholder": "NFS_SERVER"
},
"needs": [
"volume_mode=nfs"
]
},
{
"name": "volume_nfs_path",
"type": "str",
"title": "NFS Path",
"required": true,
"default": "/export/traefik/certs",
"config": {
"placeholder": "/export/traefik/certs"
},
"needs": [
"volume_mode=nfs"
]
},
{
"name": "volume_nfs_options",
"type": "str",
"title": "NFS Options",
"required": true,
"default": "rw,nolock,soft",
"config": {
"placeholder": "rw,nolock,soft"
},
"needs": [
"volume_mode=nfs"
]
}
]
}
]
}
@@ -0,0 +1,39 @@
services:
<< service_name >>:
image: docker.io/twingate/connector:1.88.0
hostname: << container_hostname >>
environment:
- TZ=<< container_timezone >>
- TWINGATE_NETWORK=<< twingate_network >>
- TWINGATE_ACCESS_TOKEN=<< twingate_access_token >>
- TWINGATE_REFRESH_TOKEN=<< twingate_refresh_token >>
- TWINGATE_LOG_ANALYTICS=v2
- TWINGATE_LOG_LEVEL=<< twingate_log_level >>
<%- if twingate_dns %>
- TWINGATE_DNS=<< twingate_dns >>
<%- endif %>
sysctls:
net.ipv4.ping_group_range: "0 2147483647"
deploy:
<%- if swarm_placement_mode == 'replicated' %>
mode: replicated
replicas: << swarm_replicas >>
<%- if swarm_placement_host %>
placement:
constraints:
- node.hostname == << swarm_placement_host >>
<%- endif %>
<%- else %>
mode: global
<%- endif %>
restart_policy:
condition: on-failure
<%- if resources_enabled %>
resources:
limits:
cpus: '<< resources_cpu_limit >>'
memory: << resources_memory_limit >>
reservations:
cpus: '<< resources_cpu_reservation >>'
memory: << resources_memory_reservation >>
<%- endif %>
+206
View File
@@ -0,0 +1,206 @@
{
"slug": "twingate-connector",
"kind": "swarm",
"metadata": {
"name": "Twingate_Connector",
"description": "Lightweight agent that establishes secure zero-trust connections between your private network and the Twingate service, allowing authorized users to access internal resources without a VPN.",
"tags": [],
"icon": {
"provider": "selfhst",
"id": "twingate"
},
"draft": false,
"version": {
"name": "1.88.0",
"source_dep_name": "docker.io/twingate/connector",
"source_dep_version": "1.88.0"
}
},
"variables": [
{
"title": "General",
"name": "general",
"items": [
{
"name": "service_name",
"type": "str",
"title": "Service Name",
"required": false,
"default": "twingate",
"config": {
"placeholder": "twingate"
}
},
{
"name": "container_hostname",
"type": "str",
"title": "Container Hostname",
"required": false,
"default": "twingate-connector",
"config": {
"placeholder": "twingate-connector"
}
},
{
"name": "container_timezone",
"type": "str",
"title": "Container Timezone",
"required": true,
"config": {
"placeholder": "Europe/Berlin"
}
},
{
"name": "swarm_placement_mode",
"type": "enum",
"title": "Swarm Placement Mode",
"required": true,
"default": "replicated",
"config": {
"options": [
"replicated",
"global"
]
}
},
{
"name": "swarm_replicas",
"type": "int",
"title": "Swarm Replicas",
"required": false,
"default": 1,
"config": {
"slider": true,
"min": 1,
"max": 10,
"step": 1,
"placeholder": "1",
"unit": "replicas"
},
"needs": [
"swarm_placement_mode=replicated"
]
},
{
"name": "swarm_placement_host",
"type": "str",
"title": "Swarm Placement Host",
"required": false,
"default": "",
"needs": [
"swarm_placement_mode=replicated"
],
"config": {
"placeholder": "swarm-node-1"
}
}
]
},
{
"title": "Twingate Configuration",
"name": "twingate",
"items": [
{
"name": "twingate_network",
"type": "str",
"title": "Network Name",
"required": true
},
{
"name": "twingate_access_token",
"type": "secret",
"title": "Access Token",
"required": true,
"description": "Connector access token from Twingate."
},
{
"name": "twingate_refresh_token",
"type": "secret",
"title": "Refresh Token",
"required": true,
"description": "Connector refresh token from Twingate."
},
{
"name": "twingate_log_level",
"type": "int",
"title": "Log Level",
"required": false,
"default": 1,
"description": "Log level (1=ERROR, 2=WARN, 3=INFO, 4=DEBUG)",
"config": {
"slider": true,
"min": 1,
"max": 4,
"step": 1,
"placeholder": "1"
}
},
{
"name": "twingate_dns",
"type": "str",
"title": "DNS Server",
"required": false,
"default": "",
"description": "Local DNS server IP (optional, leave empty to use default)",
"config": {
"placeholder": "192.0.2.53"
}
}
]
},
{
"title": "Resource Limits",
"name": "resources",
"toggle": "resources_enabled",
"items": [
{
"name": "resources_enabled",
"type": "bool",
"title": "Resources Enabled",
"required": false,
"default": false
},
{
"name": "resources_cpu_limit",
"type": "str",
"title": "Resources Cpu Limit",
"required": true,
"default": 1,
"config": {
"placeholder": "1"
}
},
{
"name": "resources_cpu_reservation",
"type": "str",
"title": "Resources Cpu Reservation",
"required": true,
"default": 0.25,
"config": {
"placeholder": "0.25"
}
},
{
"name": "resources_memory_limit",
"type": "str",
"title": "Resources Memory Limit",
"required": true,
"default": "1G",
"config": {
"placeholder": "1G"
}
},
{
"name": "resources_memory_reservation",
"type": "str",
"title": "Resources Memory Reservation",
"required": true,
"default": "512M",
"config": {
"placeholder": "512M"
}
}
]
}
]
}