Having issues with docker traefik 404 page not found error - docker

I am trying to run 2 apps with traefik.
Both work great without SSL. When I use SSL the first one does not work. I'm getting error 404 page not found. Only first service is giving error. The second service is working with ssl. Check this at second
docker.traefik.yml file
services:
traefik:
image: traefik:latest
ports:
- 80:80
- 443:443
restart: always
labels:
- traefik.enable=true
- traefik.http.services.traefik-dashboard.loadbalancer.server.port=8080
## configure http
- traefik.http.routers.traefik-dashboard-http.entrypoints=http
- traefik.http.routers.traefik-dashboard-http.rule=Host(`dash.ibhaskar.com`)
## configure https
- traefik.http.routers.traefik-dashboard-https.entrypoints=https
- traefik.http.routers.traefik-dashboard-https.tls.certresolver=le
- traefik.http.routers.traefik-dashboard-https.rule=Host(`dash.ibhaskar.com`)
- traefik.http.routers.traefik-dashboard-https.service=api#internal
- traefik.http.routers.traefik-dashboard-https.tls=true
- traefik.http.middlewares.https-redirect.redirectscheme.scheme=https
- traefik.http.routers.traefik-dashboard-http.middlewares=https-redirect
- traefik.http.middlewares.https-redirect.redirectscheme.permanent=true
# define common network for traefik and apps
- traefik.docker.network=towapp
volumes:
- traefik-public-certificates:/certificates
- /var/run/docker.sock:/var/run/docker.sock:ro
command:
- --providers.docker
- --api.insecure
- --providers.docker.exposedbydefault=false
- --entrypoints.http.address=:80
- --entrypoints.https.address=:443 # https
- --certificatesresolvers.le.acme.email=imbhaskaran#gmail.com # https
- --certificatesresolvers.le.acme.storage=/certificates/acme.json #ssl
- --certificatesresolvers.le.acme.tlschallenge=true
- --accesslog
- --log
- --api
networks:
- towapp
volumes:
traefik-public-certificates:
networks:
towapp:
external: true
The docker compose file for both services first and second. These apps are working on localhost. I have test these. The traefik dash board works with https also.
services:
first:
restart: always
container_name: first
build:
context: ./first
dockerfile: Dockerfile
labels:
# Enable Traefik for this specific "backend" service
- traefik.enable=true
# Define the port inside of the Docker service to use
- traefik.http.services.first.loadbalancer.server.port=8081
# Make Traefik use this domain in HTTP
- traefik.http.routers.first-http.entrypoints=http
- traefik.http.routers.first-http.rule=Host(`first.ibhaskar.com`)
# Use the traefik-public network (declared below)
- traefik.docker.network=traefik-public
# Make Traefik use this domain in HTTPS
- traefik.http.routers.first-https.entrypoints=https
- traefik.http.routers.first-https.rule=Host(`first.ibhaskar.com`)
- traefik.http.routers.first-https.tls=true
# Use the "le" (Let's Encrypt) resolver
- traefik.http.routers.first-https.tls.certresolver=le
# https-redirect middleware to redirect HTTP to HTTPS
- traefik.http.middlewares.first-https-redirect.redirectscheme.scheme=https
- traefik.http.middlewares.first-https-redirect.redirectscheme.permanent=true
# Middleware to redirect HTTP to HTTPS
- traefik.http.routers.first-http.middlewares=https-redirect
#- traefik.http.routers.app-https.middlewares=admin-auth
- traefik.docker.network=towapp
command: [ "node", "app.js" ]
networks:
- towapp
second:
restart: always
container_name: second
build:
context: ./second
dockerfile: Dockerfile
labels:
# Enable Traefik for this specific "backend" service
- traefik.enable=true
# Define the port inside of the Docker service to use
- traefik.http.services.second.loadbalancer.server.port=8082
# Make Traefik use this domain in HTTP
- traefik.http.routers.second-http.entrypoints=http
- traefik.http.routers.second-http.rule=Host(`second.ibhaskar.com`)
# Use the traefik-public network (declared below)
- traefik.docker.network=traefik-public
# Make Traefik use this domain in HTTPS
- traefik.http.routers.second-https.entrypoints=https
- traefik.http.routers.second-https.rule=Host(`second.ibhaskar.com`)
- traefik.http.routers.second-https.tls=true
# Use the "le" (Let's Encrypt) resolver
- traefik.http.routers.second-https.tls.certresolver=le
# https-redirect middleware to redirect HTTP to HTTPS
- traefik.http.middlewares.second-https-redirect.redirectscheme.scheme=https
- traefik.http.middlewares.second-https-redirect.redirectscheme.permanent=true
# Middleware to redirect HTTP to HTTPS
- traefik.http.routers.second-http.middlewares=https-redirect
#- traefik.http.routers.app-https.middlewares=admin-auth
- traefik.docker.network=towapp
command: [ "node", "server.js" ]
networks:
- towapp
networks:
towapp:
external: true

