In Docker how can I add a static file server to an existing setup?

I have a working (gunicorn, uvicorn, fastapi) setup with TLS provided by Let's Encrypt. I now want to add nginx or caddy to be a file server. It should listen on a couple of paths /static /videos and serve files requested on those paths.

So let's say the domain is service.example.com. app-http is redirecting to app-https and listening for all paths on that domain

I've added an nginx container listening on the same domain with label


- "traefik.frontend.rule=Host(`japanese-joinery.ultrabob.com`) && PathPrefix(`/static/`, `/videos/`, `/screencaps/`)"

Nothing seems to get routed to the new container. I tried adding an inverted PathPrefix rule to the app-https service


- "traefik.frontend.rule=Host(`japanese-joinery.ultrabob.com`) && !PathPrefix(`/static/`, `/videos/`, `/screencaps/`)"

but I see a message in the logs

level=error msg="error while parsing rule !PathPrefix(/static/, /videos/, /screencaps/): ! is not supported" entryPointName=http routerName=app-http@docker

I also wonder if this new service will be able to seamlessly use the certificate that is being procured for app-https or if I will need some config to make that happen.

I'm sorry for a bit of a broad question, I'm not sure how to simplify my setup to get to the core of things without either removing the TLS part altogether or do a new dns setup so I can test locally.

Looks fine.

If it is the same as your existing working domain it will be matched in the certificate store and used.

I run without a certificates resolver, ignore certificate errors and use curl's --resolve flag:

docker-compose.yaml
version: "3.8"

services:
  traefik:
    image: "traefik:v2.5"
    command:
    - --entrypoints.web.address=:80
    - --entrypoints.web.http.redirections.entrypoint.to=websecure
    - --entrypoints.web.http.redirections.entrypoint.permanent=true
    - --entrypoints.websecure.address=:443
    - --entrypoints.websecure.http.tls=true
    - --providers.docker=true
    - --providers.docker.exposedbydefault=false
    - --accesslog
    - --accesslog.format=json
    - --api
    - --log.level=WARNING
    - --log.format=json
    labels:
      traefik.enable: "true"
      traefik.http.routers.api.rule: Host(`traefik.localhost`)
      traefik.http.routers.api.service: api@internal
    ports:
      - published: 80
        target: 80
      - published: 443
        target: 443
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  whoami:
    image: traefik/whoami
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.w.rule=Host(`japanese-joinery.ultrabob.com`) && PathPrefix(`/static/`,`/videos/`,`/screencaps/`)"

curl -k --resolve japanese-joinery.ultrabob.com:443:127.0.0.1 https://japanese-joinery.ultrabob.com/screencaps/
Hostname: e8e6d87109fe
IP: 127.0.0.1
IP: 172.29.0.3
RemoteAddr: 172.29.0.2:59262
GET /screencaps/ HTTP/1.1
Host: japanese-joinery.ultrabob.com
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.29.0.1
X-Forwarded-Host: japanese-joinery.ultrabob.com
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: cb79a8b13fb5
X-Real-Ip: 172.29.0.1

Thank you, that curl tip is really helpful. I think my problem must not have been with the rule but something else in the configuration. I did finally get it working.