Dockerized traefik v3
with auto-discovery of other containers on the same Docker network.
The traefik
container runs as nobody and uses proxy to get restricted and limited access to the Docker socket.
- Clone this repo.
- Then run:
sudo chown nobody:nogroup letsencrypt/
echo "HOSTNAME=$(hostname)" > .env
docker network create public-network
docker-compose pull
docker-compose up -d
- This Traefik instance runs on
public-network
network. Your containers should also use it:
# make your ... container discoverable by traefik
# https://docs.docker.com/compose/networking/#configure-the-default-network
#
# docker network create public-network
networks:
default:
name: public-network
external: true
- Add labels to your container.
# https://doc.traefik.io/traefik/user-guides/docker-compose/basic-example/
labels:
traefik.enable: true
traefik.http.routers.<your app name>.rule: Host(`<your domain, e.g. myservice.foo.net>`)
traefik.http.services.<your app name>.loadbalancer.server.port: "< port where your service is bound too >" # or rely on ports defined via EXPOSE
- Make sure that your container own healthcheck also passes. Traefik filters out containers that do not pass Docker healthchecks:
$ DOCKER_HOST=tcp://localhost:2375 docker ps --format json | jq -c "[ .Names,.Status ]" -r
["socks5","Up 11 minutes (healthy)"]
["docker_socket_proxy","Up 21 hours (healthy)"]
["whoami","Up 21 hours"]
["traefik","Up 21 hours (healthy)"]
This container exposes both http (80) and https (443) ports. It supports both http/2 and http/3.
There's also the dashboard exposed on a local 58888 port (this port is bound to the local interface only!).
You can use the 5888 port to get some information from the API about your running services and routers:
$ curl -s 127.0.0.1:58888/api/http/routers | jq -r '.[] | .service' | sort
acme-http@internal
api@internal
dashboard@internal
noop@internal
ping@internal
prometheus@internal
<your app name>
$ curl -s 127.0.0.1:58888/api/http/services | jq '.[] | .serverStatus'
{
"http://172.x.x.x:8080": "UP"
}
Responses from HTTP services are getting the x-served-by
header added automatically (via the x-served-by@file
middleware), e.g.
$ curl https://localhost/whoami --insecure -H 'Host: macbre.local' -v 2>&1 | grep x-served-by
< x-served-by: macbre.local
The response header's value is taken from the
HOSTNAME
env variable.