Recently I've tried to host a simple static page behind my Traefik instance and the following problem is driving me crazy the last few days.
My Traefik image version: traefik:v3.0
I have a simple Application in a Dockerfile that looks like the following:
FROM node:lts AS build
WORKDIR /app
COPY . .
RUN npm i
RUN npm run build
FROM httpd:2.4 AS runtime
COPY --from=build /app/dist /usr/local/apache2/htdocs/
I built the Image against a container registry. On top I've configured a docker-compose.yml with the Traefik labels. The docker-compose looks like the following:
version: "3.3"
services:
my_page:
image: ghcr.io/my_page:main
restart: unless-stopped
container_name: my_page
networks:
- web
- default
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik_web"
- "traefik.http.routers.my_page.entrypoints=websecure"
- "traefik.http.routers.my_page.rule=Host(`example.com`)"
- "traefik.http.routers.my_page.tls=true"
- "traefik.http.routers.my_page.tls.certresolver=default"
networks:
default:
web:
external:
name: traefik_web
If I go to example.com I can see my index.html just fine. However, if I want to visit example.com/features it will return a 404 for me. When I access example.com:80/features my subpage is displayed correctly. I think I am missing something really simple here but I can't figure out what it is. Do you have any ideas left on what I can try? Thanks in advance!
ldez
July 21, 2023, 6:35pm
2
Hello,
Traefik v3 is in the beta phase, I recommend using the latest stable version of Traefik v2.
https://hub.docker.com/_/traefik
You didn't provide your traefik service definition (static configuration, etc.)
So I created a "light" and reproducible example based on your snippets.
Content of ./htdocs
.
├── features
│ └── index.html (content: "features")
└── index.html (content: "root")
Traefik v2
version: '3.7'
services:
traefik:
image: traefik:v2.10.1
command:
- --log.level=debug
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http.tls=true
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
foo:
image: httpd:2.4
container_name: my_page
volumes:
- ./htdocs/:/usr/local/apache2/htdocs/
labels:
traefik.enable: true
traefik.http.routers.my_page.rule: Host(`example.localhost`)
# traefik.docker.network: traefik_web
# traefik.http.routers.my_page.entrypoints: websecure
# traefik.http.routers.my_page.tls: true
# traefik.http.routers.my_page.tls.certresolver: default
$ curl -k https://example.localhost/
root%
$ curl -k https://example.localhost/features/
features%
Traefik v3
version: '3.7'
services:
traefik:
image: traefik:v3.0.0-beta3
command:
- --log.level=debug
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http.tls=true
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
foo:
image: httpd:2.4
container_name: my_page
volumes:
- ./htdocs/:/usr/local/apache2/htdocs/
labels:
traefik.enable: true
traefik.http.routers.my_page.rule: Host(`example.localhost`)
# traefik.docker.network: traefik_web
# traefik.http.routers.my_page.entrypoints: websecure
# traefik.http.routers.my_page.tls: true
# traefik.http.routers.my_page.tls.certresolver: default
$ curl -k https://example.localhost/
root%
$ curl -k https://example.localhost/features/
features%
So it works, maybe the missing information related to your context has an influence here.
Note: you can copy-paste without any changes, and run the docker-compose, to help you to debug.
Hello @ldez ,
First of all, thank you for your initial thoughts! I forgot to add my Traefik configuration. Below you'll find my docker-compose.yml for my Traefik Service and my static configuration. Maybe I miss something here.
docker-compose.yml:
version: '3.8'
services:
traefik:
restart: unless-stopped
image: traefik:v3.0
ports:
- "80:80"
- "443:443"
- "127.0.0.1:8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./cert/:/cert/"
- "./config/:/etc/traefik/:ro"
- "./config/dynamic/:/etc/traefik/dynamic/:ro"
- "/opt/traefik/plugins:/plugins-local"
labels:
- "traefik.enable=true" # set to true to expose the Monitoring & API
# middleware redirect
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
# global redirect to https
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
- "traefik.docker.network=traefik_web"
# traefik dashboard
- "traefik.http.routers.api.rule=Host(`dashboard.example.com`)"
- "traefik.http.routers.api.service=api@internal"
- "traefik.http.routers.api.middlewares=auth"
# basic auth variable provided by Ansible
- "traefik.http.middlewares.auth.basicauth.users=admin:{{ traefik_dashboard_basic_auth }}"
- "traefik.http.routers.api.entrypoints=websecure"
- "traefik.http.routers.api.tls=true"
- "traefik.http.routers.api.tls.certresolver=default"
networks:
- "web"
networks:
web:
driver: bridge
My Traefik static configuration (traefik.toml):
[global]
checkNewVersion = false
sendAnonymousUsage = false
[experimental]
[experimental.localPlugins]
[experimental.localPlugins.geoblock]
moduleName = "github.com/nscuro/traefik-plugin-geoblock"
[serversTransport]
insecureSkipVerify = true
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.websecure]
address = ":443"
[log]
level = "INFO"
[accessLog]
format = "common"
filePath = "/dev/null"
[api]
dashboard = true
[ping]
[providers.docker]
network = "traefik_web"
exposedByDefault = false
defaultRule = "Host(`{{ normalize .Name }}.docker.localhost`)"
[providers.file]
directory = "/etc/traefik/dynamic"
watch= true
[certificatesResolvers.default.acme]
email = "contact@example.com"
storage = "/cert/acme.json"
[certificatesResolvers.default.acme.httpChallenge]
entryPoint = "web"
[[tls.certificates]]
certFile = "cert/snakeoil.pem"
keyFile = "cert/snakeoil.key"
[[tls.certificates]]
certFile = "cert/bitmask.me.origin.pem"
keyFile = "cert/bitmask.me.origin.key"
[[tls.certificates]]
certFile = "cert/grun.host.origin.pem"
keyFile = "cert/grun.host.origin.key"
I hope this will help.
ldez
July 21, 2023, 6:50pm
4
Have you tried my example?
You just have to fill ./htdocs
I've tried your example with Traefik 3.0 and it's working for me. What is the best way to find the error in my current setup since I am running multiple services behind my Traefik instance?
Thanks for your help!
ldez
July 21, 2023, 11:56pm
6
stop all your services and add them again one by one.
You don’t seem to mistakenly use Path()
instead of PathPrefix()
in rule, do you?
Make sure you use different router names inside labels of each Docker service.
Set target service port via label, see simple Traefik example .
Hello @bluepuma77 .
I I don't currently use either, so I would rule that out. I have checked all the labels in my services. They are all unique at the moment.
ldez
July 22, 2023, 4:35pm
9
tls.certificates
is not a valid section for the static configuration.
This section is ignored and should be moved to your dynamic configuration files.