Actually I'm using the following config
compose.yaml
services:
traefik:
image: traefik:v2.10.1
container_name: my-traefik-container
command:
- "--log.level=ERROR"
- "--api.insecure=false"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
- "--certificatesresolvers.myresolver.acme.email=${CERT_EMAIL}"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "443:443"
volumes:
- ./letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
backend:
build:
context: ./backend/
dockerfile: Dockerfile
container_name: my-backend-container
restart: on-failure
env_file: compose-prod.env
depends_on:
- alembic
image: my-project-backend
command: bash -c "
sleep 3 &&\
uvicorn main:app --workers 1 --host 0.0.0.0 --port 8000"
labels:
- "traefik.enable=true"
- "traefik.http.routers.backend.rule=Host(`my-project.dev`, `www.my-project.dev`) && PathPrefix(`/api`)"
- "traefik.http.routers.backend.entrypoints=websecure"
- "traefik.http.middlewares.backend-redirect-non-www-to-www.redirectregex.permanent=true"
- "traefik.http.middlewares.backend-redirect-non-www-to-www.redirectregex.regex=^https?://(?:www.)?(.+)"
- "traefik.http.middlewares.backend-redirect-non-www-to-www.redirectregex.replacement=https://www.$${1}"
- "traefik.http.routers.backend.middlewares=backend-redirect-non-www-to-www"
- "traefik.http.middlewares.backend-strippefix.stripprefix.prefixes=/api"
- "traefik.http.middlewares.backend-strippefix.stripprefix.forceslash=false"
- "traefik.http.routers.backend.middlewares=backend-strippefix"
- "traefik.http.services.backend-loadbalander.loadbalancer.server.port=8000"
- "traefik.http.routers.backend.service=backend-loadbalander"
- "traefik.http.routers.backend.tls.certresolver=myresolver"
frontend:
build:
context: ./frontend/
dockerfile: Dockerfile
container_name: my-frontend-container
restart: on-failure
env_file: compose-prod.env
depends_on:
- backend
- traefik
image: my-project-frontend
command: bash -c "
sleep 4 &&\
uvicorn main:app --workers 1 --host 0.0.0.0 --port 8001"
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`my-project.dev`, `www.my-project.dev`)"
- "traefik.http.routers.frontend.entrypoints=websecure"
- "traefik.http.middlewares.frontend-redirect-non-www-to-www.redirectregex.permanent=true"
- "traefik.http.middlewares.frontend-redirect-non-www-to-www.redirectregex.regex=^https?://(?:www.)?(.+)"
- "traefik.http.middlewares.frontend-redirect-non-www-to-www.redirectregex.replacement=https://www.$${1}"
- "traefik.http.routers.frontend.middlewares=frontend-redirect-non-www-to-www"
- "traefik.http.services.frontend-loadbalander.loadbalancer.server.port=8001"
- "traefik.http.routers.frontend.service=frontend-loadbalander"
- "traefik.http.routers.frontend.tls.certresolver=myresolver"
The issue here is the redirectregex from the backend service.
When I try to do a request in frontend service the redirect works fine
➜ ~ curl https://my-project.dev/
Moved Permanently
➜ ~ curl https://www.my-project.dev/
<!DOCTYPE html>
...
When I do the same request in backend service, this one response the same thing for these requests.
➜ ~ curl https://my-project.dev/api/foo
{"detail":"foo"}
➜ ~ curl https://www.my-project.dev/api/foo
{"detail":"foo"}
I expected that the first request response with Moved Permanently
, same happened with frontend service, i.e., I want the API only serves the www domain. For what I tested, this is related with strippefix