Related

traefik rule not redirecting requests made to "localhost/api" to backend container

traefik rule not redirecting requests made to "localhost/api" to backend container
Whenever I change the backend
- "traefik.http.routers.api.rule=Host(`localhost`) && PathPrefix(`/api`)"
to Host('localhost') I can access the application at localhost but after adding this rule, whenever I go to localhost/api , it leads me to frontend and opens html page
version: '3'
volumes:
myvol2:
external: false
services:
traefik:
image: "traefik:v2.6"
command:
#- "--log.level=DEBUG"
- "--api.insecure=true"
- "--api.dashboard=true"
- "--api.debug=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.api.address=:5000"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443" # new
ports:
- "80:80"
- "5000:5000"
- "443:443" # new
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
api:
image: "myimagename"
ports:
- '5000'
scale: 1
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.api.entrypoints=web"
- "traefik.http.services.api.loadbalancer.server.port=5000"
volumes:
- /app/node_modules
- ./server:/app
- myvol2:/resources/static/assets/uploads # Volume
environment:
- PORT=5000
web:
image: "myfrontendimage"
stdin_open: true
scale: 1
ports:
- '3000'
environment:
- CHOKIDAR_USEPOLLING=true
- CI=true
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.rule=Host(`localhost`)"
- "traefik.http.routers.web.entrypoints=web"
- "traefik.http.services.web.loadbalancer.server.port=3000"
volumes:
- /app/node_modules
- ./client:/app
Tried redirecting the Tried almost all combinations of route, even tried adding regexp for matching localhost/api.
With my current nginx setup,
I have :
location /api{
rewrite /api/(.*) /$1 break;
proxy_pass http://api;
}
in my default.conf,
Trying to migrate to traefik but the requests to localhost/api are not reaching
Your configuration seems to be fine. In your question you have a bunch of placeholder values, so it's not actually possible to test your docker-compose.yaml, but we can produce a runnable version like this:
services:
traefik:
image: "traefik:v2.9"
command:
- "--api.insecure=true"
- "--api.dashboard=true"
- "--api.debug=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
# The port mappings here are to avoid conflicts with other services
# on my system
ports:
- "7080:80"
- "7443:443"
- "7090:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
api:
# Note that we don't need a `ports` configuration here because we're
# not publish any ports to the host (all access will be via the
# frontend proxy).
image: "docker.io/traefik/whoami:latest"
command:
- --name=API
- --port=5000
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.api.entrypoints=web"
- "traefik.http.services.api.loadbalancer.server.port=5000"
web:
image: "docker.io/traefik/whoami:latest"
command:
- --name=WEB
- --port=3000
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.rule=Host(`localhost`)"
- "traefik.http.routers.web.entrypoints=web"
- "traefik.http.services.web.loadbalancer.server.port=3000"
The significant changes here are:
I'm using Traefik v2.9 (because why use an older release?)
I've replaced all your images with docker.io/traefik/whoami, which gives us a simple endpoint for testing.
With the above configuration, a request to http://localhost hits the "web" container:
$ curl localhost:7080
Name: WEB
[...]
Whereas a request to http://localhost/api hits the "api" container:
$ curl localhost:7080/api
{...., "name": "API"}
(We're getting a JSON response in the second case because we're hitting the /api path on the whoami container.)
Finally, got the traefik /api to redirect to the other backend container with the following set up
The primary issue was that even though it redirects to the container, it did not strip the /api prefix, so the API route was getting messed up
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=PathPrefix(`/api/`)"
- "traefik.http.routers.api.service=api"
- "traefik.http.services.api.loadbalancer.server.port=5000"
- "traefik.http.middlewares.api.stripprefix.prefixes=/api"
- "traefik.http.middlewares.api.stripprefix.forceSlash=false"
- "traefik.http.routers.api.middlewares=api"

