Using Traefik in Docker Compose

Peter Larsson
Predictly on Tech
Published in
2 min readAug 9, 2021

In my current project we use Kubernetes with ingress and services using the same hostname but different paths. Testing locally we ran into difficulties of testing the full setup. Since we already use docker compose in general we watned to get a quick start this way, rather than starting to use Kubernetes or Minikube.

For simplicity our structure looks like this:

  • Frontend javascript service being served on root path /
    Example: https://our-application.company.com/
  • Backend service being served on the same hostname and the path /api where the /api is not part of the backend service itself so requests routed to /api is served by the backend at /.
    Example: https://our-application.company.com/api/

Snippet below is our ingress helm configuration for our backend using the nginx-ingress controller in our Kubernetes environment.

The snippet is more to get an idea, than to provide working code.

ingress:
enabled: true
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
hosts:
- host: <HOST_URL>
paths:
- /api(/|$)(.*)

To solve this we used the traefik docker image in our compose file, which lead me to write this article since I couldn’t find a working example in one place.

The docker compose file to showcase the use of traefik would be this in its condensed form with just two nginx demos docker images.

version: "3.3"services:
# Traefik to mimic the kubernetes ingress
traefik:
image: "traefik:v2.4"
container_name: "traefik"
command:
# - "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
frontend:
image: nginxdemos/hello
container_name: "frontend"
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=PathPrefix(`/`)"
backend:
image: nginxdemos/hello
container_name: "backend"
labels:
- "traefik.enable=true"
- "traefik.http.routers.backend.rule=PathPrefix(`/api/`)"
- "traefik.http.middlewares.backend.stripprefix.prefixes=/api"
- "traefik.http.routers.backend.middlewares=backend"

After starting this simple docker compose environment you will have two different nginx responding to either:

  • http://localhost/
  • http://localhost/api/

Both respond with the path / but different server id’s.

Challenges

Two things that was a little bit troublesome getting correct was:

  1. The trailing slash on the path prefix needing to be there.
  2. Including the last line in compose above with the middlewares configuration to include stripprefix configuration.

--

--

Peter Larsson
Predictly on Tech

DevOps Consultant at Predictly AB. Working primarily with Kubernetes and Public Cloud. Enjoys automating processes, working hard to be able to do less work.