Traefik Dashboard 404 when running on Custom Port?

I'm trying to get Traefik running on a Server with the Dashboard on a custom Port.
This is more in the "Spirit" like Caddy does, typically 1 Proxy Instance per each Application.

On the same Server (bound to a different IPv6 Address), another Traefik Container can be reached without any Issues on Port 443 (Redirect Port 80 -> 443 is also in Place).

Now I tried to use the same config with just the following Changes:

  • Changed Hostname in Rule
  • Port changed from 80 -> 8080
  • Port changed from 443 -> 8443
  • Disabled Docker Provider
  • Changed from using a traefik Network to Podman's pasta Driver (and removed Label=traefik.docker.network=traefik in Traefik .container File)

After this, I just get a 404 error when visiting the new Domain.

Is there a known Issue when running Traefik Dashboard on Ports different than 80 and 443 ?

These Dashboard Issues are really annoying, Traefik must be better at providing meaningful Errors/Warnings in the Logs !

Share your full Traefik static and dynamic config, and Docker compose file(s) if used.

Podman Pod:

[Install]
WantedBy=default.target

[Pod]
PodName=authentik

# HTTP & HTTPS Ports
PublishPort=[2aXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX]:80:80/tcp
PublishPort=[2aXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX]:443:443/tcp
PublishPort=[2aXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX]:443:443/udp

# Traefik Dashboard on custom Port
PublishPort=[2aXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX]:8080:8080/tcp
PublishPort=[2aXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX]:8443:8443/tcp

# LDAP over SSL/TLS Ports
PublishPort=[2aXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX]:636:636/tcp

Podman Quadlet authentik-traefik.container:

[Service]
Restart=always

[Install]
WantedBy=default.target

[Container]
ContainerName=authentik-traefik

Pod=authentik.pod
StartWithPod=true
     
Exec=\
     --log.level=DEBUG \
     --log.filePath=/log/server/traefik.log \
     --accesslog=true \
     --accesslog.filePath=/log/access/access.log \
     --api \
     --api.insecure=false \
     --api.dashboard=true \
     --entryPoints.web.address=:8080 \
     --entryPoints.web.http.redirections.entryPoint.to=websecure \
     --entryPoints.web.http.redirections.entryPoint.scheme=https \
     --entryPoints.web.http.redirections.entryPoint.permanent=true \
     --entryPoints.websecure.address=:8443 \
     --entryPoints.websecure.http.tls=true \
     --entryPoints.websecure.transport.respondingTimeouts.readTimeout=420 \
     --entryPoints.websecure.transport.respondingTimeouts.writeTimeout=420 \
     --entryPoints.websecure.transport.respondingTimeouts.idleTimeout=420 \
     --entryPoints.ldaps.address=:636/tcp \
     # --providers.docker=false \
     # --providers.docker.exposedByDefault=false \
     #--providers.docker.watch=true \
     # - -providers.docker.endpoint=unix:///var/run/docker.sock \
     # --providers.docker.allowEmptyServices=true \ 
     --providers.file=true \  
     --providers.file.directory=/etc/traefik/dynamic \
     --serversTransport.insecureSkipVerify=true \ 
     --global.sendAnonymousUsage=false

Image=traefik:v3.3

Label=traefik.enable=true
# Label=traefik.docker.network=traefik
Label=traefik.http.routers.dashboard.entryPoints=websecure
Label=traefik.http.routers.dashboard.rule=Host(`authentik.MYDOMAIN.TLD`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))
Label=traefik.http.routers.dashboard.service=api@internal

# Security Optimizations
NoNewPrivileges=true
SecurityLabelType=container_runtime_t

# Volumes
#Volume=/run/user/1002/podman/podman.sock:/var/run/docker.sock:ro,Z
#Volume=%h/containers/config/traefik/dynamic:/etc/traefik/dynamic:ro,Z
#Volume=%h/containers/certificates/letsencrypt:/certificates:ro,Z
#Volume=%h/containers/log/traefik:/log:Z
Volume=/home/podman/containers/config/authentik/traefik/dynamic:/etc/traefik/dynamic:ro,Z
Volume=/home/podman/containers/certificates/letsencrypt:/certificates:ro,Z
Volume=/home/podman/containers/log/authentik/traefik:/log:rw,Z

Traefic Dynamic Certificates Configuration /etc/traefik/dynamic/certificates.yml:

tls:
  certificates:
    - certFile: /certificates/MYDOMAIN.TLD/fullchain.pem
      keyFile: /certificates/MYDOMAIN.TLD/privkey.pem

Obviously it's binding to the Port and it's answering, but it's NOT routing !

LDAPS Connection (which is the Target Goal of the Container, I already tried with Caddy Layer4 Plugin, but it kept failing) also fails, but for some Reason it takes a while to fail using:

ldapsearch -vvv -x -H ldaps://authentik.MYDOMAIN.TLD -b "<LDAP_BASEDN>" -D "<LDAP_BINDDN>" -w "<LDAP_BINDPASSWORD>" -s sub

I know, the Command is not formulated correctly, however the Point is the Result.
I think it times out after 30 Seconds or so:

ldap_initialize( ldaps://authentik.MYDOMAIN.TLD:636/??base )
ldap_result: Can't contact LDAP server (-1)

Nothing in the Logs.

Firewall is Open for Port 8080, 8443, 636 (and also 80 + 443) TCP:

root@HOST:/# nmap -6 -p 80,443,636,3389,8080,8443 2aXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-07-14 09:36 CEST
Nmap scan report for 2aXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX
Host is up (0.00056s latency).

PORT     STATE    SERVICE
80/tcp   open     http
443/tcp  open     https
636/tcp  open     ldapssl
3389/tcp filtered ms-wbt-server
8080/tcp open     http-proxy
8443/tcp open     https-alt

Nmap done: 1 IP address (1 host up) scanned in 13.11 seconds

Port 3389 is the LDAP Container Backend (goauthentik/ldap Container).
Quadlet for that is authentik-ldap.container:

[Unit]
Description=Authentik LDAP Output
# Requires=authentik-caddy.service 
# After=authentik-caddy.service
Requires=authentik-traefik.service 
After=authentik-traefik.service

[Container]
ContainerName=authentik-ldap

Pod=authentik.pod
StartWithPod=true

Environment=AUTHENTIK_HOST=https://authentik.MYDOMAIN.TLD
Environment=AUTHENTIK_INSECURE=false
Environment=AUTHENTIK_TOKEN=WNnJDzN24po0pebVuUBcOBmwtYOTn1a5nIlhM93G4vhmrNwOGAFXR7Szpq6n

Image=ghcr.io/goauthentik/ldap:2025.6.3

Network=container:authentik-traefik

Pull=missing

User=root

Label=traefik.enable=true

Label=traefik.tcp.routers.ldaps-server-router.entryPoints=ldaps
Label=traefik.tcp.routers.ldaps-server-router.priority=20
Label=traefik.tcp.routers.ldaps-server-router.rule=(HostSNI(`*`))
Label=traefik.tcp.routers.ldaps-server-router.service=ldaps-server-router-service
Label=traefik.tcp.routers.ldaps-server-router.tls=true
Label=traefik.tcp.services.ldaps-server-router-service.loadbalancer.server.port=3389

[Service]
Restart=always

The labels are read through providers.docker. So if you disable the provider, you need to supply the router/service via a dynamic config file.

You can use providers.docker with multiple Traefik instances, place constraints via labels (doc), so different Traefik instances pick up different target services.

Note that traefik.* is a reserved namespace for the labels (pull request), so use something different for your custom labels.

Now that I think about it, it makes perfect Sense :laughing:.

On the Spot however it was really weird that the Configuration of Traefik was not affecting the Dashboard.

Although of course, as you rightfully said, the Configuration I wrote was for the Docker Provider, thus without that Provider enabled, it wouldn't be able to "fetch" the Settings once it starts up.

Interesting about the constraints Labels Constraint. It seems like it's possible to have multiple Matches with include/exclude Rules based on the Documentation :smiley:.

About the Reserved Namespace for traefik, what exactly do you mean ?
Right now, where I have Traefik handling ALL Reverse Proxy Services (say 1 Traefik Instance for 20 Containers), I always have Label=traefik.enable and the others.

Do I need to migrate those as well in the Future ?

Or can I keep using traefik for the "main" Service ? I guess I will need to setup inclusion Rules on the "main" Traefik Instance as well, so it doesn't pickup the other ones.

So instead of:

Label=traefik.enable=true
# Label=traefik.docker.network=traefik
Label=traefik.http.routers.dashboard.entryPoints=websecure
Label=traefik.http.routers.dashboard.rule=Host(`authentik.MYDOMAIN.TLD`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))
Label=traefik.http.routers.dashboard.service=api@internal

I should just go with e.g.:

Label=traefik-authentik.enable=true
# Label=traefik-authentik.docker.network=traefik-authentik
Label=traefik-authentik.http.routers.dashboard.entryPoints=websecure
Label=traefik-authentik.http.routers.dashboard.rule=Host(`authentik.MYDOMAIN.TLD`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))
Label=traefik-authentik.http.routers.dashboard.service=api@internal

Correct ?

You explicitly need to set a constraint label.

It can not be traefik.myOwn, but needs to start with something else than traefik.

All other labels stay the same.