Traefik reverse proxy service into sub folder that doesn't allow BASE URL changing

I recently got into self hosting, I found tailscale to be the best way to access the services that i want on all my devices but typing ports is getting real annoying and I am trying a to enable SSL for some of the important services.
Now most guides on reverse hosting say to use subdomains but I don't want to and thus want to make them accessible in sub-folders instead of sub-domains.
I have been trying to set up a reverse proxy to do that now I have tried Nginx proxy-manager, Caddy and Traefik out of which I found Traefik being the easiest to understand as noob.
I am trying to reverse proxy stuff using traefik to some success, simple services like the ones which have one page work but for bigger services it doesn't work.
This is my traefik docker-compose.yml
version: "3"
networks:
# network created for reverse proxy such that all other
# containers are also on it can communicate with each other
revProxy-net:
name: revProxy-net
driver: bridge
services:
traefik:
image: traefik:v3.0.0-beta2
container_name: traefik
ports:
- 80:80
- 443:443
- 8080:8080
volumes:
- ./config:/etc/traefik
- ./logs:/var/log/traefik
- /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
- /var/run/docker.sock:/var/run/docker.sock
networks:
- revProxy-net
restart: unless-stopped
and this is the traefik.yml
global:
checkNewVersion: true
sendAnonymousUsage: false # true by default
# (Optional) Log information
# ---
log:
level: ERROR # DEBUG, INFO, WARNING, ERROR, CRITICAL
format: common # common, json, logfmt
filePath: /var/log/traefik/traefik.log
# (Optional) Accesslog
# ---
accesslog:
format: common # common, json, logfmt
filePath: /var/log/traefik/access.log
# (Optional) Enable API and Dashboard
# ---
api:
dashboard: true # true by default
insecure: true # Don't do this in production!
# Entry Points configuration
# ---
entryPoints:
web:
address: :80
# (Optional) Redirect to HTTPS
# ---
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: :443
certificatesResolvers:
tailsolver:
tailscale: {}
providers:
docker:
exposedByDefault: false # Default is true
file:
# watch for dynamic configuration changes
directory: /etc/traefik
watch: true
Lets take glances a simple (it has only one html and one js file that loads), which works with this configuration, it is accessible on https://lenovo-ideapad-320-15ikb.tail9ece4.ts.net/glances/
version: "3"
services:
glances:
image: nicolargo/glances:latest-full
container_name: glances
restart: always
ports:
- 61208-61209:61208-61209
environment:
- GLANCES_OPT=-w
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./glances.conf:/etc/glances.conf
pid: host
networks:
- revProxy-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.glances.entrypoints=web,websecure"
- "traefik.http.routers.glances.rule=Host(`lenovo-ideapad-320-15ikb.tail9ece4.ts.net`) && PathPrefix(`/glances`)"
- "traefik.http.middlewares.strip-glances.stripprefix.prefixes=/glances"
- "traefik.http.routers.glances.middlewares=strip-glances#docker"
- "traefik.http.routers.glances.tls=true"
- "traefik.http.routers.glances.tls.certresolver=tailsolver"
- "traefik.http.routers.glances.tls.domains[0].main=lenovo-ideapad-320-15ikb.tail9ece4.ts.net"
networks:
revProxy-net:
external: true
But when i try to use this same thing on jellyfin, it gives Bad Gateway when going to https://lenovo-ideapad-320-15ikb.tail9ece4.ts.net/jellyfin/ ,Here is the jellyfin docker-compose.yml
version: "2.1"
#name: media-stack
services:
jellyfin:
image: lscr.io/linuxserver/jellyfin:latest
container_name: jellyfin
environment:
- PUID=1000
- PGID=1000
- TZ=${TZ_NAME}
#- JELLYFIN_PublishedServerUrl=192.168.0.25 #optional
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=all
volumes:
- ./jellyfin/config:/config
- /home/sagnik/Projects/yt-diff/yt-dlp/:/yt-dlp
# Removed for testing purposes
ports:
- ${JELLYFIN_PORT}:8096
- 8920:8920
- 7359:7359/udp
- 1900:1900/udp
deploy:
resources:
reservations:
devices:
- capabilities: [ gpu ]
restart: unless-stopped
labels:
- 'traefik.enable=true'
## HTTP Router
#### Entry point where Jellyfin is accessible via
#### Change secure to https in the line below to have accessible without needing to specify a port and change the SSLHost option below
- 'traefik.http.routers.jellyfin.entryPoints=web,websecure'
#### Host or Path where Jellyfin is accessible
#### Remove (or change) this rule if you'd rather have Jellyfin accessible at a PathPrefix URI
- 'traefik.http.routers.jellyfin.rule=Host(`lenovo-ideapad-320-15ikb.tail9ece4.ts.net`) && PathPrefix(`/jellyfin`)'
#### Prefix stripper
- "traefik.http.middlewares.strip-jellyfin.stripprefix.prefixes=/jellyfin"
- "traefik.http.routers.jellyfin.middlewares=strip-jellyfin#docker"
#### Using the tailscale ones
- "traefik.http.routers.jellyfin.tls=true"
- "traefik.http.routers.jellyfin.tls.certresolver=tailsolver"
- "traefik.http.routers.jellyfin.tls.domains[0].main=lenovo-ideapad-320-15ikb.tail9ece4.ts.net"
networks:
- revProxy-net
networks:
revProxy-net:
external: true
I have tried reading the documentation, and reading the ways to change base url for some services but I don't understand what is happening.
You forgot about the port!
- 'traefik.http.routers.jellyfin.service=jellyfin-svc'
- 'traefik.http.services.jellyfin-svc.loadBalancer.server.port=8096'

