Author SHA1 Message Date
Arnout van Westen 169b5f1ba0 fix(ai): drop --host flag from ollama healthcheck, 0.35.x lacks it
OLLAMA_HOST env already points the CLI at the API server.
2026-10-05 14:52:27 +02:00
Arnout van Westen 8a6b48313d fix(ai): ollama healthcheck via ollama CLI, curl absent from image
curl/wget missing from ollama/ollama -> healthcheck exit 127 -> ollama
unhealthy -> openwebui (depends_on: service_healthy) never started.
Use the ollama CLI against the API server instead.
2026-10-05 14:45:57 +02:00
Arnout van Westen 7517727ec3 ai fix 2026-10-05 14:43:56 +02:00
Arnout van Westen e9c8c882a5 feat(ai): add ollama + open webui stack on private network
- ollama 0.35.1, host port 11434 for LAN/other-stacks API access
- open-webui 0.11.4, host port 8081 (8080 taken by immich)
- wired via OLLAMA_BASE_URL on shared ai network
- traefik router chat.arnoutvw.nl via TNC attach pattern
2026-10-05 14:30:51 +02:00
Arnout van Westen b922d54f36 fix(dawarich): restore redis 8.10 tag from renovate bump, fixes RDB v15 load
c136daf reverted the renovate redis-8.x bump by restoring the pre-bump
file. Redis 8.10 wrote an RDB v15 dump to the shared volume; redis 7.4
cannot read it. Restore the 8.10-alpine tag so the dump loads.
2026-10-05 12:05:18 +02:00
arnoutvw 6ceca7cd73 Update gitea/docker-compose.yml 2026-10-05 11:22:08 +02:00
Arnout van Westen c136dafc5b feat(trn): replace TNC with shell traefik-network-watcher
Own watcher (docker:28-cli + handler.sh): attaches traefik to every docker
network labelled traefik.enable=true (daemon-side filter), 5-min periodic
resync + traefik-restart healing. dawarich/teslamate back on private
networks with the net label set.
2026-10-05 11:05:19 +02:00
Arnout van Westen 21ee8d9c98 fix(s3): alias router for vaults3 container-name domain 2026-10-05 10:28:29 +02:00
Arnout van Westen fe75087641 fix(download): alias routers for binhex-*/seerr container-name domains 2026-10-05 10:27:52 +02:00
Arnout van Westen 9c4022a650 fix(teslamate): restore teslamateapi traefik router label
Lost in 122ca76 base restore — without it dnsweaver orphan cleanup deleted
the teslamateapi.arnoutvw.nl rewrite (desired-set shrank).
2026-10-05 10:25:20 +02:00
arnoutvw 237af8b40c Merge pull request 'chore(deps): update redis docker tag to v8' (#438) from renovate/redis-8.x into main
Reviewed-on: #438
2026-10-05 10:24:50 +02:00
arnoutvw 9f9cd36304 Merge pull request 'chore(deps): update jgeusebroek/spotweb docker tag to v20261003' (#440) from renovate/jgeusebroek-spotweb-20261003.x into main
Reviewed-on: #440
2026-10-05 10:24:30 +02:00
arnoutvw 7d2f745af3 Merge pull request 'chore(deps): update docker.io/fosrl/gerbil docker tag to v1.5.2' (#442) from renovate/docker.io-fosrl-gerbil-1.x into main
Reviewed-on: #442
2026-10-05 10:24:19 +02:00
arnoutvw 7790717c44 Merge pull request 'chore(config): migrate Renovate config' (#445) from renovate/migrate-config into main
Reviewed-on: #445
2026-10-05 10:24:07 +02:00
Renovate Bot e17779d5bc chore(config): migrate config renovate.json 2026-10-05 08:17:21 +00:00
renovate-bot c0cb407d7a Merge pull request 'chore(deps): update ghcr.io/pocket-id/pocket-id docker tag to v2.18.0' (#444) from renovate/ghcr.io-pocket-id-pocket-id-2.x into main 2026-10-05 10:17:11 +02:00
Renovate Bot 533c268e56 chore(deps): update ghcr.io/pocket-id/pocket-id docker tag to v2.18.0 2026-10-05 08:17:07 +00:00
renovate-bot 09533fcd9c Merge pull request 'chore(deps): update n8nio/n8n docker tag to v2.42.3' (#443) from renovate/n8nio-n8n-2.x into main 2026-10-05 10:17:06 +02:00
Renovate Bot 4118de31e9 chore(deps): update n8nio/n8n docker tag to v2.42.3 2026-10-05 08:16:44 +00:00
Renovate Bot 55d24d7928 chore(deps): update docker.io/fosrl/gerbil docker tag to v1.5.2 2026-10-05 08:16:38 +00:00
Arnout van Westen 03b1607e79 revert(infra): back to bridge networking, remove TNC dependency
Per request: TNC removed, all stacks back on default bridge with legacy
links for inter-container DNS (default bridge has no embedded DNS —
verified: nameserver passthrough to AdGuard). Kept: traefik router labels
(dnsweaver records), dawarich prod + SECRET_KEY_BASE, teslamate/bookorbit
hostport removals (service DNS now via links), komodo periphery as
separate project with 8120 hostport + server address change.
2026-10-05 10:15:39 +02:00
Arnout van Westen fa790b3d37 fix(dnsweaver): own router label + underscore hostnames excluded 2026-10-05 09:22:37 +02:00
Arnout van Westen 0eb590f455 feat(dnsweaver): traefik router labels on all HTTP UIs; exclude list trimmed to DBs/agents
All HTTP-served containers (web UIs + metrics APIs) now carry explicit
router-rule labels so dnsweaver manages their arnoutvw.nl rewrites end
to end (no more relying on traefik defaultRule). krusader fixed to
noVNC 8080-ish label -> 6080. EXCLUDE_DOMAINS reduced to databases,
workers and agents (postgres14/mariadb/redis/postgresql17/komodo-mongo/
bookorbit-db/immich_postgres/immich_ml/dawarich_*db-redis-sidekiq/
influxdb/newt*/komodo-periphery/dockersocket/subsyncarr/wordpress-blues).
2026-10-05 09:10:52 +02:00
Arnout van Westen 5060226c23 chore(dnsweaver): unexclude gitea — now carries traefik router label 2026-10-05 08:55:10 +02:00
Arnout van Westen 92873ae4bf fix(pangolin-labels): full blueprint labels minus region rules
Region value=EU is not a UN M.49 subregion id (the only real invalid reason)
so rules are omitted entirely, matching how existing resources are configured.
2026-10-05 08:53:50 +02:00
Arnout van Westen f32910e2c9 fix(pangolin-labels): drop remaining numeric/boolean-typed label fields 2026-10-05 08:48:31 +02:00
Arnout van Westen fb4223fa17 fix(pangolin-labels): minimal strings-only labels — pangolin Zod rejects numeric/boolean string label values
port/ssl/healthcheck as labels arrive as strings and fail Zod (z.int/z.boolean);
drop those, rely on auto-detection (container hostname + exposed port, ssl
default on) and pangolin-side defaults for rules/auth.
2026-10-05 08:48:12 +02:00
Arnout van Westen ef28e2d358 fix(pangolin-labels): proxy-resources rejected by pangolin ee-1.23
Primary pangolin skips legacy proxy-resources labels entirely ('All
resources were invalid and skipped'); secondary ee-1.24 accepted them.
Switch gitea+komodo to current public-resources syntax with mode=http.
2026-10-05 08:46:06 +02:00
Arnout van Westen e658b49fd7 refactor(komodo): periphery outside核心 stack (komodo-periphery/)
Per komodo discussion #223: periphery executes deploys; compose child
recreating its own parent dies mid-deploy. Core stack = mongo+core+mcp;
periphery = separate project on the same external komodo-internal network.
Renovate disabled for komodo-periphery/; update-stacks procedure excludes
both komodo stacks (manual host deploys).
2026-10-05 08:44:45 +02:00
Arnout van Westen 10e9a09a4a fix(komodo): private network for stack (default bridge DNS insufficient after dropping legacy links) 2026-10-05 08:41:19 +02:00
Arnout van Westen b38dca675a fix(newt): drop DOCKER_ENFORCE_NETWORK_VALIDATION
Newt 1.18.1 enforces this feature; newt runs on the default bridge and
resource targets are host-IP ports, so the host-container lookup can never
match -> 'failed to find host container' on every docker event, breaking
docker-label blueprint provisioning (since 1.12.5->1.18.1 bump on Oct 2).
2026-10-05 08:30:59 +02:00
Arnout van Westen 1b8d5e5f15 feat(komodo): move komodo + gitea off dockerman/compose-manager into repo
komodo: mongo:9.0 + core/periphery :2 + mcp, .env from compose-manager
project (no legacy passkeys), komodo.skip labels + init + v2 keys mounts
kept. Gitea: gitea:28.0.0 + act_runner:0.6.1, restart=unless-stopped
(dockerman had restart=no with Unraid autostart). Both get pangolin
proxy-resources blueprint labels (internet via pangolin primary + newt
-> host port) next to their traefik routes. Renovate-bumpable now.
2026-10-05 08:23:14 +02:00
arnoutvw 67574a80c7 Update pangolin/docker-compose.yml 2026-10-05 08:15:44 +02:00
Arnout van Westen 4eb5d0914f feat(pangolin): move ionos primary compose from files_on_host into repo
Same stack (pangolin ee-1.23.0, gerbil 1.5.1, traefik v3.7, crowdsec, grafana,
prometheus, dashboards, project pangolin); mounts absolute to /root on the
VPS; crowdsec-manager now mounted on the repo-managed compose file so it
edits the git-tracked source. Enables Renovate version bumps.
2026-10-05 07:36:14 +02:00
arnoutvw f2d14badb4 Update pangolin-secondary/docker-compose.yml 2026-10-04 22:13:50 +02:00
Arnout van Westen d32b08ce95 feat(infra): dnsweaver manages AdGuard rewrites for labeled containers
Managed mode (type+target-scoped orphan cleanup). Wildcard *.arnoutvw.nl
rewrite removed; defaultRule-derived (unlabeled) hostnames kept as static
rewrites via EXCLUDE_DOMAINS.
2026-10-04 20:56:16 +02:00
Arnout van Westen 7a1c0c234b fix(download): valid 64-hex BOOK_REQUEST_ENCRYPTION_KEY (was UUID form, app rejected it: credentials could not be stored) 2026-10-04 19:38:44 +02:00
Arnout van Westen aa309fbf81 fix(dawarich): SECRET_KEY_BASE missing on sidekiq env
Production mode derives OTP/encryption keys from SECRET_KEY_BASE; app had
it, sidekiq did not -> 'OTP_ENCRYPTION_PRIMARY_KEY required in production'
crash loop. DB has 0 OTP users, so derived keys are safe.
2026-10-04 19:32:30 +02:00
renovate-bot 6413918e26 Merge pull request 'chore(deps): update docker.io/fosrl/gerbil docker tag to v1.5.2' (#441) from renovate/docker.io-fosrl-gerbil-1.x into main 2026-10-04 10:03:20 +02:00
Renovate Bot a89bdcede3 chore(deps): update docker.io/fosrl/gerbil docker tag to v1.5.2 2026-10-04 08:03:17 +00:00
Arnout van Westen 085c5f7243 feat(pangolin-secondary): move VPS compose from files_on_host into repo
Same stack (pangolin ee-1.21.1, gerbil 1.4.3, traefik v3.7, project pangolin);
bind mounts made absolute to /root/config on the VPS. Enables Renovate
version bumps.
2026-10-04 08:05:03 +02:00
Renovate Bot 5b3608b3e8 chore(deps): update jgeusebroek/spotweb docker tag to v20261003 2026-10-03 20:02:38 +00:00
renovate-bot 15a60afa7c Merge pull request 'chore(deps): update ghcr.io/maintainerr/maintainerr docker tag to v3.30.1' (#439) from renovate/ghcr.io-maintainerr-maintainerr-3.x into main 2026-10-03 22:02:31 +02:00
Renovate Bot 3d94cba6c2 chore(deps): update ghcr.io/maintainerr/maintainerr docker tag to v3.30.1 2026-10-03 20:02:25 +00:00
Arnout van Westen 5e7ab46f71 refactor(networks): private compose networks instead of shared bridge
traefik-network-connector attaches traefik to container networks labelled
traefik.enable=true, so stacks no longer need the default bridge:
- changedetection: app+sockpuppetbrowser on changedetection network, links out
- postiz: postiz-network, legacy links out
- teslamate: teslamate network, DB via service DNS (postgresql17), 5432
  hostport dropped, teslamateapi -> teslamate:4000 internal
- download: bookorbit+bookorbit-db on bookorbit network (5435 hostport dropped)
- immich: immich network in .env host IP refs -> service/container DNS
All published host ports kept unless removed above; pangolin target
hostnames still point at 192.168.10.144 host ports.
2026-10-03 21:53:13 +02:00
Arnout van Westen 9ab0357f16 feat(infra): add traefik-network-connector; dawarich off shared bridge
- new stack traefik-network-connector: attaches atlas traefik to networks
  of containers labelled traefik.enable=true (obeone/traefik_network_connector)
- dawarich: rewrite to upstream compose style (private dawarich network,
  no default-bridge sharing, no legacy links). Keep pinned image tags,
  host port 3007 (pangolin/newt target), photon override, concurrency 10.
  RAILS_ENV development -> production (+ SECRET_KEY_BASE, upstream default).
2026-10-03 07:53:12 +02:00
Renovate Bot 887a93d5a6 chore(deps): update redis docker tag to v8 2026-10-02 20:03:45 +00:00
renovate-bot 122ca76eb8 Merge pull request 'chore(deps): update n8nio/n8n docker tag to v2.42.2' (#436) from renovate/n8nio-n8n-2.x into main 2026-10-02 22:03:14 +02:00
renovate-bot 0e1806a8f3 Merge pull request 'chore(deps): update ghcr.io/gitroomhq/postiz-app docker tag to v2.25.0' (#435) from renovate/ghcr.io-gitroomhq-postiz-app-2.x into main 2026-10-02 22:02:38 +02:00
Renovate Bot 3bb40ad67e chore(deps): update n8nio/n8n docker tag to v2.42.2 2026-10-02 20:02:38 +00:00
Renovate Bot adbf36a9d3 chore(deps): update ghcr.io/gitroomhq/postiz-app docker tag to v2.25.0 2026-10-02 20:02:37 +00:00
renovate-bot a6fe126fbb Merge pull request 'chore(deps): update fosrl/newt docker tag to v1.18.1' (#434) from renovate/fosrl-newt-1.x into main 2026-10-02 22:02:36 +02:00
Renovate Bot 5fbdd7ffde chore(deps): update fosrl/newt docker tag to v1.18.1 2026-10-02 20:02:33 +00:00
27 changed files with 1155 additions and 91 deletions

No files matched your search

+84
View File
@@ -0,0 +1,84 @@
# Ollama + Open WebUI in one stack, wired together on a private network.
# Local deviations:
# - image tags pinned (repo convention; Renovate bumps)
# - ollama on host port 11434: LAN clients and other stacks (n8n, HA)
# target the API at 192.168.10.144:11434
# - open-webui on host port 8081: 8080 already taken on Atlas by immich
# - traefik labels on openwebui: Atlas traefik does NOT sit on this
# network; traefik-network-connector (own stack) attaches it on start
# - CPU-only inference: Atlas has only an Intel UHD 630 iGPU (not usable
# by the plain ollama image); 4c/8t + 32GB RAM -> small models (3-8B Q4)
networks:
ai:
labels:
- traefik.enable=true
services:
ollama:
image: ollama/ollama:0.35.1
container_name: ollama
networks:
- ai
environment:
OLLAMA_HOST: 0.0.0.0:11434
ports:
# host port 11434: LAN API target for n8n / homeassistant
- 11434:11434
volumes:
- ollama_models:/root/.ollama
restart: unless-stopped
healthcheck:
# no curl in the ollama image; its own CLI hits the API server via
# OLLAMA_HOST env (no --host flag in 0.35.x), passes when server answers
test: [ "CMD-SHELL", "ollama list >/dev/null 2>&1 || exit 1" ]
interval: 30s
retries: 5
start_period: 60s
timeout: 10s
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "5"
openwebui:
image: ghcr.io/open-webui/open-webui:0.11.4
container_name: openwebui
networks:
- ai
labels:
- traefik.enable=true
- traefik.http.routers.openwebui.rule=Host(`chat.arnoutvw.nl`)
environment:
OLLAMA_BASE_URL: http://ollama:11434
WEBUI_NAME: Atlas AI
ports:
# custom host port: 8080 already taken on Atlas by immich
- 8081:8080
volumes:
- openwebui_data:/app/backend/data
restart: unless-stopped
healthcheck:
# upstream image ships its own healthcheck using curl/urllib
test: [ "CMD-SHELL", "curl -f -o /dev/null http://127.0.0.1:8080/api/version || exit 1" ]
interval: 30s
retries: 5
start_period: 90s
timeout: 10s
depends_on:
ollama:
condition: service_healthy
restart: true
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "5"
deploy:
resources:
limits:
memory: '2G'
volumes:
ollama_models:
openwebui_data:
+23 -4
View File
@@ -52,6 +52,9 @@ services:
ipc: "private"
labels:
traefik.enable: "true"
traefik.http.routers.mealie.rule: Host(`mealie.arnoutvw.nl`)
traefik.http.services.mealie.loadbalancer.server.port: "9000"
net.unraid.docker.managed: "dockerman"
net.unraid.docker.webui: "http://[IP]:[PORT:9926]"
org.opencontainers.image.created: "2026-05-06T18:51:16.487Z"
@@ -104,7 +107,6 @@ services:
- "HOST_CONTAINERNAME=Newt"
- "HOST_OS=Unraid"
- "NEWT_ID=nj3wvqzj44a8sh1"
- "DOCKER_ENFORCE_NETWORK_VALIDATION=true"
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
expose:
@@ -112,7 +114,7 @@ services:
hostname: "e6ea728334b3"
image: "fosrl/newt:1.12.5"
image: "fosrl/newt:1.18.1"
ipc: "private"
@@ -168,7 +170,6 @@ services:
- "HOST_HOSTNAME=Atlas"
- "HOST_CONTAINERNAME=Newt-secondary"
- "DOCKER_SOCKET=/var/run/docker.sock"
- "DOCKER_ENFORCE_NETWORK_VALIDATION=true"
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
expose:
@@ -176,7 +177,7 @@ services:
hostname: "62a85da202e1"
image: "fosrl/newt:1.12.5"
image: "fosrl/newt:1.18.1"
ipc: "private"
@@ -257,6 +258,9 @@ services:
ipc: "private"
labels:
traefik.enable: "true"
traefik.http.routers.ntfy.rule: Host(`ntfy.arnoutvw.nl`)
traefik.http.services.ntfy.loadbalancer.server.port: "80"
cloudflare.tunnel.enable: "true"
cloudflare.tunnel.hostname: "ntfy.arnoutvw.nl"
net.unraid.docker.icon: "https://raw.githubusercontent.com/binwiederhier/ntfy:v2.28.0/main/docs/static/img/ntfy.png"
@@ -328,6 +332,9 @@ services:
ipc: "private"
labels:
traefik.enable: "true"
traefik.http.routers.wallos.rule: Host(`wallos.arnoutvw.nl`)
traefik.http.services.wallos.loadbalancer.server.port: "80"
net.unraid.docker.icon: "https://raw.githubusercontent.com/devzwf/unraid-docker-templates/main/images/wallos.png"
net.unraid.docker.managed: "dockerman"
net.unraid.docker.webui: "http://[IP]:[PORT:80]/"
@@ -477,6 +484,9 @@ services:
ipc: "private"
labels:
traefik.enable: "true"
traefik.http.routers.homepage.rule: Host(`homepage.arnoutvw.nl`)
traefik.http.services.homepage.loadbalancer.server.port: "3000"
net.unraid.docker.icon: "https://raw.githubusercontent.com/gethomepage/homepage/main/public/android-chrome-512x512.png"
net.unraid.docker.managed: "dockerman"
net.unraid.docker.webui: "http://[IP]:[PORT:3000]"
@@ -617,6 +627,9 @@ services:
ipc: "private"
labels:
traefik.enable: "true"
traefik.http.routers.paperless-ng.rule: Host(`paperless-ng.arnoutvw.nl`)
traefik.http.services.paperless-ng.loadbalancer.server.port: "8000"
net.unraid.docker.icon: "https://raw.githubusercontent.com/selfhosters/unRAID-CA-templates/master/templates/img/paperless.png"
net.unraid.docker.managed: "dockerman"
net.unraid.docker.webui: "http://[IP]:[PORT:8000]"
@@ -703,6 +716,9 @@ services:
ipc: "private"
labels:
traefik.enable: "true"
traefik.http.routers.paperless-ngx-kristin.rule: Host(`paperless-ngx-kristin.arnoutvw.nl`)
traefik.http.services.paperless-ngx-kristin.loadbalancer.server.port: "8000"
net.unraid.docker.icon: "https://raw.githubusercontent.com/selfhosters/unRAID-CA-templates/master/templates/img/paperless.png"
net.unraid.docker.managed: "dockerman"
net.unraid.docker.webui: "http://[IP]:[PORT:8000]"
@@ -835,6 +851,9 @@ services:
ipc: "private"
labels:
traefik.enable: "true"
traefik.http.routers.syncthing.rule: Host(`syncthing.arnoutvw.nl`)
traefik.http.services.syncthing.loadbalancer.server.port: "8384"
build_version: "Linuxserver.io version:- v2.0.16-ls216 Build-date:- 2026-05-09T04:12:55+00:00"
maintainer: "thelamer"
net.unraid.docker.icon: "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/syncthing-icon.png"
+9 -1
View File
@@ -74,6 +74,10 @@ services:
- "PGADMIN_DEFAULT_EMAIL=arnoutvw@gmail.com"
- "PGADMIN_DEFAULT_PASSWORD=${PGADMIN_PASSWORD}"
image: "dpage/pgadmin4:9.18"
labels:
- traefik.enable=true
- traefik.http.routers.pgadmin4.rule=Host(`pgadmin4.arnoutvw.nl`)
- traefik.http.services.pgadmin4.loadbalancer.server.port=80
ipc: "private"
logging:
driver: "json-file"
@@ -107,6 +111,10 @@ services:
- "MEMORY_LIMIT=512M"
- "UPLOAD_LIMIT=8192K"
image: "lscr.io/linuxserver/phpmyadmin:5.2.3-ls252"
labels:
- traefik.enable=true
- traefik.http.routers.phpmyadmin.rule=Host(`phpmyadmin.arnoutvw.nl`)
- traefik.http.services.phpmyadmin.loadbalancer.server.port=80
ipc: "private"
logging:
driver: "json-file"
@@ -137,4 +145,4 @@ services:
network_mode: "bridge"
ports:
- "6379:6379/tcp"
restart: "unless-stopped"
restart: "unless-stopped"
+48 -40
View File
@@ -1,27 +1,49 @@
# Based on upstream https://github.com/Freika/dawarich/blob/master/docker/docker-compose.yml
# Local deviations:
# - image tags pinned (repo convention; Renovate bumps)
# - host port 3007 -> 3000: pangolin (newt) and LAN clients target
# 192.168.10.144:3007, so it must stay published on the host
# - traefik labels on dawarich_app: Atlas traefik does NOT sit on this
# network; traefik-network-connector (own stack) attaches it on start
# - RAILS_ENV production (upstream default; install predates the switch)
# - BACKGROUND_PROCESSING_CONCURRENCY 10 (upstream default 3; tuned for
# large imports)
# - local photon geocoding (photon container currently disabled)
networks:
dawarich:
labels:
- traefik.enable=true
services:
dawarich_redis:
image: redis:7.4-alpine
image: redis:8.10-alpine
container_name: dawarich_redis
command: redis-server
network_mode: bridge
command: >
redis-server
--save 900 1
--save 300 10
--appendonly no
networks:
- dawarich
volumes:
- dawarich_shared:/data
restart: always
healthcheck:
test: [ "CMD-SHELL", "redis-cli --raw incr ping || exit 1" ]
test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ]
interval: 10s
retries: 5
start_period: 30s
timeout: 10s
dawarich_db:
image: postgis/postgis:17-3.5-alpine
shm_size: 1G
container_name: dawarich_db
network_mode: bridge
volumes:
- dawarich_db_data:/var/lib/postgresql/data
- dawarich_shared:/var/shared
# - ./postgresql.conf:/etc/postgresql/postgresql.conf # Optional, uncomment if you want to use a custom config
networks:
- dawarich
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
@@ -33,31 +55,32 @@ services:
retries: 5
start_period: 30s
timeout: 10s
# command: postgres -c config_file=/etc/postgresql/postgresql.conf # Use custom config, uncomment if you want to use a custom config
dawarich_app:
labels:
- traefik.constraint=proxy-public
- traefik.http.routers.nginx.rule=Host(`dawarich.arnoutvw.nl`)
image: freikin/dawarich:1.15.3
container_name: dawarich_app
network_mode: bridge
volumes:
- dawarich_public:/var/app/public
- dawarich_watched:/var/app/tmp/imports/watched
- dawarich_storage:/var/app/storage
links:
- dawarich_db
- dawarich_redis
- dawarich_db_data:/dawarich_db_data
networks:
- dawarich
labels:
- traefik.enable=true
- traefik.http.routers.dawarich.rule=Host(`dawarich.arnoutvw.nl`)
- traefik.http.services.dawarich.loadbalancer.server.port=3000
ports:
# custom host port: pangolin/newt + LAN target 192.168.10.144:3007
- 3007:3000
- 9397:9394 # Prometheus exporter, uncomment if needed
stdin_open: true
tty: true
entrypoint: web-entrypoint.sh
command: [ 'bin/rails', 'server', '-p', '3000', '-b', '::' ]
restart: always
restart: unless-stopped
environment:
RAILS_ENV: development
RAILS_ENV: production
SECRET_KEY_BASE: 2f5e59518ddeaeb978c73bc265eea20a91d5fe203d2a45280bd8fbf62b447b57
REDIS_URL: redis://dawarich_redis:6379
DATABASE_HOST: dawarich_db
DATABASE_USERNAME: postgres
@@ -65,13 +88,6 @@ services:
DATABASE_NAME: dawarich_development
MIN_MINUTES_SPENT_IN_CITY: 60
APPLICATION_HOSTS: localhost,dawarich.arnoutvw.nl,192.168.10.144
TIME_ZONE: Europe/London
APPLICATION_PROTOCOL: http
PROMETHEUS_EXPORTER_ENABLED: false
PROMETHEUS_EXPORTER_HOST: 0.0.0.0
PROMETHEUS_EXPORTER_PORT: 9394
SELF_HOSTED: "true"
STORE_GEODATA: "true"
PHOTON_API_HOST: 192.168.10.144:2322
PHOTON_API_USE_HTTPS: false
logging:
@@ -95,8 +111,9 @@ services:
deploy:
resources:
limits:
cpus: '0.50' # Limit CPU usage to 50% of one core
memory: '4G' # Limit memory usage to 4GB
cpus: '0.50'
memory: '4G'
dawarich_sidekiq:
image: freikin/dawarich:1.15.3
container_name: dawarich_sidekiq
@@ -104,33 +121,24 @@ services:
- dawarich_public:/var/app/public
- dawarich_watched:/var/app/tmp/imports/watched
- dawarich_storage:/var/app/storage
network_mode: bridge
links:
- dawarich_db
- dawarich_redis
networks:
- dawarich
stdin_open: true
tty: true
entrypoint: sidekiq-entrypoint.sh
command: [ 'sidekiq' ]
restart: always
restart: unless-stopped
environment:
RAILS_ENV: development
RAILS_ENV: production
SECRET_KEY_BASE: 2f5e59518ddeaeb978c73bc265eea20a91d5fe203d2a45280bd8fbf62b447b57
REDIS_URL: redis://dawarich_redis:6379
DATABASE_HOST: dawarich_db
DATABASE_USERNAME: postgres
DATABASE_PASSWORD: password
DATABASE_NAME: dawarich_development
APPLICATION_HOSTS: localhost
BACKGROUND_PROCESSING_CONCURRENCY: 10
APPLICATION_PROTOCOL: http
PROMETHEUS_EXPORTER_ENABLED: false
PROMETHEUS_EXPORTER_HOST: dawarich_app
PROMETHEUS_EXPORTER_PORT: 9394
SELF_HOSTED: "true"
STORE_GEODATA: "true"
PHOTON_API_HOST: 192.168.10.144:2322
PHOTON_API_USE_HTTPS: false
logging:
driver: "json-file"
options:
+41 -9
View File
@@ -11,6 +11,9 @@ services:
- "PUID=99"
image: "binhex/arch-jackett:0.24"
labels:
traefik.enable: "true"
traefik.http.routers.binhex-jackett.rule: Host(`binhex-jackett.arnoutvw.nl`)
traefik.http.services.binhex-jackett.loadbalancer.server.port: "9117"
net.unraid.docker.icon: "https://raw.githubusercontent.com/binhex/docker-templates/master/binhex/images/jackett-icon.png"
net.unraid.docker.webui: "http://[IP]:[PORT:9117]/"
org.opencontainers.image.authors: "binhex"
@@ -33,6 +36,8 @@ services:
- "HOST_OS=Unraid"
image: "binhex/arch-radarr:6.4.4.10685-1-01"
labels:
- traefik.http.routers.binhex-radarr.rule=Host(`binhex-radarr.arnoutvw.nl`)
- traefik.http.services.binhex-radarr.loadbalancer.server.port=7878
cloudflare.tunnel.access.policy: "sabnzbd"
cloudflare.tunnel.enable: "true"
cloudflare.tunnel.service: "http://192.168.10.144:7878"
@@ -82,6 +87,8 @@ services:
- "UMASK=000"
image: "binhex/arch-sabnzbd:5.1.3-1-01"
labels:
- traefik.http.routers.binhex-sabnzbd.rule=Host(`binhex-sabnzbd.arnoutvw.nl`)
- traefik.http.services.binhex-sabnzbd.loadbalancer.server.port=8080
cloudflare.tunnel.access.policy: "sabnzbd"
cloudflare.tunnel.enable: "true"
cloudflare.tunnel.hostname: "sabnzbd.arnoutvw.nl"
@@ -132,6 +139,8 @@ services:
- "HOST_CONTAINERNAME=binhex-sonarr"
image: "binhex/arch-sonarr:4.0.20.3014-1-01"
labels:
- traefik.http.routers.binhex-sonarr.rule=Host(`binhex-sonarr.arnoutvw.nl`)
- traefik.http.services.binhex-sonarr.loadbalancer.server.port=8989
cloudflare.tunnel.enable: "true"
cloudflare.tunnel.service: "http://192.168.10.144:8989"
net.unraid.docker.icon: "https://raw.githubusercontent.com/binhex/docker-templates/master/binhex/images/sonarr-icon.png"
@@ -209,8 +218,11 @@ services:
- "TZ=Europe/Berlin"
- "SPOTWEB_DB_HOST=192.168.10.144"
- "SPOTWEB_DB_NAME=spotweb"
image: "jgeusebroek/spotweb:20260919"
image: "jgeusebroek/spotweb:20261003"
labels:
traefik.enable: "true"
traefik.http.routers.spotweb.rule: Host(`spotweb.arnoutvw.nl`)
traefik.http.services.spotweb.loadbalancer.server.port: "80"
Author: "Jeroen Geusebroek <me@jeroengeusebroek.nl>"
net.unraid.docker.icon: "https://raw.githubusercontent.com/riffsphereha/Unraid-Templates/main/spotweb/Spotweb.webp"
net.unraid.docker.webui: "http://[IP]:[PORT:80]"
@@ -293,6 +305,9 @@ services:
- "HOST_HOSTNAME=Atlas"
image: "ghcr.io/thecfu/scraparr:3.2.0"
labels:
traefik.enable: "true"
traefik.http.routers.scraparr.rule: Host(`scraparr.arnoutvw.nl`)
traefik.http.services.scraparr.loadbalancer.server.port: "7100"
net.unraid.docker.icon: "https://raw.githubusercontent.com/jordan-dalby/unraidtemplates/refs/heads/main/images/scraparr.png"
net.unraid.docker.webui: "http://[IP]:[PORT:7100]/metrics"
org.opencontainers.image.created: "2025-06-16T13:12:32.406Z"
@@ -348,6 +363,9 @@ services:
- "WEBUI_PORTS=9696/tcp,9696/udp"
image: "ghcr.io/hotio/prowlarr:release-2.5.2.5491"
labels:
traefik.enable: "true"
traefik.http.routers.prowlarr.rule: Host(`prowlarr.arnoutvw.nl`)
traefik.http.services.prowlarr.loadbalancer.server.port: "9696"
net.unraid.docker.icon: "https://hotio.dev/webhook-avatars/prowlarr.png"
net.unraid.docker.webui: "http://[IP]:[PORT:9696]"
org.opencontainers.image.created: "2025-07-08T23:37:25.000Z"
@@ -423,6 +441,8 @@ services:
retries: 3
restart: unless-stopped
labels:
- traefik.http.routers.seerr.rule=Host(`seerr.arnoutvw.nl`)
- traefik.http.services.seerr.loadbalancer.server.port=5055
traefik.http.routers.seerr.rule: "Host(`overseerr.arnoutvw.nl`)"
pangolin.proxy-resources.overseerr.name: overseerr
pangolin.proxy-resources.overseerr.full-domain: overseerr.arnoutvw.nl
@@ -454,6 +474,9 @@ services:
volumes:
- /mnt/user/appdata/wizarrr:/data
labels:
traefik.enable: "true"
traefik.http.routers.wizarr.rule: Host(`wizarr.arnoutvw.nl`)
traefik.http.services.wizarr.loadbalancer.server.port: "5690"
pangolin.proxy-resources.wizarr.name: wizarr
pangolin.proxy-resources.wizarr.full-domain: wizarr.arnoutvw.nl
pangolin.proxy-resources.wizarr.protocol: http
@@ -482,7 +505,10 @@ services:
kavita:
image: ghcr.io/kareadita/kavita:0.9.1 # Using the stable branch from ghcr.io
container_name: kavita
labels:
- traefik.enable=true
- traefik.http.routers.kavita.rule=Host(`kavita.arnoutvw.nl`)
- traefik.http.services.kavita.loadbalancer.server.port=5000
network_mode: bridge
volumes:
- /mnt/user/books:/books
@@ -500,6 +526,8 @@ services:
image: ghcr.io/bookorbit/bookorbit:3.2.0
container_name: bookorbit-app
network_mode: bridge
links:
- bookorbit-db
ports:
- "3099:3000"
environment:
@@ -509,14 +537,14 @@ services:
PUID: 99
PGID: 100
APP_URL: https://bookorbit.arnoutvw.nl
POSTGRES_HOST: 192.168.10.144
POSTGRES_PORT: 5435
POSTGRES_HOST: bookorbit-db
POSTGRES_PORT: 5432
POSTGRES_USER: bookorbit
POSTGRES_PASSWORD: ${BOOKORBIT_DB_PASSWORD}
POSTGRES_DB: bookorbit
JWT_SECRET: ${BOOKORBIT_JWT_SECRET}
SETUP_BOOTSTRAP_TOKEN: ${BOOKORBIT_SETUP_TOKEN}
BOOK_REQUEST_ENCRYPTION_KEY: ${BOOK_REQUEST_ENCRYPTION_KEY}
BOOK_REQUEST_ENCRYPTION_KEY: a2b1eb1dc394cb3f64725530bb04f7db41a96f7f4a0188b4d75949c81da44127
depends_on:
bookorbit-db:
condition: service_healthy
@@ -539,7 +567,9 @@ services:
stop_grace_period: 30s
restart: unless-stopped
labels:
traefik.http.routers.bookorbit.rule: "Host(`bookorbit.arnoutvw.nl`)"
- traefik.enable=true
- traefik.http.routers.bookorbit.rule=Host(`bookorbit.arnoutvw.nl`)
- traefik.http.services.bookorbit.loadbalancer.server.port=3000
shelfarr:
container_name: shelfarr
@@ -596,8 +626,6 @@ services:
image: pgvector/pgvector:pg18
container_name: bookorbit-db
network_mode: bridge
ports:
- "5435:5432"
environment:
TZ: Europe/Berlin
POSTGRES_USER: bookorbit
@@ -626,7 +654,10 @@ services:
- "TZ=Europe/Berlin"
- "NZBHYDRA2_RELEASE_TYPE=Release"
image: "lscr.io/linuxserver/nzbhydra2:v7.16.3-ls62"
ipc: "private"
labels:
- traefik.enable=true
- traefik.http.routers.hydra2.rule=Host(`hydra2.arnoutvw.nl`)
- traefik.http.services.hydra2.loadbalancer.server.port=5076
logging:
driver: "json-file"
options:
@@ -644,3 +675,4 @@ services:
volumes:
28eea8bfffd285350962765a88ff04ea9d580fe872771d5c06fd62afb26f2ef2:
external: true
+52
View File
@@ -0,0 +1,52 @@
# Gitea (web + act runner) — moved off Unraid dockerman into the repo.
# Exposed via atlas-traefik (LAN) AND pangolin primary (internet) via the
# pangolin docker-label blueprint. Renovate bumps the pinned tags.
# Note: dockerman had restart=no (autostart handled by Unraid); here it is
# unless-stopped so docker/compose restarts it after host boot.
services:
gitea:
image: gitea/gitea:28.0.0
container_name: "Gitea"
restart: unless-stopped
ipc: private
mac_address: "7e:d9:f5:36:de:80"
network_mode: bridge
ports:
- "2233:22/tcp"
- "3322:3000/tcp"
environment:
- "TZ=Europe/Berlin"
- "DELIVER_TIMEOUT=60"
- "USER=git"
- "GITEA_CUSTOM=/data/gitea"
volumes:
- "/mnt/user/appdata/gitea:/data"
logging:
driver: "json-file"
options:
max-file: "1"
max-size: "50m"
labels:
- traefik.enable=true
- traefik.http.routers.gitea.rule=Host(`gitea.arnoutvw.nl`)
- traefik.http.services.gitea.loadbalancer.server.port=3000
# port/ssl/healthcheck-string values are coerced by pangolin; only the
# region-rule (value=EU, not a valid UN M.49 subregion) was rejected —
# existing resources carry no rules, so none are set via labels.
gitea-runner:
image: gitea/act_runner:0.6.1
container_name: "Gitea-Runner"
restart: unless-stopped
ipc: private
network_mode: bridge
entrypoint: [ "/sbin/tini", "--", "run.sh" ]
environment:
# Registration token for the runner (rotate via gitea admin if leaked).
- "GITEA_RUNNER_REGISTRATION_TOKEN=5tPWewhkKr58gQt0UsSvOvh3E4RPFWV1CIXO7imj"
- "GITEA_INSTANCE_URL=https://gitea.arnoutvw.nl"
- "TZ=Europe/Berlin"
volumes:
- "/mnt/user/appdata/gitea-runner:/data"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
+1 -1
View File
@@ -40,5 +40,5 @@ MACHINE_LEARNING_MAX_BATCH_SIZE__FACIAL_RECOGNITION=1
MACHINE_LEARNING_CACHE_FOLDER=/config/machine-learning/models
MACHINE_LEARNING_MAX_BATCH_SIZE__TEXT_RECOGNITION=3
IMMICH_URL = "http://192.168.10.144:8693" # Your immich instace ip address and port
IMMICH_URL = "http://192.168.10.144:8693"
EXTERNAL_IMMICH_URL = "https://photos.arnoutvw.nl" # External address of immich
+48 -2
View File
@@ -1,4 +1,44 @@
services:
dnsweaver:
# Auto-manages AdGuard (192.168.10.54:3000, primary of the 2 synced
# instances) DNS rewrites for containers carrying traefik router rule
# labels, plus the traefik file-provider rules (fileConfig.yml mount).
# Managed mode: orphan cleanup deletes only records whose type+target
# match (A -> 192.168.10.144), which is why the *.arnoutvw.nl wildcard
# rewrite was removed and every defaultRule-derived hostname (no router
# label on its container) lives as an EXCLUDE_DOMAINS static rewrite.
image: maxamill/dnsweaver:latest
container_name: dnsweaver
restart: unless-stopped
init: true
network_mode: bridge
labels:
- traefik.enable=true
- traefik.http.routers.dnsweaver.rule=Host(`dnsweaver.arnoutvw.nl`)
- traefik.http.services.dnsweaver.loadbalancer.server.port=8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /mnt/user/appdata/traefik/fileConfig.yml:/etc/traefik/fileConfig.yml:ro
environment:
TZ: Europe/Amsterdam
DNSWEAVER_LOG_LEVEL: info
DNSWEAVER_SOURCES: traefik
DNSWEAVER_SOURCE_TRAEFIK_FILE_PATHS: /etc/traefik/fileConfig.yml
DNSWEAVER_INSTANCES: adguard
DNSWEAVER_ADGUARD_TYPE: adguard
DNSWEAVER_ADGUARD_URL: http://192.168.10.54:3000
DNSWEAVER_ADGUARD_USERNAME: arnout
DNSWEAVER_ADGUARD_PASSWORD: ${DNSWEAVER_ADGUARD_PASSWORD}
DNSWEAVER_ADGUARD_MODE: managed
DNSWEAVER_ADGUARD_RECORD_TYPE: A
DNSWEAVER_ADGUARD_TARGET: 192.168.10.144
DNSWEAVER_ADGUARD_ZONE: arnoutvw.nl
DNSWEAVER_ADGUARD_DOMAINS: "*.arnoutvw.nl"
DNSWEAVER_ADGUARD_EXCLUDE_DOMAINS: postgres14.arnoutvw.nl,mariadb.arnoutvw.nl,redis.arnoutvw.nl,postgresql17.arnoutvw.nl,komodo-mongo.arnoutvw.nl,bookorbit-db.arnoutvw.nl,immich_postgres.arnoutvw.nl,immich_machine_learning.arnoutvw.nl,postgres_exporter.arnoutvw.nl,dawarich_db.arnoutvw.nl,dawarich_redis.arnoutvw.nl,dawarich_sidekiq.arnoutvw.nl,influxdb-1.8.arnoutvw.nl,newt.arnoutvw.nl,newt-secondary.arnoutvw.nl,komodo-periphery.arnoutvw.nl,dockersocket.arnoutvw.nl,subsyncarr.arnoutvw.nl,wordpress-blues.arnoutvw.nl
# underscore hostnames (immich_machine_learning, postgres_exporter) are
# invalid DNS labels for dnsweaver — they resolve via the static rewrites
# and their traefik routes work, so they stay excluded instead.
smartctl-exporter:
image: quay.io/prometheuscommunity/smartctl-exporter:v0.14.0
container_name: smartctl-exporter
@@ -11,7 +51,10 @@ services:
- "9633:9633"
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.55.1
container_name: cadvisor
labels:
- traefik.enable=true
- traefik.http.routers.cadvisor.rule=Host(`cadvisor.arnoutvw.nl`)
- traefik.http.services.cadvisor.loadbalancer.server.port=8080
pull_policy: always
restart: unless-stopped
network_mode: bridge
@@ -37,6 +80,9 @@ services:
- "HOST_CONTAINERNAME=prometheus"
image: "prom/prometheus:v3.15.0"
labels:
traefik.enable: "true"
traefik.http.routers.prometheus.rule: Host(`prometheus.arnoutvw.nl`)
traefik.http.services.prometheus.loadbalancer.server.port: "9090"
maintainer: "The Prometheus Authors <prometheus-developers@googlegroups.com>"
net.unraid.docker.icon: "https://raw.githubusercontent.com/selfhosters/unRAID-CA-templates/master/templates/img/prometheus.png"
net.unraid.docker.managed: "dockerman"
@@ -95,4 +141,4 @@ services:
network_mode: "bridge"
volumes:
- "/mnt/user/appdata/autokuma/static_monitors:/static_monitors"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
+44
View File
@@ -0,0 +1,44 @@
# Komodo periphery for Atlas — deliberately SEPARATE from the komodo stack:
# the periphery executes deploys, and a compose child that recreates its own
# parent dies mid-deploy leaving half-created containers
# (see moghtech/komodo discussion #223). Deploys for this stack are manual
# (host docker compose), renovate is disabled for this folder, and the
# update-stacks procedure does not include it.
# Joins the komodo stack's private network so core can resolve "periphery"
name: komodo-periphery
services:
periphery:
image: ghcr.io/moghtech/komodo-periphery:2
container_name: komodo-periphery
restart: unless-stopped
init: true
network_mode: bridge
ports:
- "8120:8120"
logging:
driver: local
env_file: ../komodo/.env
environment:
PERIPHERY_REPO_DIR: ${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}/repos
PERIPHERY_STACK_DIR: ${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}/stacks
PERIPHERY_SSL_KEY_FILE: ${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}/ssl/key.pem
PERIPHERY_SSL_CERT_FILE: ${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}/ssl/cert.pem
volumes:
## Mount external docker socket
- /var/run/docker.sock:/var/run/docker.sock
## Allow Periphery to see processes outside of container
- /proc:/proc
## Specify the Periphery agent root directory - must be the same inside and outside the container.
- ${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}:${PERIPHERY_ROOT_DIRECTORY:-/etc/komodo}
## Custom location for docker compose repo
- /mnt/user/compose:/mnt/user/compose
## v2 PKI private keys (persist)
- /etc/komodo/keys:/config/keys
labels:
komodo.skip: # Prevent Komodo from stopping with StopAllContainers
networks:
komodo-internal:
external: true
name: komodo_komodo-internal
+141
View File
@@ -0,0 +1,141 @@
####################################
# 🦎 KOMODO COMPOSE - VARIABLES 🦎 #
####################################
## These compose variables can be used with all Komodo deployment options.
## Pass these variables to the compose up command using `--env-file komodo/compose.env`.
## Additionally, they are passed to both Komodo Core and Komodo Periphery with `env_file: ./compose.env`,
## so you can pass any additional environment variables to Core / Periphery directly in this file as well.
## Stick to a specific version, or use `latest`
COMPOSE_KOMODO_IMAGE_TAG=2
## DB credentials
KOMODO_DB_USERNAME=admin
KOMODO_DB_PASSWORD=admin
## Configure a secure passkey to authenticate between Core / Periphery.
## Set your time zone for schedules
## https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TZ=Etc/UTC
#=-------------------------=#
#= Komodo Core Environment =#
#=-------------------------=#
## Full variable list + descriptions are available here:
## 🦎 https://github.com/moghtech/komodo/blob/main/config/core.config.toml 🦎
## Note. Secret variables also support `${VARIABLE}_FILE` syntax to pass docker compose secrets.
## Docs: https://docs.docker.com/compose/how-tos/use-secrets/#examples
## Used for Oauth / Webhook url suggestion / Caddy reverse proxy.
KOMODO_HOST=https://komodo.arnoutvw.nl
## Displayed in the browser tab.
KOMODO_TITLE=Komodo
## Create a server matching this address as the "first server".
## Use `https://host.docker.internal:8120` when using systemd-managed Periphery.
KOMODO_FIRST_SERVER=https://192.168.10.144:8120
## Make all buttons just double-click, rather than the full confirmation dialog.
KOMODO_DISABLE_CONFIRM_DIALOG=false
## Rate Komodo polls your servers for
## status / container status / system stats / alerting.
## Options: 1-sec, 5-sec, 15-sec, 1-min, 5-min, 15-min
## Default: 15-sec
KOMODO_MONITORING_INTERVAL="15-sec"
## Interval at which to poll Resources for any updates / automated actions.
## Options: 15-min, 1-hr, 2-hr, 6-hr, 12-hr, 1-day
## Default: 1-hr
KOMODO_RESOURCE_POLL_INTERVAL="1-hr"
## Used to auth incoming webhooks. Alt: KOMODO_WEBHOOK_SECRET_FILE
KOMODO_WEBHOOK_SECRET=a_random_secret
## Used to generate jwt. Alt: KOMODO_JWT_SECRET_FILE
KOMODO_JWT_SECRET=a_random_jwt_secret
## Time to live for jwt tokens.
## Options: 1-hr, 12-hr, 1-day, 3-day, 1-wk, 2-wk
KOMODO_JWT_TTL="1-day"
## Enable login with username + password.
KOMODO_LOCAL_AUTH=true
## Disable new user signups.
KOMODO_DISABLE_USER_REGISTRATION=false
## All new logins are auto enabled
KOMODO_ENABLE_NEW_USERS=false
## Disable non-admins from creating new resources.
KOMODO_DISABLE_NON_ADMIN_CREATE=false
## Allows all users to have Read level access to all resources.
KOMODO_TRANSPARENT_MODE=false
## Prettier logging with empty lines between logs
KOMODO_LOGGING_PRETTY=false
## More human readable logging of startup config (multi-line)
KOMODO_PRETTY_STARTUP_CONFIG=false
## OIDC Login
KOMODO_OIDC_ENABLED=true
## Must reachable from Komodo Core container
KOMODO_OIDC_PROVIDER=https://pass.arnoutvw.nl
## Change the host to one reachable be reachable by users (optional if it is the same as above).
## DO NOT include the `path` part of the URL.
#KOMODO_OIDC_REDIRECT_HOST=https://oidc.provider.external
## Your OIDC client id
KOMODO_OIDC_CLIENT_ID=0a4e7af5-73de-41b3-806f-c6fa6da55929
## Your OIDC client secret.
## If your provider supports PKCE flow, this can be ommitted.
KOMODO_OIDC_CLIENT_SECRET=FNQBmSybrizJmNCsUs4Mxh0BRRZVMhOF
## Make usernames the full email.
## Note. This does not work for all OIDC providers.
# KOMODO_OIDC_USE_FULL_EMAIL=true
## Add additional trusted audiences for token claims verification.
## Supports comma separated list, and passing with _FILE (for compose secrets).
# KOMODO_OIDC_ADDITIONAL_AUDIENCES=abc,123 # Alt: KOMODO_OIDC_ADDITIONAL_AUDIENCES_FILE
## Github Oauth
KOMODO_GITHUB_OAUTH_ENABLED=false
# KOMODO_GITHUB_OAUTH_ID= # Alt: KOMODO_GITHUB_OAUTH_ID_FILE
# KOMODO_GITHUB_OAUTH_SECRET= # Alt: KOMODO_GITHUB_OAUTH_SECRET_FILE
## Google Oauth
KOMODO_GOOGLE_OAUTH_ENABLED=false
# KOMODO_GOOGLE_OAUTH_ID= # Alt: KOMODO_GOOGLE_OAUTH_ID_FILE
# KOMODO_GOOGLE_OAUTH_SECRET= # Alt: KOMODO_GOOGLE_OAUTH_SECRET_FILE
## Aws - Used to launch Builder instances.
KOMODO_AWS_ACCESS_KEY_ID= # Alt: KOMODO_AWS_ACCESS_KEY_ID_FILE
KOMODO_AWS_SECRET_ACCESS_KEY= # Alt: KOMODO_AWS_SECRET_ACCESS_KEY_FILE
#=------------------------------=#
#= Komodo Periphery Environment =#
#=------------------------------=#
## Full variable list + descriptions are available here:
## 🦎 https://github.com/moghtech/komodo/blob/main/config/periphery.config.toml 🦎
## Specify the root directory used by Periphery agent.
PERIPHERY_ROOT_DIRECTORY=/etc/komodo
## Periphery passkeys must include KOMODO_PASSKEY to authenticate.
## Specify whether to disable the terminals feature
## and disallow remote shell access (inside the Periphery container).
PERIPHERY_DISABLE_TERMINALS=false
## Enable SSL using self signed certificates.
## Connect to Periphery at https://address:8120.
PERIPHERY_SSL_ENABLED=true
## If the disk size is overreporting, can use one of these to
## whitelist / blacklist the disks to filter them, whichever is easier.
## Accepts comma separated list of paths.
## Usually whitelisting just /etc/hostname gives correct size.
PERIPHERY_INCLUDE_DISK_MOUNTS=/etc/hostname
# PERIPHERY_EXCLUDE_DISK_MOUNTS=/snap,/etc/repos
## Prettier logging with empty lines between logs
PERIPHERY_LOGGING_PRETTY=false
## More human readable logging of startup config (multi-line)
PERIPHERY_PRETTY_STARTUP_CONFIG=false
PERIPHERY_CORE_PUBLIC_KEYS=MCowBQYDK2VuAyEAoidjxlTRIeVAy0TMF517ZXxAfPgW7IndrOBsQfmKH3M=
+88
View File
@@ -0,0 +1,88 @@
# Komodo (mongo, core, MCP proxy) — moved off Unraid compose-manager into the
# repo so Renovate tracks it. Periphery deliberately lives OUTSIDE this stack
# (komodo-periphery/): the periphery executes deploys, and a compose child
# that recreates its own parent dies mid-deploy leaving orphaned containers
# (see moghtech/komodo discussion #223 — periphery must not be in the Core
# stack). komodo.skip labels prevent StopAllContainers from taking it down.
# Renovate bumps are NOT auto-deployed for this stack — update via host:
# cd /etc/komodo/repos/compose-files/komodo && docker compose up -d
# Exposed via atlas-traefik (LAN) + pangolin primary (internet) blueprint
# labels. .env lives next to this file (env_file for core).
name: komodo
services:
mongo:
image: mongo:9.0
container_name: komodo-mongo
command: --quiet --wiredTigerCacheSizeGB 0.25
restart: unless-stopped
network_mode: bridge
logging:
driver: ${COMPOSE_LOGGING_DRIVER:-local}
volumes:
- /mnt/user/appdata/komodo/mongo/db:/data/db
- /mnt/user/appdata/komodo/mongo/config:/data/configdb
environment:
MONGO_INITDB_ROOT_USERNAME: ${KOMODO_DB_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${KOMODO_DB_PASSWORD}
labels:
komodo.skip: # Prevent Komodo from stopping with StopAllContainers
core:
image: ghcr.io/moghtech/komodo-core:${COMPOSE_KOMODO_IMAGE_TAG:-2}
container_name: komodo-core
restart: unless-stopped
init: true
network_mode: bridge
links:
- mongo
depends_on:
- mongo
logging:
driver: ${COMPOSE_LOGGING_DRIVER:-local}
ports:
- 9120:9120
env_file: ./.env
environment:
KOMODO_DATABASE_ADDRESS: mongo:27017
KOMODO_DATABASE_USERNAME: ${KOMODO_DB_USERNAME}
KOMODO_DATABASE_PASSWORD: ${KOMODO_DB_PASSWORD}
volumes:
## Core cache for repos for latest commit hash / contents
- /mnt/user/appdata/komodo/core/repos:/repo-cache
## v2 PKI keys
- /mnt/user/appdata/komodo/core/keys:/config/keys
labels:
- komodo.skip=true # Prevent Komodo from stopping with StopAllContainers
- traefik.enable=true
- traefik.http.routers.komodo.rule=Host(`komodo.arnoutvw.nl`)
- traefik.http.services.komodo.loadbalancer.server.port=9120
- pangolin.public-resources.komodo.name=Komodo
- pangolin.public-resources.komodo.full-domain=komodo.arnoutvw.nl
- pangolin.public-resources.komodo.protocol=http
- pangolin.public-resources.komodo.ssl=true
- pangolin.public-resources.komodo.targets[0].method=http
- pangolin.public-resources.komodo.targets[0].hostname=192.168.10.144
- pangolin.public-resources.komodo.targets[0].port=9120
- pangolin.public-resources.komodo.targets[0].healthcheck.hostname=192.168.10.144
- pangolin.public-resources.komodo.targets[0].healthcheck.port=9120
- pangolin.public-resources.komodo.targets[0].healthcheck.enabled=true
- pangolin.public-resources.komodo.auth.sso-enabled=false
# ssl defaults on. See gitea note: string-typed labels only.
komodo-mcp:
image: ghcr.io/myrikld/komodo-mcp:latest
container_name: komodo-mcp
init: true
network_mode: bridge
ports:
- "8333:8000"
environment:
- KOMODO_MCP_KOMODO_URL=https://komodo.arnoutvw.nl
- KOMODO_MCP_KOMODO_API_KEY=K-Bui3dtbn4ZEcO4Hv4keHpFRo1p5FI4GEePwVLn6J
- KOMODO_MCP_KOMODO_API_SECRET=S-NWNKyfgZEd6XvnpLxIlH21PJtwdOrb9ebKg9L7K5
restart: unless-stopped
labels:
- traefik.enable=true
- traefik.http.routers.komodomcp.rule=Host(`komodo-mcp.arnoutvw.nl`)
- traefik.http.services.komodomcp.loadbalancer.server.port=8000
+9 -1
View File
@@ -12,6 +12,10 @@ services:
- "STASH_CONFIG_FILE=/root/.stash/config.yml"
- "TZ=Europe/Berlin"
image: "stashapp/stash:v0.31.1"
labels:
- traefik.enable=true
- traefik.http.routers.stash.rule=Host(`stash.arnoutvw.nl`)
- traefik.http.services.stash.loadbalancer.server.port=9999
ipc: "private"
logging:
driver: "json-file"
@@ -44,6 +48,10 @@ services:
- "CacheFilePath=/config/clips.json"
- "ASPNETCORE_URLS=http://+:5000"
image: "ghcr.io/imagegenius/teslacamplayer:2024.8.11.923-ig37"
labels:
- traefik.enable=true
- traefik.http.routers.teslacamplayer.rule=Host(`teslacamplayer.arnoutvw.nl`)
- traefik.http.services.teslacamplayer.loadbalancer.server.port=5000
ipc: "private"
logging:
driver: "json-file"
@@ -57,4 +65,4 @@ services:
volumes:
- "/mnt/cache/appdata/teslacamplayer:/config"
- "/mnt/user/tesla:/media"
working_dir: "/"
working_dir: "/"
+13 -1
View File
@@ -48,6 +48,10 @@ services:
- "ADGUARD_PASSWORDS=${ADGUARD_PASSWORDS}"
- "TZ=Europe/Berlin"
image: "ghcr.io/henrywhitaker3/adguard-exporter:v1.2.1"
labels:
- traefik.enable=true
- traefik.http.routers.adguard-exporter.rule=Host(`adguard-exporter.arnoutvw.nl`)
- traefik.http.services.adguard-exporter.loadbalancer.server.port=9618
ipc: "private"
logging:
driver: "json-file"
@@ -105,6 +109,10 @@ services:
environment:
- "TZ=Europe/Berlin"
image: "quay.io/prometheuscommunity/postgres-exporter:v0.20.1"
labels:
- traefik.enable=true
- traefik.http.routers.postgres_exporter.rule=Host(`postgres_exporter.arnoutvw.nl`)
- traefik.http.services.postgres_exporter.loadbalancer.server.port=9187
ipc: "private"
logging:
driver: "json-file"
@@ -168,6 +176,10 @@ services:
- "GF_SERVER_ROOT_URL=http://grafana.arnoutvw.nl"
- "GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}"
image: "grafana/grafana:13.2.3"
labels:
- traefik.enable=true
- traefik.http.routers.grafana.rule=Host(`grafana.arnoutvw.nl`)
- traefik.http.services.grafana.loadbalancer.server.port=3000
ipc: "private"
logging:
driver: "json-file"
@@ -180,4 +192,4 @@ services:
restart: "unless-stopped"
user: "472"
volumes:
- "/mnt/user/appdata/grafana-latest:/var/lib/grafana"
- "/mnt/user/appdata/grafana-latest:/var/lib/grafana"
+1 -1
View File
@@ -13,7 +13,7 @@ services:
- "N8N_RELEASE_TYPE=stable"
- "NODE_ENV=production"
- "NPM_CONFIG_UPDATE_NOTIFIER=false"
image: "n8nio/n8n:2.41.6"
image: "n8nio/n8n:2.42.3"
ipc: "private"
logging:
driver: "json-file"
+6
View File
@@ -37,6 +37,9 @@ services:
ipc: "private"
labels:
traefik.enable: "true"
traefik.http.routers.adguardhome-sync.rule: Host(`adguardhome-sync.arnoutvw.nl`)
traefik.http.services.adguardhome-sync.loadbalancer.server.port: "8080"
build_version: "Linuxserver.io version:- v0.9.0-ls163 Build-date:- 2026-04-22T08:08:27+00:00"
maintainer: "thespad"
net.unraid.docker.icon: "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/linuxserver-ls-logo.png"
@@ -175,6 +178,9 @@ services:
ipc: "private"
labels:
traefik.enable: "true"
traefik.http.routers.netbootxyz.rule: Host(`netbootxyz.arnoutvw.nl`)
traefik.http.services.netbootxyz.loadbalancer.server.port: "3000"
maintainer: "antonym"
net.unraid.docker.icon: "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/netbootxyz-logo.png"
net.unraid.docker.managed: "dockerman"
+65
View File
@@ -0,0 +1,65 @@
# pangolin-secondary VPS (plex-hetzner) — pangolin edge stack.
# Moved off files_on_host /root/docker-compose.yml into the repo, so Renovate
# can handle updates (config lives on the host at /root/config; mounts are
# absolute paths for that reason — periphery has /root:/root bind-mounted).
# Original: /root/docker-compose.yml (left in place as backup).
name: pangolin
services:
pangolin:
image: docker.io/fosrl/pangolin:ee-1.24.0
container_name: pangolin
restart: unless-stopped
volumes:
- /root/config:/app/config
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3001/api/v1/"]
interval: "10s"
timeout: "10s"
retries: 15
gerbil:
image: docker.io/fosrl/gerbil:1.5.2
container_name: gerbil
restart: unless-stopped
depends_on:
pangolin:
condition: service_healthy
command:
- --reachableAt=http://gerbil:3004
- --generateAndSaveKeyTo=/var/config/key
- --remoteConfig=http://pangolin:3001/api/v1/
volumes:
- /root/config/:/var/config
cap_add:
- NET_ADMIN
- SYS_MODULE
ports:
- 51820:51820/udp
- 21820:21820/udp
- 443:443
- 80:80
- 32400:32400
traefik:
image: docker.io/traefik:v3.7
container_name: traefik
restart: unless-stopped
network_mode: service:gerbil # Ports appear on the gerbil service
depends_on:
pangolin:
condition: service_healthy
command:
- --configFile=/etc/traefik/traefik_config.yml
volumes:
- /root/config/traefik:/etc/traefik:ro # Volume to store the Traefik configuration
- /root/config/letsencrypt:/letsencrypt # Volume to store the Let's Encrypt certificates
- /root/config/traefik/logs:/var/log/traefik # Volume to store Traefik logs
networks:
default:
driver: bridge
name: pangolin
enable_ipv6: true
+241
View File
@@ -0,0 +1,241 @@
# pangolin primary VPS (ionos) — pangolin edge stack.
# Moved off files_on_host /root/docker-compose.yml into the repo, so Renovate
# can handle updates (config lives on the host at /root/config + /root/backups
# etc.; mounts are absolute paths for that reason — systemd periphery has
# direct host access). crowdsec-manager is pointed at the repo-managed
# compose file. Original: /root/docker-compose.yml (left in place as backup).
name: pangolin
networks:
default:
driver: bridge
enable_ipv6: true
name: pangolin
services:
crowdsec:
container_name: crowdsec
environment:
COLLECTIONS: crowdsecurity/traefik crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-generic-rules crowdsecurity/linux crowdsecurity/iptables
ENROLL_INSTANCE_NAME: pangolin-crowdsec
ENROLL_TAGS: docker
GID: "1000"
PARSERS: crowdsecurity/whitelists
healthcheck:
interval: 60s
retries: 15
test:
- CMD
- cscli
- lapi
- status
timeout: 30s
image: docker.io/crowdsecurity/crowdsec:v1.8.1
labels:
- traefik.enable=false
ports:
- 127.0.0.1:6060:6060
- 127.0.0.1:8080:8080
restart: unless-stopped
volumes:
- /root/config/crowdsec:/etc/crowdsec
- /root/config/crowdsec/db:/var/lib/crowdsec/data
- /root/config/traefik/logs:/var/log/traefik
- /var/log/auth.log:/var/log/auth.log:ro
- /var/log/syslog:/var/log/syslog:ro
gerbil:
cap_add:
- NET_ADMIN
- SYS_MODULE
command:
- --reachableAt=http://gerbil:3004
- --generateAndSaveKeyTo=/var/config/key
- --remoteConfig=http://pangolin:3001/api/v1/
container_name: gerbil
depends_on:
pangolin:
condition: service_healthy
image: docker.io/fosrl/gerbil:1.5.2
ports:
- 51820:51820/udp
- 21820:21820/udp
- 443:443
- 80:80
- 32400:32400
- 8082:8082
restart: unless-stopped
volumes:
- /root/config/:/var/config
pangolin:
container_name: pangolin
hostname: pangolin
healthcheck:
interval: 10s
retries: 15
test:
- CMD
- curl
- -f
- http://localhost:3001/api/v1/
timeout: 10s
image: docker.io/fosrl/pangolin:ee-1.24.0
restart: unless-stopped
volumes:
- /root/config:/app/config
traefik:
command:
- --configFile=/etc/traefik/traefik_config.yml
container_name: traefik
depends_on:
crowdsec:
condition: service_healthy
pangolin:
condition: service_healthy
image: docker.io/traefik:v3.7
network_mode: service:gerbil
restart: unless-stopped
environment:
- CF_API_EMAILL=4v792wk2b2@privaterelay.appleid.com
- CF_DNS_API_TOKEN=yt9Q41S9jg92mxpZaWyd6MyOP6Y7OeC5GdUl1tRD
volumes:
- /root/config/traefik:/etc/traefik:ro
- /root/config/letsencrypt:/letsencrypt
- /root/config/traefik/logs:/var/log/traefik
# Traefik Log Dashboard Agent
traefik-agent:
image: hhftechnology/traefik-log-dashboard-agent:latest
restart: unless-stopped
ports:
- "5000:5000"
volumes:
- /root/data/positions:/data
- /root/config/traefik/logs:/logs:ro
- /root/config/maxmind:/geoip:ro
environment:
# Log Paths
- TRAEFIK_LOG_DASHBOARD_ACCESS_PATH=/logs/access.log
- TRAEFIK_LOG_DASHBOARD_ERROR_PATH=/logs/traefik.log
# Authentication
- TRAEFIK_LOG_DASHBOARD_AUTH_TOKEN=VZwCZobpojOAMxJ4X5UGFLebe7WHXiuqCsSE9ahWXzoICTQBVPvXcOP6qVgxczfw
# System Monitoring
- TRAEFIK_LOG_DASHBOARD_SYSTEM_MONITORING=true
# GeoIP Configuration
- TRAEFIK_LOG_DASHBOARD_GEOIP_ENABLED=true
- TRAEFIK_LOG_DASHBOARD_GEOIP_CITY_DB=/geoip/GeoLite2-City.mmdb
- TRAEFIK_LOG_DASHBOARD_GEOIP_COUNTRY_DB=/geoip/GeoLite2-Country.mmdb
# Log Format
- TRAEFIK_LOG_DASHBOARD_LOG_FORMAT=json
# Server Port
- PORT=5000
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5000/api/logs/status"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
# Traefik Log Dashboard - Web UI
traefik-dashboard:
image: hhftechnology/traefik-log-dashboard:latest
container_name: traefik-log-dashboard
restart: unless-stopped
ports:
- "3000:3000"
environment:
# Agent Configuration
- AGENT_API_URL=http://traefik-agent:5000
- AGENT_API_TOKEN=VZwCZobpojOAMxJ4X5UGFLebe7WHXiuqCsSE9ahWXzoICTQBVPvXcOP6qVgxczfw
- NODE_ENV=production
- PORT=3000
depends_on:
traefik-agent:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3000"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
# Optional: MaxMind GeoIP Database Updater
# maxmind-updater:
# image: alpine:latest
# restart: "no"
# volumes:
# - /root/config/maxmind:/data
# environment:
# - MAXMIND_LICENSE_KEY=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
# command: >
# sh -c "
# apk add --no-cache wget tar &&
# cd /data &&
# if [ ! -f GeoLite2-City.mmdb ] || [ \"$(find . -name 'GeoLite2-City.mmdb' -mtime +7)\" ]; then
# echo 'Updating GeoLite2-City database...'
# wget -O GeoLite2-City.tar.gz 'https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&lic...'
# tar --wildcards -xzf GeoLite2-City.tar.gz --strip-components=1 '*/GeoLite2-City.mmdb' &&
# rm -f GeoLite2-City.tar.gz
# fi &&
# if [ ! -f GeoLite2-Country.mmdb ] || [ \"$(find . -name 'GeoLite2-Country.mmdb' -mtime +7)\" ]; then
# echo 'Updating GeoLite2-Country database...'
# wget -O GeoLite2-Country.tar.gz 'https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&lic...'
# tar --wildcards -xzf GeoLite2-Country.tar.gz --strip-components=1 '*/GeoLite2-Country.mmdb' &&
# rm -f GeoLite2-Country.tar.gz
# fi &&
# echo 'GeoIP databases updated successfully.'
# "
prometheus:
container_name: prometheus
image: prom/prometheus:latest
restart: unless-stopped
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--web.route-prefix=/prometheus"
- "--web.external-url=https://powersync.arnoutvw.nl/prometheus"
ports:
- 9090:9090
volumes:
# - /etc/timezone:/etc/timezone:ro
# - /etc/localtime:/etc/localtime:ro
- /root/config/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- /root/config/prometheus/data:/prometheus
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
# dns: ['127.0.0.53', '8.8.8.8']
ports:
- 3003:3000
environment:
GF_SERVER_ROOT_URL: "https://powersync.arnoutvw.nl/grafana"
GF_SERVER_SERVE_FROM_SUBPATH: grafana
volumes:
# - /etc/timezone:/etc/timezone:ro
# - /etc/localtime:/etc/localtime:ro
- /root/config/grafana/data:/var/lib/grafana
crowdsec-manager:
image: hhftechnology/crowdsec-manager:latest
container_name: crowdsec-manager
restart: unless-stopped
ports:
- 8384:8080
environment:
- PORT=8080
- ENVIRONMENT=production
- DOCKER_HOST=unix:///var/run/docker.sock
- COMPOSE_FILE=/app/docker-compose.yml
- PANGOLIN_DIR=/app
- CONFIG_DIR=/app/config
- DATABASE_PATH=/app/data/settings.db
- TRAEFIK_DYNAMIC_CONFIG=/dynamic_config.yml
- TRAEFIK_STATIC_CONFIG=/etc/traefik/traefik_config.yml
- TRAEFIK_ACCESS_LOG=/var/log/traefik/access.log
- TRAEFIK_ERROR_LOG=/var/log/traefik/traefik.log
- CROWDSEC_ACQUIS_FILE=/etc/crowdsec/acquis.yaml
- BACKUP_DIR=/app/backups
- RETENTION_DAYS=60
- INCLUDE_CROWDSEC=false
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /root/config:/app/config
- /etc/komodo/repos/compose-files/pangolin/docker-compose.yml:/app/docker-compose.yml
- /root/backups:/app/backups
- /root/config/traefik/logs:/app/logs
- /root/data:/app/data
- /root/config/traefik/logs:/var/log/traefik
+8 -2
View File
@@ -162,9 +162,12 @@ services:
- "VERSION_TAG=stable"
- "BASE_PATH="
image: "ghcr.io/maintainerr/maintainerr:3.30.0"
image: "ghcr.io/maintainerr/maintainerr:3.30.1"
labels:
traefik.enable: "true"
traefik.http.routers.maintainerr.rule: Host(`maintainerr.arnoutvw.nl`)
traefik.http.services.maintainerr.loadbalancer.server.port: "6246"
Description: "Contains the Maintainerr Docker image"
net.unraid.docker.icon: "https://github.com/jorenn92/Maintainerr/blob/main/ui/public/logo.png?raw=true"
net.unraid.docker.webui: "http://[IP]:[PORT:6246]"
@@ -237,7 +240,10 @@ services:
prom-plex-exporter:
image: ghcr.io/timothystewart6/prometheus-plex-exporter@sha256:90dc0799601c334f2945a3d5b4b552a06352b208a8ce88a428cf90d6c9aa51cd
ports:
labels:
- traefik.enable=true
- traefik.http.routers.prom-plex-exporter.rule=Host(`prom-plex-exporter.arnoutvw.nl`)
- traefik.http.services.prom-plex-exporter.loadbalancer.server.port=9000
- "9403:9000/tcp"
network_mode: "bridge"
restart: always
+1 -1
View File
@@ -27,7 +27,7 @@ services:
- "TRUST_PROXY=true"
- "APP_URL=https://pass.arnoutvw.nl"
- "APP_ENV=production"
image: "ghcr.io/pocket-id/pocket-id:v2.17.0"
image: "ghcr.io/pocket-id/pocket-id:v2.18.0"
ipc: "private"
labels:
traefik.http.routers.pocketid.rule: "Host(`pass.arnoutvw.nl`)"
+3 -3
View File
@@ -1,6 +1,6 @@
services:
postiz:
image: ghcr.io/gitroomhq/postiz-app:v2.24.0
image: ghcr.io/gitroomhq/postiz-app:v2.25.0
container_name: postiz
restart: always
network_mode: bridge
@@ -147,7 +147,7 @@ services:
timeout: 3s
retries: 3
postiz-redis:
image: redis:7.4
image: redis:8.10
container_name: postiz-redis
restart: always
network_mode: bridge
@@ -174,4 +174,4 @@ volumes:
networks:
postiz-network:
external: false
external: false
+7 -1
View File
@@ -24,6 +24,12 @@
"patch"
],
"automerge": true
},
{
"matchFileNames": [
"komodo-periphery/**"
],
"enabled": false
}
]
}
}
+28 -23
View File
@@ -1,13 +1,19 @@
networks:
teslamate:
labels:
- traefik.enable=true
services:
teslamate:
container_name: "teslamate"
image: teslamate/teslamate:4.3.0
restart: always
network_mode: "bridge"
networks:
- teslamate
environment:
- "DATABASE_USER=teslamate"
- "DATABASE_NAME=teslamate"
- "DATABASE_HOST=192.168.10.144"
- "DATABASE_HOST=postgresql17"
- "DATABASE_PASS=${DATABASE_PASS}"
- "DATABASE_PORT=5432"
- "MQTT_HOST=192.168.10.54"
@@ -25,15 +31,16 @@ services:
cap_drop:
- ALL
labels:
traefik.http.routers.teslamate.rule: "Host(`teslamate.arnoutvw.nl`)"
- traefik.enable=true
- traefik.http.routers.teslamate.rule=Host(`teslamate.arnoutvw.nl`)
- traefik.http.services.teslamate.loadbalancer.server.port=4000
postgresql17:
container_name: "postgresql17"
image: postgres:17-alpine3.22
restart: always
network_mode: "bridge"
ports:
- "5432:5432"
networks:
- teslamate
environment:
- "HOST_CONTAINERNAME=postgresql17"
- "POSTGRES_USER=postgres"
@@ -46,13 +53,14 @@ services:
container_name: "teslamate-grafana"
image: teslamate/grafana:4.3.0
restart: always
network_mode: "bridge"
networks:
- teslamate
environment:
- "GF_AUTH_GENERIC_OAUTH_SCOPES=openid profile email"
- "GF_AUTH_GENERIC_OAUTH_TOKEN_URL=https://pass.arnoutvw.nl/api/oidc/token"
- "HOST_OS=Unraid"
- "DATABASE_USER=teslamate"
- "DATABASE_HOST=192.168.10.144"
- "DATABASE_HOST=postgresql17"
- "GF_AUTH_GENERIC_OAUTH_NAME=PocketID"
- "GF_AUTH_GENERIC_OAUTH_ALLOW_SIGN_UP=true"
- "GF_AUTH_DISABLE_LOGIN_FORM=false"
@@ -83,7 +91,9 @@ services:
- "/mnt/cache/appdata/teslamate-customdashboard/Teslamate-CustomGrafanaDashboards/dashboards:/TeslamateCustomDashboards"
- "/mnt/user/appdata/telsamate-grafana:/var/lib/grafana"
labels:
traefik.http.routers.tesla.rule: "Host(`tesla.arnoutvw.nl`)"
- traefik.enable=true
- traefik.http.routers.tesla.rule=Host(`tesla.arnoutvw.nl`)
- traefik.http.services.tesla.loadbalancer.server.port=3000
TeslaMate-ABRP:
container_name: "TeslaMate-ABRP"
@@ -116,7 +126,8 @@ services:
restart: "always"
teslamateapi:
container_name: "teslamateapi"
network_mode: "bridge"
networks:
- teslamate
image: tobiasehlert/teslamateapi:1.25.0
restart: always
environment:
@@ -124,7 +135,7 @@ services:
- DATABASE_USER=teslamate
- "DATABASE_PASS=${DATABASE_PASS}"
- DATABASE_NAME=teslamate
- DATABASE_HOST=192.168.10.144
- DATABASE_HOST=postgresql17
- "MQTT_HOST=192.168.10.54"
- "MQTT_PASSWORD=${MQTT_PASSWORD}"
- "MQTT_TLS_ACCEPT_INVALID_CERTS=true"
@@ -133,12 +144,15 @@ services:
- "MQTT_TLS=false"
- "MQTT_PORT=1883"
- TZ=Europe/Berlin
- TESLAMATE_HOST=192.168.10.144
- TESLAMATE_HOST=teslamate
- TESLAMATE_PORT=4000
- API_TOKEN=826d3b8b-daad-48c7-ad3b-8bdaade8c706
ports:
- 4001:8080
labels:
- traefik.enable=true
- traefik.http.routers.teslamateapi.rule=Host(`teslamateapi.arnoutvw.nl`)
- traefik.http.services.teslamateapi.loadbalancer.server.port=8080
- pangolin.proxy-resources.teslamateapi.name=teslamateapi
- pangolin.proxy-resources.teslamateapi.full-domain=teslamateapi.arnoutvw.nl
- pangolin.proxy-resources.teslamateapi.protocol=http
@@ -150,15 +164,6 @@ services:
- pangolin.proxy-resources.teslamateapi.targets[0].healthcheck.port=4001
- pangolin.proxy-resources.teslamateapi.targets[0].healthcheck.enabled=true
- pangolin.proxy-resources.teslamateapi.auth.sso-enabled=false
- pangolin.proxy-resources.teslamateapi.rules[0].match=region
- pangolin.proxy-resources.teslamateapi.rules[0].match=ip
- pangolin.proxy-resources.teslamateapi.rules[0].action=allow
- pangolin.proxy-resources.teslamateapi.rules[0].value=EU
- pangolin.proxy-resources.teslamateapi.rules[1].match=ip
- pangolin.proxy-resources.teslamateapi.rules[1].action=allow
- pangolin.proxy-resources.teslamateapi.rules[1].value=172.21.0.1
- pangolin.proxy-resources.teslamateapi.rules[2].match=ip
- pangolin.proxy-resources.teslamateapi.rules[2].action=allow
- pangolin.proxy-resources.teslamateapi.rules[2].value=212.227.105.183
- pangolin.proxy-resources.teslamateapi.rules[3].match=country
- pangolin.proxy-resources.teslamateapi.rules[3].action=deny
- pangolin.proxy-resources.teslamateapi.rules[3].value=ALL
- pangolin.proxy-resources.teslamateapi.rules[0].value=172.21.0.1
+25 -1
View File
@@ -10,6 +10,10 @@ services:
- "cloudcmd_terminal_path=gritty"
- "cloudcmd_open=false"
image: "coderaiser/cloudcmd:19.21.1"
labels:
- traefik.enable=true
- traefik.http.routers.cloudcommander.rule=Host(`cloudcommander.arnoutvw.nl`)
- traefik.http.services.cloudcommander.loadbalancer.server.port=8000
ipc: "private"
logging:
driver: "json-file"
@@ -42,6 +46,10 @@ services:
- "CA_TS_FALLBACK_DIR=/app/Data"
- "DOTNET_CLI_TELEMETRY_OPTOUT=true"
image: "revenz/fileflows:26.09"
labels:
- traefik.enable=true
- traefik.http.routers.fileflows.rule=Host(`fileflows.arnoutvw.nl`)
- traefik.http.services.fileflows.loadbalancer.server.port=5000
ipc: "private"
logging:
driver: "json-file"
@@ -85,6 +93,10 @@ services:
- "SUP_GROUP_IDS="
- "KEEP_APP_RUNNING=0"
image: "jlesage/qdirstat:v26.09.1"
labels:
- traefik.enable=true
- traefik.http.routers.qdirstat.rule=Host(`qdirstat.arnoutvw.nl`)
- traefik.http.services.qdirstat.loadbalancer.server.port=5800
ipc: "private"
logging:
driver: "json-file"
@@ -169,6 +181,10 @@ services:
- "TERM=xterm"
- "LANG=en_GB.UTF-8"
image: "ghcr.io/binhex/arch-krusader:2.9.0-2-01"
labels:
- traefik.enable=true
- traefik.http.routers.binhex-krusader.rule=Host(`binhex-krusader.arnoutvw.nl`)
- traefik.http.services.binhex-krusader.loadbalancer.server.port=6080
ipc: "private"
logging:
driver: "json-file"
@@ -243,6 +259,10 @@ services:
- "DUPLICATI__WEBSERVICE_INTERFACE=any"
- "DUPLICATI__WEBSERVICE_ALLOWED_HOSTNAMES=*"
image: "linuxserver/duplicati:v2.4.0.0_stable_2026-09-03-ls310"
labels:
- traefik.enable=true
- traefik.http.routers.duplicati.rule=Host(`duplicati.arnoutvw.nl`)
- traefik.http.services.duplicati.loadbalancer.server.port=8200
ipc: "private"
logging:
driver: "json-file"
@@ -285,6 +305,10 @@ services:
- "DISABLE_DRI3=false"
- "DISABLE_ZINK=false"
image: "lscr.io/linuxserver/chrome:154.0.8037.97-1-ls127"
labels:
- traefik.enable=true
- traefik.http.routers.chrome.rule=Host(`chrome.arnoutvw.nl`)
- traefik.http.services.chrome.loadbalancer.server.port=3000
ipc: "private"
logging:
driver: "json-file"
@@ -298,4 +322,4 @@ services:
restart: "unless-stopped"
volumes:
- "/mnt/cache/appdata/chrome:/config"
working_dir: "/"
working_dir: "/"
@@ -0,0 +1,18 @@
# Attaches the Atlas traefik (container_name "traefik", dockerman) to the
# docker networks of any container labelled `traefik.enable=true`, so stacks
# can use their own private compose network instead of sharing the default
# bridge with traefik. https://github.com/obeone/traefik_network_connector
# No version tags published yet — only :latest.
services:
traefik-network-connector:
image: ghcr.io/obeone/traefik_network_connector:latest
container_name: traefik-network-connector
restart: unless-stopped
init: true
network_mode: bridge
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
TZ: Europe/Amsterdam
TRAEFIK_CONTAINERNAME: traefik
LOGLEVEL: INFO
@@ -0,0 +1,20 @@
# traefik-network-watcher — sh-script vervanging voor TNC
# (github.com/obeone/traefik_network_connector): koppelt traefik aan elk
# docker-netwerk met label traefik.enable=true, daemon-side filtering,
# periodieke resync (5 min) + traefik-restart herstel.
services:
traefik-network-watcher:
image: docker:28-cli
container_name: traefik-network-watcher
restart: unless-stopped
init: true
network_mode: bridge
entrypoint: ["/bin/sh", "/usr/local/bin/handler.sh"]
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./handler.sh:/usr/local/bin/handler.sh:ro
environment:
TZ: Europe/Amsterdam
TRAEFIK_CONTAINER: traefik
SYNC_INTERVAL: "300"
DETACH_UNLABELED: "false"
+129
View File
@@ -0,0 +1,129 @@
#!/bin/sh
#
# traefik-network-watcher
# Koppelt Traefik automatisch aan elke Docker-network die het label
# "traefik.enable=true" draagt. De filtering gebeurt daemon-side
# (docker network ls --filter label=...), dus zonder label gebeurt er
# niets: geen inspect-call, geen connect.
#
# Gedrag:
# - bij opstart: eenmalige scan over alle netwerken met het label
# - live: reactie op Docker-events (network create/connect)
# - herstelt zichzelf als de Traefik-container opnieuw opgestart wordt
# - optioneel: periodieke resync (SYNC_INTERVAL, standaard 300s)
# - optioneel: detachen van netwerken die het label verloren hebben
# (DETACH_UNLABELED=true, standaard uit)
#
set -u
TRAEFIK="${TRAEFIK_CONTAINER:-traefik}"
LABEL_SELECTOR="${TRAEFIK_NETWORK_LABEL:-label=traefik.enable=true}"
EXCLUDED="${EXCLUDED_NETWORKS:-bridge host none ingress docker_gwbridge}"
SYNC_INTERVAL="${SYNC_INTERVAL:-300}"
DETACH_UNLABELED="${DETACH_UNLABELED:-false}"
log() { echo "[watcher] $*"; }
warn() { echo "[watcher] $*" >&2; }
is_excluded() {
for n in $EXCLUDED; do
[ "$1" = "$n" ] && return 0
done
return 1
}
is_labeled() {
# True alleen als de daemon zelf dit netwerk met het label teruggeeft.
# Dit is de single source of truth; nergens anders wordt op het label
# gecontroleerd of geparst.
[ "$(docker network ls --filter "name=^$1\$" --filter "$LABEL_SELECTOR" --format '{{.Name}}')" = "$1" ]
}
networks_of() {
docker inspect "$TRAEFIK" --format \
'{{range $name, $_ := .NetworkSettings.Networks}}{{$name}}
{{end}}' 2>/dev/null
}
is_connected() {
networks_of | grep -qxF "$1"
}
attach() {
net="$1"
is_excluded "$net" && return 0
is_connected "$net" && return 0
log "attach: $TRAEFIK -> $net"
docker network connect "$net" "$TRAEFIK" >/dev/null 2>&1 || warn "attach $net mislukt"
}
detach() {
net="$1"
is_excluded "$net" && return 0
is_connected "$net" || return 0
log "detach: $TRAEFIK -/- $net"
docker network disconnect "$net" "$TRAEFIK" >/dev/null 2>&1 || warn "detach $net mislukt"
}
sync() {
# Alles met het label verbinden (idempotent, connect-check zit in attach)
docker network ls --filter "$LABEL_SELECTOR" --format '{{.Name}}' | while read -r net; do
attach "$net"
done
# Optioneel: alles zonder label weer loskoppelen
if [ "$DETACH_UNLABELED" = "true" ]; then
networks_of | while read -r net; do
is_excluded "$net" && continue
is_labeled "$net" || detach "$net"
done
fi
}
# --- opstart ------------------------------------------------------------
docker inspect "$TRAEFIK" >/dev/null 2>&1 || {
warn "container '$TRAEFIK' niet gevonden; restart:unless-stopped probeert het opnieuw";
exit 1;
}
log "traefik='$TRAEFIK' label-selector='$LABEL_SELECTOR' sync-interval=${SYNC_INTERVAL}s"
if [ "$SYNC_INTERVAL" != "0" ]; then
(
while :; do
sleep "$SYNC_INTERVAL"
sync
done
) &
SYNC_PID=$!
trap 'kill "$SYNC_PID" 2>/dev/null; exit 0' INT TERM
fi
# 1. bestaande netwerken nalopen
log "eerste scan..."
sync
# 2. live events volgen
# - network create/connect -> label-check op het betrokken netwerk,
# connect = connect (handmatige detaches worden ook gerepareerd)
# - container start (traefik zelf) -> volledige resync, zo herstellen
# de koppelingen na een 'docker compose up -d' van de traefik-stack,
# omdat die het container-object vernieuwt en alle endpoints wist
docker events \
--filter type=network \
--filter type=container \
--format '{{.Type}} {{.Action}} {{.Actor.Attributes.name}}' |
while read -r type action name; do
case "$type:$action" in
network:create | network:connect)
is_labeled "$name" && attach "$name"
;;
container:start)
if [ "$name" = "$TRAEFIK" ]; then
log "traefik opnieuw gestart, resync"
sync
fi
;;
esac
done
+2
View File
@@ -5,6 +5,8 @@ services:
network_mode: bridge
labels:
- traefik.http.routers.vaults3.rule=Host(`s3.arnoutvw.nl`)
- traefik.http.routers.vaults3-name.rule=Host(`vaults3.arnoutvw.nl`)
- traefik.http.services.vaults3-name.loadbalancer.server.port=9000
- pangolin.proxy-resources.vaults3.name=vaults3
- pangolin.proxy-resources.vaults3.full-domain=s3.arnoutvw.nl
- pangolin.proxy-resources.vaults3.protocol=http