feat(nodes): remote ingress via Traefik file provider

Remote replicas publish an ephemeral host port; the agent reports the
assigned binding back in the create_container result and the backend
renders a per-service file-provider config into TRAEFIK_DYNAMIC_DIR
pointing Traefik at the node's mesh IP + port. Routes are rewritten on
every remote reconcile and removed on teardown or local placement.

Also: RetireService retires remote leftovers when a service returns to
local placement; remove_container is idempotent agent-side; tombstoned
replicas skip remove dispatch; the domains-stay-local ceiling is gone.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-10-09 18:19:08 +02:00
1 parent 4458de56b0
commit c3a35081d0
13 files changed
+374 -39

No files matched your search

+8 -2
View File
@@ -7,7 +7,8 @@ services:
- "--api.insecure=${TRAEFIK_API_INSECURE:-true}"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.file.filename=/etc/traefik/traefik-dynamic.yml"
- "--providers.file.directory=/traefik-dynamic"
- "--providers.file.watch=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.traefik.address=:8080"
@@ -26,7 +27,8 @@ services:
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ../data/letsencrypt:/letsencrypt
- ./traefik-dynamic.yml:/etc/traefik/traefik-dynamic.yml:ro
- traefik_dynamic:/traefik-dynamic
- ./traefik-dynamic.yml:/traefik-dynamic/00-base.yml:ro
networks:
- containr-network
restart: unless-stopped
@@ -100,6 +102,7 @@ services:
- JWT_SECRET=${JWT_SECRET:-dev_jwt_secret_key_change_in_production}
- CONTAINR_AGENT_AUTH_TOKEN=${CONTAINR_AGENT_AUTH_TOKEN:-}
- CONTAINR_AGENT_AUTH_TOKENS=${CONTAINR_AGENT_AUTH_TOKENS:-}
- TRAEFIK_DYNAMIC_DIR=/traefik-dynamic
- COOKIE_SECURE=${COOKIE_SECURE:-true}
- TRUSTED_PROXY_CIDR=${TRUSTED_PROXY_CIDR:-172.20.0.0/16}
- CORS_ORIGINS=${CORS_ORIGINS:-http://localhost,http://localhost:3000}
@@ -136,6 +139,7 @@ services:
- GITEA_BASE_URL=${GITEA_BASE_URL:-https://gitea.example.com}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- traefik_dynamic:/traefik-dynamic
group_add:
- "${DOCKER_GID:-0}"
networks:
@@ -213,6 +217,8 @@ volumes:
driver: local
dragonfly_data:
driver: local
traefik_dynamic:
driver: local
networks:
containr-network: