Summary
In my setup, Middleware Manager is configured to use standalone Traefik with active_data_source=traefik and no Pangolin present.
Codex found that GET /api/v1/traefik-config still appears to go through Pangolin fetch logic and returns 500 Internal Server Error when Pangolin is absent, even though Traefik itself is reachable and the loaded plugins are active.
This causes Traefik's HTTP provider to stay in a retry loop and makes the Middleware Manager state misleading.
Environment
- Middleware Manager:
v4.5.0
- Traefik:
v3.6.12
- Deployment mode: standalone Traefik
- Active data source in config/UI:
traefik
- Pangolin: not present in my setup
Traefik compose.yaml from my setup
services:
traefik:
container_name: traefik
image: traefik:v3.6.12@sha256:171c9c3565b29f6c133f1c1b43c5d4e5853415198e9e1078c001f8702ff66aec
logging:
driver: "json-file"
options:
max-file: "10"
max-size: "100m"
restart: unless-stopped
# Network
networks:
smoonet:
# Ports (host binding)
ports:
- "443:443/tcp" # HTTPS
- "444:444/tcp" # TCP (your custom)
- "8080:8080/tcp" # Dashboard
- "80:80/tcp" # HTTP
- "81:81/tcp" # Additional HTTP
# Volumes
volumes:
- /mnt/user/appdata/traefik:/etc/traefik # Config, certs, acme.json
# Environment variables
environment:
- CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN} # Cloudflare API token (sensitive!)
- DOCKER_HOST=tcp://dockerproxy:2375 # Docker socket proxy
- HOST_CONTAINERNAME=traefik
- HOST_HOSTNAME=smooRAID
- HOST_OS=Unraid
- TZ=Europe/Berlin
# Resource limits
deploy:
resources:
limits:
pids: 2048
## Start Traefik Config
labels:
- traefik.enable=true
- traefik.http.middlewares.crowdsec-bouncer.plugin.bouncer.enabled=true
- traefik.http.middlewares.crowdsec-bouncer.plugin.bouncer.crowdsecmode=stream
- traefik.http.middlewares.crowdsec-bouncer.plugin.bouncer.crowdseclapischeme=http
- traefik.http.middlewares.crowdsec-bouncer.plugin.bouncer.crowdseclapihost=crowdsec:8080
- traefik.http.middlewares.crowdsec-bouncer.plugin.bouncer.crowdseclapipath=/
- traefik.http.middlewares.crowdsec-bouncer.plugin.bouncer.crowdseclapikey=${CROWDSEC_TRAEFIK_BOUNCER_API_KEY}
- traefik.http.middlewares.crowdsec-bouncer.plugin.bouncer.forwardedheaderstrustedips=${CROWDSEC_FORWARDED_HEADERS_TRUSTED_IPS}
# # Internal
- traefik.http.routers.${SERVICE}-internal.entrypoints=websecure-internal
- traefik.http.routers.${SERVICE}-internal.middlewares=chain-internal@file
- traefik.http.routers.${SERVICE}-internal.priority=5000
- traefik.http.routers.${SERVICE}-internal.rule=Host(`${TRAEFIK_EXTERNAL_URL}`)
- traefik.http.routers.${SERVICE}-internal.service=${SERVICE}
- traefik.http.routers.${SERVICE}-internal.tls=true
# # External
- traefik.http.routers.${SERVICE}-external.entrypoints=websecure-external
- traefik.http.routers.${SERVICE}-external.middlewares=chain-external@file
- traefik.http.routers.${SERVICE}-external.priority=10
- traefik.http.routers.${SERVICE}-external.rule=Host(`${TRAEFIK_EXTERNAL_URL}`)
- traefik.http.routers.${SERVICE}-external.service=${SERVICE}
- traefik.http.routers.${SERVICE}-external.tls=true
# # HTTP-Header
- traefik.http.routers.${SERVICE}-bypass.entrypoints=websecure-external
- traefik.http.routers.${SERVICE}-bypass.middlewares=chain-external-bypass@file
- traefik.http.routers.${SERVICE}-bypass.priority=2500
- traefik.http.routers.${SERVICE}-bypass.rule=Host(`${TRAEFIK_EXTERNAL_URL}`) && Header(`${SPECIAL_HEADER_NAME}`, `${SPECIAL_HEADER_SECRET}`)
- traefik.http.routers.${SERVICE}-bypass.service=${SERVICE}
- traefik.http.routers.${SERVICE}-bypass.tls=true
# Service port (must match the port Komodo listens on INSIDE the container)
- traefik.docker.network=smoonet
- traefik.http.services.${SERVICE}.loadbalancer.server.url=${TRAEFIK_INTERNAL_URL}
## End Traefik Config
- com.smoochy.komodo.restore_stack=traefik
- net.unraid.docker.icon=https://raw.githubusercontent.com/ibracorp/unraid-templates/master/traefik/traefik.png
- net.unraid.docker.webui=${TRAEFIK_INTERNAL_URL}
geoipupdate:
container_name: geoipupdate
image: ghcr.io/maxmind/geoipupdate:v7.1.1@sha256:faecdca22579730ab0b7dea5aa9af350bb3c93cb9d39845c173639ead30346d2
restart: unless-stopped
# Network
networks:
smoonet:
# Volumes
volumes:
- /mnt/user/appdata/traefik-dashboard/data/geoip/:/usr/share/GeoIP:rw
# Environment variables
environment:
- GEOIPUPDATE_ACCOUNT_ID=${GEOIPUPDATE_ACCOUNT_ID}
- GEOIPUPDATE_EDITION_IDS=GeoLite2-City GeoLite2-Country
- GEOIPUPDATE_FREQUENCY=24
- GEOIPUPDATE_LICENSE_KEY=${GEOIPUPDATE_LICENSE_KEY}
- HOST_CONTAINERNAME=geoipupdate
- HOST_HOSTNAME=smooRAID
- HOST_OS=Unraid
- TZ=Europe/Berlin
# Resource limits
deploy:
resources:
limits:
pids: 2048
labels:
- com.smoochy.komodo.restore_stack=traefik
- net.unraid.docker.icon=https://raw.githubusercontent.com/tritones/unraid-templates/main/templates/img/geoipupdate.png
traefik-middleware-manager:
container_name: traefik-middleware-manager
image: hhftechnology/middleware-manager:v4.5.0@sha256:96099c3e069f24800e9b7f8ffa43e359b90c54d73961681825fd51d3cfdc1e49
restart: unless-stopped
# Network
networks:
smoonet:
# Ports
ports:
- "3456:3456/tcp" # Middleware Manager UI
# Volumes
volumes:
- /mnt/user/appdata/traefik/middleware-manager/data:/data:rw
- /mnt/user/appdata/traefik/middleware-manager/config:/app/config:rw
- /mnt/user/appdata/traefik/rules:/conf:rw
- /mnt/user/appdata/traefik:/etc/traefik:rw
# Environment variables
environment:
- ACTIVE_DATA_SOURCE=traefik
- DB_PATH=/data/middleware.db
- HOST_CONTAINERNAME=${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}
- HOST_HOSTNAME=smooRAID
- HOST_OS=Unraid
- PORT=3456
- TRAEFIK_API_URL=http://traefik:8080
- TRAEFIK_CONF_DIR=/conf
- TRAEFIK_STATIC_CONFIG_PATH=/etc/traefik/traefik.yml
- TZ=Europe/Berlin
# Resource limits
deploy:
resources:
limits:
pids: 2048
## Start Traefik Config
labels:
- traefik.enable=true
# # Internal
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-internal.entrypoints=websecure-internal
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-internal.middlewares=chain-internal@file
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-internal.priority=5000
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-internal.rule=Host(`${TRAEFIK_MIDDLEWARE_MANAGER_EXTERNAL_URL}`)
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-internal.service=${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-internal.tls=true
# # External
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-external.entrypoints=websecure-external
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-external.middlewares=chain-external@file
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-external.priority=10
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-external.rule=Host(`${TRAEFIK_MIDDLEWARE_MANAGER_EXTERNAL_URL}`)
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-external.service=${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-external.tls=true
# # HTTP-Header
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-bypass.entrypoints=websecure-external
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-bypass.middlewares=chain-external-bypass@file
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-bypass.priority=2500
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-bypass.rule=Host(`${TRAEFIK_MIDDLEWARE_MANAGER_EXTERNAL_URL}`) && Header(`${SPECIAL_HEADER_NAME}`, `${SPECIAL_HEADER_SECRET}`)
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-bypass.service=${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}
- traefik.http.routers.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}-bypass.tls=true
# Service port (Middleware Manager runs on 3456)
- traefik.docker.network=smoonet
- traefik.http.services.${TRAEFIK_MIDDLEWARE_MANAGER_SERVICE}.loadbalancer.server.url=${TRAEFIK_MIDDLEWARE_MANAGER_INTERNAL_URL}
## End Traefik Config
- com.smoochy.komodo.restore_stack=traefik
- net.unraid.docker.icon=https://github.com/hhftechnology.png
- net.unraid.docker.webui=${TRAEFIK_MIDDLEWARE_MANAGER_INTERNAL_URL}
traefik-log-dashboard:
container_name: traefik-log-dashboard
depends_on:
- traefik
- traefik-log-dashboard-agent
image: hhftechnology/traefik-log-dashboard:3.0.0@sha256:b9a8e6a3a2d7261526975beac67e605111f0d03aedf646016d9d230bef24c016
restart: unless-stopped
# Network
networks:
smoonet:
# Ports
ports:
- "5101:3000/tcp" # Dashboard UI
# Volumes
volumes:
- /mnt/user/appdata/traefik-dashboard/data/dashboard/:/data:rw
- /mnt/user/appdata/traefik-dashboard/data/geoip/:/geoip:ro
# Environment variables
environment:
- AGENT_1_NAME=smooRaid
- AGENT_1_TOKEN=${TRAEFIK_LOG_AGENT_TOKEN}
- AGENT_1_URL=http://traefik-log-dashboard-agent:5000
- DASHBOARD_AGENTS_ENV_ONLY=true
- DASHBOARD_MAX_LOGS_DISPLAY=500
- GEOIP_LOCAL_DB_PATH=/geoip/GeoLite2-City.mmdb
# Accounts are not free, hence disabled
#- GEOIP_PROVIDER_URLS=https://ipwho.is,https://ip-api.com/json
- GEOIP_UNKNOWN_CACHE_TTL_MS=300000
- HOST_CONTAINERNAME=traefik-log-dashboard
- HOST_HOSTNAME=smooRAID
- HOST_OS=Unraid
- NODE_ENV=production
- TZ=Europe/Berlin
# Resource limits
deploy:
resources:
limits:
pids: 2048
## Start Traefik Config (only for dashboard)
labels:
- traefik.enable=true
# # Internal
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-internal.entrypoints=websecure-internal
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-internal.middlewares=chain-internal@file
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-internal.priority=5000
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-internal.rule=Host(`${TRAEFIK_LOG_DASHBOARD_EXTERNAL_URL}`)
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-internal.service=${TRAEFIK_LOG_DASHBOARD_SERVICE}
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-internal.tls=true
# # External
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-external.entrypoints=websecure-external
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-external.middlewares=chain-external@file
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-external.priority=10
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-external.rule=Host(`${TRAEFIK_LOG_DASHBOARD_EXTERNAL_URL}`)
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-external.service=${TRAEFIK_LOG_DASHBOARD_SERVICE}
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-external.tls=true
# # HTTP-Header
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-bypass.entrypoints=websecure-external
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-bypass.middlewares=chain-external-bypass@file
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-bypass.priority=2500
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-bypass.rule=Host(`${TRAEFIK_LOG_DASHBOARD_EXTERNAL_URL}`) && Header(`${SPECIAL_HEADER_NAME}`, `${SPECIAL_HEADER_SECRET}`)
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-bypass.service=${TRAEFIK_LOG_DASHBOARD_SERVICE}
- traefik.http.routers.${TRAEFIK_LOG_DASHBOARD_SERVICE}-bypass.tls=true
# Service port (dashboard runs on 3000)
- traefik.docker.network=smoonet
- traefik.http.services.${TRAEFIK_LOG_DASHBOARD_SERVICE}.loadbalancer.server.url=${TRAEFIK_LOG_DASHBOARD_INTERNAL_URL}
## End Traefik Config
- com.smoochy.komodo.restore_stack=traefik
- net.unraid.docker.icon=https://github.com/user-attachments/assets/e6cf097b-2232-4c2c-ba55-5de780724aed
- net.unraid.docker.webui=${TRAEFIK_LOG_DASHBOARD_INTERNAL_URL}/dashboard
traefik-log-dashboard-agent:
container_name: traefik-log-dashboard-agent
image: hhftechnology/traefik-log-dashboard-agent:3.0.0@sha256:aa75766b9235bf9d8d28f4dd3b1e0902ce589b10386221d43e7eab6f19ce7e57
restart: unless-stopped
# Network
networks:
smoonet:
# Ports (internal API)
ports:
- "5100:5000/tcp"
# Volumes
volumes:
- /mnt/user/appdata/traefik-dashboard/data/positions/:/data:rw
- /mnt/user/appdata/traefik/logs/:/logs:ro
# Environment variables
environment:
- HOST_CONTAINERNAME=traefik-log-dashboard-agent
- HOST_HOSTNAME=smooRAID
- HOST_OS=Unraid
- TRAEFIK_LOG_DASHBOARD_ACCESS_PATH=/logs/access.log
- TRAEFIK_LOG_DASHBOARD_AUTH_TOKEN=${TRAEFIK_LOG_AGENT_TOKEN}
- TRAEFIK_LOG_DASHBOARD_ERROR_PATH=/logs/traefik.log
- TRAEFIK_LOG_DASHBOARD_LOG_FORMAT=json
- TRAEFIK_LOG_DASHBOARD_SYSTEM_MONITORING=true
- TZ=Europe/Berlin
# Resource limits
deploy:
resources:
limits:
pids: 2048
labels:
- com.smoochy.komodo.restore_stack=traefik
- net.unraid.docker.icon=https://github.com/user-attachments/assets/e6cf097b-2232-4c2c-ba55-5de780724aed
networks:
smoonet:
external: true
Steps to reproduce
- Run Middleware Manager with standalone Traefik.
- Set
active_data_source to traefik.
- Do not include Pangolin in the stack.
- Request
GET /api/v1/traefik-config.
Actual behavior
The endpoint returns 500 Internal Server Error and tries to contact Pangolin:
{
"error": "Failed to get Traefik configuration",
"details": "failed to fetch Pangolin config: HTTP request failed: Get \"http://pangolin:3001/api/v1/traefik-config\": dial tcp: lookup pangolin on 127.0.0.11:53: no such host"
}
At the same time, in my setup:
config.json contains "active_data_source": "traefik"
- the Traefik API is reachable
- Traefik successfully loads the plugins Codex originally investigated
- Traefik logs show repeated HTTP provider retries because Middleware Manager keeps returning
500
Expected behavior
When active_data_source is traefik:
/api/v1/traefik-config should not depend on Pangolin
- Middleware Manager should build and serve the standalone Traefik config path without attempting to contact
PANGOLIN_API_URL
- Traefik's HTTP provider should receive
200 OK
Likely root cause
Based on source inspection, ConfigProxy.GetMergedConfig() appears to always call fetchPangolinConfig() instead of switching behavior based on the active data source.
If that reading is correct, standalone Traefik mode is configurable in the UI/config file, but the proxy endpoint still remains Pangolin-dependent.
Suggested direction
Make the config proxy data-source-aware:
- keep the existing Pangolin fetch/merge path for
pangolin
- for
traefik, generate the config from Middleware Manager's standalone Traefik path without requiring Pangolin
Transparency notice
This issue text was prepared with AI-assisted analysis based on live runtime logs and source inspection.
Summary
In my setup, Middleware Manager is configured to use standalone Traefik with
active_data_source=traefikand no Pangolin present.Codex found that
GET /api/v1/traefik-configstill appears to go through Pangolin fetch logic and returns500 Internal Server Errorwhen Pangolin is absent, even though Traefik itself is reachable and the loaded plugins are active.This causes Traefik's HTTP provider to stay in a retry loop and makes the Middleware Manager state misleading.
Environment
v4.5.0v3.6.12traefikTraefik
compose.yamlfrom my setupSteps to reproduce
active_data_sourcetotraefik.GET /api/v1/traefik-config.Actual behavior
The endpoint returns
500 Internal Server Errorand tries to contact Pangolin:{ "error": "Failed to get Traefik configuration", "details": "failed to fetch Pangolin config: HTTP request failed: Get \"http://pangolin:3001/api/v1/traefik-config\": dial tcp: lookup pangolin on 127.0.0.11:53: no such host" }At the same time, in my setup:
config.jsoncontains"active_data_source": "traefik"500Expected behavior
When
active_data_sourceistraefik:/api/v1/traefik-configshould not depend on PangolinPANGOLIN_API_URL200 OKLikely root cause
Based on source inspection,
ConfigProxy.GetMergedConfig()appears to always callfetchPangolinConfig()instead of switching behavior based on the active data source.If that reading is correct, standalone Traefik mode is configurable in the UI/config file, but the proxy endpoint still remains Pangolin-dependent.
Suggested direction
Make the config proxy data-source-aware:
pangolintraefik, generate the config from Middleware Manager's standalone Traefik path without requiring PangolinTransparency notice
This issue text was prepared with AI-assisted analysis based on live runtime logs and source inspection.