Docker-compose . Yml file for traefik running, but can't access dashboard

second post. Was having trouble getting my traefik docker-compose yamel file to run,got that sorted,now it runs, but the traefik dashboard isn't accessible.
The code for my compose file is
version: "3.8"
########################### NETWORKS
networks:
t2_proxy:
external:
name: t2_proxy
default:
driver: bridge
########################### SERVICES
services:
# All services / apps go below this line
# Traefik 2 - Reverse Proxy
traefik:
container_name: traefik
image: traefik:2.6.1 # the chevrotin tag refers to v2.2.x but introduced a breaking change in 2.2.2
restart: unless-stopped
command: # CLI arguments
- --global.checkNewVersion=true
- --global.sendAnonymousUsage=true
- --entryPoints.http.address=:80
- --entryPoints.https.address=:443
# Allow these IPs to set the X-Forwarded-* headers - Cloudflare IPs: https://www.cloudflare.com/ips/
- --entrypoints.https.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/12,172.64.0.0/13,131.0.72.0/22
- --entryPoints.traefik.address=:8080
- --api=true
- --api.insecure=true
# - --serversTransport.insecureSkipVerify=true
- --log=true
- --log.level=DEBUG # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC
- --accessLog=true
- --accessLog.filePath=/traefik.log
- --accessLog.bufferingSize=100 # Configuring a buffer of 100 lines
- --accessLog.filters.statusCodes=400-499
- --providers.docker=true
- --providers.docker.endpoint=unix:///var/run/docker.sock
- --providers.docker.defaultrule=Host(`{{ index .Labels "com.docker.compose.service" }}.$DOMAINNAME`)
- --providers.docker.exposedByDefault=false
- --providers.docker.network=t2_proxy
- --providers.docker.swarmMode=false
- --providers.file.directory=/rules # Load dynamic configuration from one or more .toml or .yml files in a directory.
# - --providers.file.filename=/path/to/file # Load dynamic configuration from a file.
- --providers.file.watch=true # Only works on top level files in the rules folder -
# - --certificatesResolvers.dns-cloudflare.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory # LetsEncrypt Staging Server - uncomment when testing -
- --certificatesResolvers.dns-cloudflare.acme.email=$CLOUDFLARE_EMAIL
- --certificatesResolvers.dns-cloudflare.acme.storage=/acme.json
- --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.provider=cloudflare
- --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.resolvers=1.1.1.1:53,1.0.0.1:53
# networks:
# t2_proxy:
# ipv4_address: 192.168.90.829 # You can specify a static IP
networks:
- t2_proxy
security_opt:
- no-new-privileges:true
ports:
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
- target: 8080
published: 8080
protocol: tcp
mode: host
volumes:
- $DOCKERDIR/traefik2/rules:/rules
- /var/run/docker.sock:/var/run/docker.sock:ro
- $DOCKERDIR/traefik2/acme/acme.json:/acme.json
- $DOCKERDIR/traefik2/traefik.log:/traefik.log
- $DOCKERDIR/shared:/shared
environment:
- CF_API_EMAIL=$CLOUDFLARE_EMAIL
- CF_API_KEY=$CLOUDFLARE_API_KEY
labels:
- "traefik.enable=true"
# HTTP-to-HTTPS Redirect
- "traefik.http.routers.http-catchall.entrypoints=http"
- "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
# HTTP Routers
- "traefik.http.routers.traefik-rtr.entrypoints=https"
- "traefik.http.routers.traefik-rtr.rule=Host(`traefik.$DOMAINNAME`)"
- "traefik.http.routers.traefik-rtr.tls=true"
# - "traefik.http.routers.traefik-rtr.tls.certresolver=dns-cloudflare" # Comment out this line after first run of traefik to force the use of wildcard certs
- "traefik.http.routers.traefik-rtr.tls.domains[0].main=$DOMAINNAME"
- "traefik.http.routers.traefik-rtr.tls.domains[0].sans=*.$DOMAINNAME"
# - "traefik.http.routers.traefik-rtr.tls.domains[1].main=$SECONDDOMAINNAME" # Pulls main cert for second domain
# - "traefik.http.routers.traefik-rtr.tls.domains[1].sans=*.$SECONDDOMAINNAME" # Pulls wildcard cert for second domain
## Services - API
- "traefik.http.routers.traefik-rtr.service=api#internal"
## Middlewares
- "traefik.http.routers.traefik-rtr.middlewares=middlewares-basic-auth#file"
`Looked at the log file, and I've observed it saying:
level=debug msg="No default certificate, generating one" tlsStoreName=default
But I'm pretty sure I have a certificate for cloudflare, which is in a environments folder i set up
Also I noticed this:
level=debug msg="http: TLS handshake error from with my server pc's static IP address and port 36198:EOF
When I attempt to access the dashboard via my servers web browser I see this:
And when I get everything running and switch over to my desktop this pops up:

Traefik Docker SSL Configuration With Lets Encrypt

Hi everyone I am trying to enable SSL in my docker-compose.yml file for my backend service. All of my Traefik configuration is done in my docker-compose.yml file, so I may be missing a line. Running docker-compose on this configuration works without SSL and the site is displayed properly, but it does not work when using https. I have checked the Traefik documentation for the certResolvers and I am not sure what I am missing thanks.
version: "3"
networks:
NanoWall-Net:
services:
api:
build:
context: .
dockerfile: Dockerfile
labels:
- "traefik.docker.network=NanoWall-Net"
- "traefik.enable=true"
- "traefik.port=5000"
- "traefik.http.routers.http-catchall.rule=Host(`nanowalldocs.com`)"
- "traefik.http.routers.http-catchall.tls=true"
- "traefik.http.routers.http-catchall.tls.certresolver=le"
- "traefik.http.routers.http-catchall.tls.domains[0].sans=nanowalldocs.com"
- "traefik.http.routers.http-catchall.entrypoints=web"
ports:
- "5000:5000"
networks:
- NanoWall-Net
reverse-proxy:
image: traefik:v2.0
# Enables the web UI and tells Traefik to listen to docker
command:
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls.certResolver: le"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--api.insecure=true"
- "--api.debug=true"
- "--api=true"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
- "--providers.docker.exposedbydefault=false"
- "--accesslog=true"
- "--accesslog.filepath=/var/log/traefik-access.log"
- "--accesslog.bufferingsize=1000"
- "--log.filePath=/var/log/traefik.log"
- "--certificatesResolvers.le.acme.email=jamar.phillip99#gmail.com"
- "--certificatesResolvers.le.acme.storage=acme.json"
- "--certificatesResolvers.le.acme.httpChallenge=true"
- "--certificatesResolvers.le.acme.httpChallenge.entryPoint=web"
ports:
# The HTTP port
- "80:80"
- "443:443"
# The Web UI (enabled by --api.insecure=true)
- "8080:8080"
networks:
- NanoWall-Net
volumes:
- /acme.json/etc/traefik/acme.json
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: always
It may not be the only issue, but you are missing a colon in your traefik volumes section. You have:
- /acme.json/etc/traefik/acme.json
I think it should be (assuming your host location is really /acme.json and not ./acme.json or in some other directory):
- /acme.json:/etc/traefik/acme.json
That said, I have also been having an issue where traefik always wants it in /acme.json, so I just put it there instead of in /etc/traefik/acme.json .

Traefik 2.0 behind docker swarm not working

So, I'm trying to use Traefik to load-balance my web apps via docker swarm.
However, I already tried many configurations but somehow not works. I already read the documentation and read some articles in the internet. Unfortunately, many articles references traefik 1.x instead traefik 2.0.
Here is my docker-stack.yml for traefik
version: '3.7'
services:
traefik:
image: traefik:2.0
deploy:
mode: global
placement:
constraints:
- node.role == manager
restart_policy:
condition: on-failure
labels:
- traefik.docker.network=load_balancer
configs:
- source: traefik
target: /etc/traefik/traefik.yml
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- load_balancer
configs:
traefik:
file: ./traefik.yml
networks:
load_balancer:
external: true
name: load_balancer
whoami.yml (for testing purpose)
version: '3.7'
services:
whoami:
image: containous/whoami
deploy:
labels:
- traefik.enable=true
- traefik.docker.network=load_balancer
- traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)
networks:
- load_balancer
networks:
load_balancer:
external: true
name: load_balancer
My traefik.yml
log:
level: DEBUG
api:
insecure: true
providers:
docker:
exposedByDefault: false
swarmMode: true
watch: true
docker network ls
hxjw9rytw3od load_balancer overlay swarm
curl -H Host:whoami.docker.localhost http://127.0.0.1
404 page not found
Maybe you have to add entrypoints declaration in your config: https://docs.traefik.io/routing/entrypoints/
I hope is not too late to answer this. I've found the solution.
First, you can either use traefik.yml for configuration or use traefik cli flags in docker-compose command field.
Here is the working approach if you use traefik.yml as your main configuration.
It is recommended to use directory over file.
traefik.yml
log:
level: DEBUG
api:
insecure: true
# This is required
entryPoints:
web:
address: ':80'
websecure:
address: ':443'
providers:
file: # Required, if you use traefik.yml as your main configuration
directory: /etc/traefik
watch: true
docker:
exposedByDefault: false
swarmMode: true
watch: true
Working approach if you use traefik cli flags
docker-compose.stack.yml
version: '3.7'
services:
traefik:
image: traefik:2.0
deploy:
mode: global
placement:
constraints:
- node.role == manager
restart_policy:
condition: on-failure
command:
- --log.level=DEBUG
- --api.insecure=true
- --ping=true
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --providers.docker.swarmmode=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=load_balancer
- --providers.docker.watch=true
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- load_balancer
networks:
load_balancer:
external: true
name: load_balancer
whoami.yml (for testing purpose)
version: '3.7'
services:
whoami:
image: containous/whoami
deploy:
labels:
- traefik.enable=true
- traefik.docker.network=load_balancer
- traefik.http.routers.whoami.entrypoints=web
- traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)
- traefik.http.services.whoami.loadbalancer.server.port=80
networks:
- load_balancer
networks:
load_balancer:
external: true
name: load_balancer
Test via curl
curl -H Host:whoami.docker.localhost 127.0.0.1
I can suggest you to Not use traefik.yml but to use the cli args to configure your instance.
You can make it like this :
version: "3.7"
services:
ingress:
image: traefik:v2.0
networks:
- ingress-net
ports:
- "80:80"
- "443:443"
# TCP Port if needed for any service you have
- "60000:60000"
command:
### ###
# Traefik Global Configuration #
### ###
# Enable DEBUG logs
- "--log.level=DEBUG" # DEBUG, INFO, etc...
- "--ping=true"
# Enable api access without authentification (only GET route so it only possible to get IPs)
- "--api.insecure=true" # You can insecure here, because It accessible only in the container if you didn't open the port.
# Set the provider to Docker
- "--providers.docker=true"
# Set the docker network
- "--providers.docker.network=ingress-net"
# Set to docker swarm cluster
- "--providers.docker.swarmMode=true"
# If False : Do not expose containers to the web by default
- "--providers.docker.exposedByDefault=false"
# Default rule to service-name.example.com
- "--providers.docker.defaultRule=Host(`{{ trimPrefix `/` .Name }}.example.com`)"
# Default http port
- "--entrypoints.http.address=:80"
# Default https port
- "--entrypoints.https.address=:443"
# Enable let's encrypt
- "--certificatesResolvers.certbot=true"
- "--certificatesResolvers.certbot.acme.httpChallenge=true"
- "--certificatesResolvers.certbot.acme.httpChallenge.entrypoint=http"
- "--certificatesResolvers.certbot.acme.email=admin#example.com"
- "--certificatesResolvers.certbot.acme.storage=/letsencrypt/acme.json"
# TCP Entrypoint if needed
- "--entrypoints.tcpendpointname.address=:60000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./acme.json:/letsencrypt/acme.json
deploy:
replicas: 1
labels:
### ###
# Traefik Dashboard #
### ###
# Enable this endpoint
- traefik.enable=true
##
# Http
#
# Set the service route
- traefik.http.routers.ingress_http.rule=Host(`ingress.example.com`)
# Set the entrypoint (http or https)
- traefik.http.routers.ingress_http.entrypoints=http
# Rule to redirect to http to https
- traefik.http.middlewares.ingress-https-redirect.redirectscheme.scheme=https
# Enable Https redirection
- traefik.http.routers.ingress_http.middlewares=ingress-https-redirect#docker
#
##
##
# Https
#
- traefik.http.routers.ingress_https.rule=Host(`ingress.example.com`)
# Set the entrypoint (http or https)
- traefik.http.routers.ingress_https.entrypoints=https
# Enable Let's encrypt auto certificat creation
- traefik.http.routers.ingress_https.tls.certresolver=certbot
# Enable authentification
- traefik.http.routers.ingress_https.middlewares=ingress-auth#
# Uncommant this to enable basic authentification
# - traefik.http.middlewares.ingress-auth.basicauth.users=admin:$$this$$is$$encrypted$$password
#
##
##
# TCP Endpoint
#
# Set the service route
- "traefik.tcp.routers.tcpendpointname.rule=HostSNI(`*`)"
# Here you can set the host uri if you use tls only.
# - "traefik.tcp.routers.tcpendpointname.rule=HostSNI(`tcp.example.com`)"
# - "traefik.tcp.routers.tcpendpointname.tls=true"
# Set the entrypoin
- "traefik.tcp.routers.tcpendpointname.entrypoints=tcpendpointname"
#
##
##
# Service
#
# Set the service port
- traefik.http.services.ingress.loadbalancer.server.port=8080
#
##
placement:
constraints:
- node.role == manager
networks:
ingress-net:
external: true
I hope this will Help you.
You can use the same labels for any other containers, that work with the same logic.
Since you've got a 404 page not found Traefik seems to be available.
However, when using curl to fetch http://127.0.0.1 this IP address is going to be content of request's Host header field. This in turn is used by Traefik for routing the request. Since your whoami service is meant to match requests for Host whoami.docker.localhost this given response of Traefik is just fine.
Have you tried fetching http://whoami.docker.localhost instead? You might need to inject this hostname into hosts /etc/hosts files prior to testing with curl.
127.0.0.1 whoami.docker.localhost
Optionally, you can try manual HTTP request with a tool like netcat (sometimes available as nc):
# netcat 127.0.0.1 80
GET / HTTP/1.0
Host: whoami.docker.localhost
You need to press Enter twice after entering second line of request as required by HTTP.
Port Detection
Docker Swarm does not provide any port detection information to Traefik.
Therefore you must specify the port to use for communication by using the label traefik.http.services.<service_name>.loadbalancer.server.port (Check the reference for this label in the routing section for Docker).
Traefik's service discovery with Docker requires container labels instead of image labels (check traefik's quickstart).
The following minimal working example works on docker swarm:
version: '3.7'
services:
traefik:
image: traefik:2.0
command: --providers.docker
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
whoami:
image: containous/whoami
labels: # defining a container label instead of an image label
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"

Resources