A compose file for running traefik as a local reverse proxy for web services. This means you can run various web servers across various projects at the same time without them clashing.
The typical problem is each project will bring up a web server on port 8000 or something. You can try changing ports, but then you have to remember which port corresponds to which service.
This lets you give names to the services and not worry about ports.
Getting started is very easy, read on...
Traefik itself will listen on port 80 so make sure this is available first (it usually is).
Bring up Traefik:
docker compose up -d
Traefik will keep running; you don't need to keep doing this after you reboot.
Browse to http://traefik.localhost/ to see the Traefik dashboard.
(If you can't see the dashboard at this point, see the Troubleshooting section below).
To see if it's working correctly, run a temporary nginx container:
docker run --name test-nginx --network traefik --rm nginx
And browse to http://test-nginx.localhost/ You should see the nginx test page.
Notice that all we had to do here is make sure that container was connected to the
traefik
network and we can connect to it by name. No ports were configured.
To make a docker compose project work you need to change only one or two things for each project:
- Each container you want to expose must be on the
traefik
network, - If the port cannot be auto-discovered (because either multiple ports are exposed, or a different port is used for the dev environment), you need to tell traefik the port to use.
These can both be achieved with a compose.override.yaml
file (or
docker-compose.override.yaml
) to override stuff in the regular compose file.
Assuming we have a project called proj
with a service www
we can do both 1 and 2 in
an override file like:
services:
www:
labels:
- "traefik.http.services.www-proj.loadbalancer.server.port=8000"
- "traefik.docker.network=traefik"
networks:
- default
- traefik
networks:
traefik:
external: true
Now you can connect to http://www.proj.localhost/
If you have a project that opens specific ports in its compose.yaml
then you can
disable this in your compose.override.yaml
like so:
services:
web:
ports: !reset []
You don't need open ports when using Traefik so this should work OK. You could also change the upstream file to allow the ports to be set using environment variables.
If the upstream project includes an override file already then this is unfortunate. You will have to supply your own override file manually:
docker compose -f compose.yaml -f compose.override.yaml -f my-overrides.yaml up -d
You'll need to read the Traefik docs for everything, but to give a hint here's another common configuration via a label, you can configure a different host name, or multiple host names:
services:
www:
labels:
- "traefik.http.routers.www-proj.rule=Host(`proj.localhost`) || Host(`othername.localhost`)"
- "traefik.http.services.www-proj.loadbalancer.server.port=8000"
- "traefik.docker.network=traefik"
networks:
- default
- traefik
networks:
traefik:
external: true
Traefik listens to the Docker daemon and discovers running containers automatically.
This project sets up Traefik with a default routing rule for each container: if it's
part of a docker compose set up the host is service.project.localhost
, otherwise it is
containername.localhost
.
Traefik uses labels on each container to configure itself further. This way you don't have to have some big global config file. The combination of the default rule plus a couple of extra rules is normally all you need.
Add a .env
file to this project to conveniently change some of the defaults, supported
options are:
PORT=80 # the port Traefik will listen on
DOMAIN=localhost # the domain used for local services
The above simple set up requires your OS to support a wildcard localhost
. This works
on most GNU/Linux distros like Ubuntu and (I think) MacOS. It might not work on Windows
or other systems. On those systems you can use lvh.me
or traefik.me
instead of
localhost
. This does a real DNS lookup that resolves to 127.0.0.1
for any
subdomain. See http://traefik.me/ for further info.
You could also set up your network to have localhost
subdomain resolution using
dnsmasq with the following setting:
address=/localhost/127.0.0.1
address=/localhost/::1
Before I formalised this set up I wrote a blog post about it here. You can also find a link to the Hacker News discussion there with other ideas and options you might like.