In the past I’ve used jwilder’s nginx-proxy for my reverse proxy needs but maintenance on that codebase seems to be struggling with several ideas hanging around as open PRs. One of these ideas that I’m interested is routing http requests to different docker containers based on path, something a more modern reverse proxy, Traefik, already does natively. For me however, ramping up on Traefik had some head-to-brick-wall moments that I’ll document here so you, or more likely future me, doesn’t have to make the same mistakes.

Routing between multiple docker-compose files

The docker-compose quickstart is simple but if you want to take the next step and route between docker-compose applications you’ll need to either define a network or use a pre-existing network. If you don’t specify network details in docker-compose, a default one will be created for you in the format <parent-directory>_default. You can confirm this by running docker network ls after you’ve docker-compose up.

If you’ve only got one other docker-compose application, you could include traefik as service in that application, in which case it’ll use the default network. If you want to split the files out, you can make traefik run in your first application’s network by overriding the default network in the traefik docker-compose:

networks:
  default:
    external:
      name: myapplication_default

You can’t route from one provider frontend to another provider’s backend

Think you wanna route from a frontend configured in file to a backend in docker? Well you aint, so go put that rule matcher on the container in your docker-compose file.

frontend.priority null is over 9000

Priorities are respected across providers, however for two rules that would overlap, one with priority and without, the rule without priority will match. Add priority to both where a higher priority (20 > 10) will match first.

Routing to a static website in an S3 bucket

In the end routing a domain to a website hosted on S3 looked like this. The priority is in there such that other matchers (PathPrefixStrip) can match on specific paths.

[file]

[frontends]
  [frontends.frontend1]
  priority = 10
  backend = "backend1"
    [frontends.frontend1.routes.test_1]
    rule = "Host:mydomain.com"
[backends]
  [backends.backend1]
    [backends.backend1.servers.server1]
    url = "http://my.s3.bucket.amazonaws.com"