Tried everything, cannot get PathPrefix to work, Docker Swarm

I'm using docker swarm, but somehow traefik sends everything to my django container and nothing to nginx to serve my static files. I'm really clueless why this happens.

Thanks to anyone that can spot the problem! :slight_smile:

NOTE: I tried stripping prefix with middleware but the same happens

Access.log:

10.0.0.2 - - [26/Apr/2020:07:28:12 +0000] "GET / HTTP/2.0" 200 1934 "-" "-" 1 "web@docker" "http://10.0.1.17:8000" 271ms
10.0.0.2 - - [26/Apr/2020:07:28:13 +0000] "GET /static/css/app.c3fcfcaf.css/ HTTP/2.0" 200 1934 "-" "-" 2 "web@docker" "http://10.0.1.17:8000" 3ms
10.0.0.2 - - [26/Apr/2020:07:28:13 +0000] "GET /static/js/chunk-vendors.3f10924e.js/ HTTP/2.0" 200 1934 "-" "-" 3 "web@docker" "http://10.0.1.17:8000" 3ms
10.0.0.2 - - [26/Apr/2020:07:28:13 +0000] "GET /static/js/app.7456a09d.js/ HTTP/2.0" 200 1934 "-" "-" 4 "web@docker" "http://10.0.1.17:8000" 3ms
10.0.0.2 - - [26/Apr/2020:07:28:13 +0000] "GET /static/js/app.7456a09d.js/ HTTP/2.0" 200 1934 "-" "-" 5 "web@docker" "http://10.0.1.17:8000" 3ms

As you can see, everything is sent to web@docker:8000 (my django gunicorn app)

this is my traefik.yml:

version: "3.7"

services:
  reverse-proxy:
    image: traefik:v2.2.0
    command:
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--providers.docker.swarmMode=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.network=traefik-public"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencryptresolver.acme.httpchallenge=true"
      - "--certificatesresolvers.letsencryptresolver.acme.httpchallenge.entrypoint=web"
      - "--certificatesresolvers.letsencryptresolver.acme.email=user@example.app"
      - "--certificatesresolvers.letsencryptresolver.acme.storage=/letsencrypt/acme.json"
      - "--log.level=DEBUG"
      - "--accesslog=true"
      - "--accesslog.filepath=/access.log"
    ports:
      - 80:80
      - 443:443
    volumes:
      - traefik-certificates:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - traefik-public
    deploy:
      placement:
        constraints:
          - node.role == manager
      labels:
         - "traefik.enable=true"
         - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
         - "traefik.http.routers.http-catchall.entrypoints=web"
         - "traefik.http.routers.http-catchall.middlewares=redirect-to-https@docker"
         - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
         - "traefik.http.services.static-http.loadbalancer.server.port=443" #otherwise it keeps giving errors

volumes:
  traefik-certificates:
networks:
  traefik-public:
    external: true

my django / nginx yml:

version: "3.7"

services:
  web:
    image: web:production
    command: gunicorn web.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static_volume:/usr/src/app/static
    ports:
      - "8000:8000"
    networks:
      - traefik-public
    env_file:
      - .env
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.web-https.rule=Host(`example.app`)"
        - "traefik.http.routers.web-https.entrypoints=websecure"
        - "traefik.http.routers.web-https.tls.certresolver=letsencryptresolver"
        - "traefik.http.services.web-https.loadbalancer.server.port=8000"

  static:
   image: nginx:1.17.10-alpine
   volumes:
     - ./nginx.prod/nginx.conf:/etc/nginx/conf.d/default.conf
     - static_volume:/static:ro
   networks:
     - traefik-public
   labels:
     - "traefik.enable=true"
     - "traefik.http.routers.static-https.entrypoints=websecure"
     - "traefik.http.routers.static-https.rule=Host(`example.app`) && PathPrefix(`/static`)"
     - "traefik.http.routers.static-https.priority=200"
     - "traefik.http.routers.static-https.tls.certresolver=letsencryptresolver"
     - "traefik.http.services.static-https.loadbalancer.server.port=80"

volumes:
  static_volume:

networks:
  traefik-public:
    external: true

Hello,

You have to define the labels inside the deploy section.

https://docs.traefik.io/v2.2/providers/docker/#routing-configuration-with-labels_1

  static:
   image: nginx:1.17.10-alpine
   volumes:
     - ./nginx.prod/nginx.conf:/etc/nginx/conf.d/default.conf
     - static_volume:/static:ro
   networks:
     - traefik-public
   deploy: # <----
     labels:
       - "traefik.enable=true"
       - "traefik.http.routers.static-https.entrypoints=websecure"
       - "traefik.http.routers.static-https.rule=Host(`example.app`) && PathPrefix(`/static`)"
       - "traefik.http.routers.static-https.priority=200"
       - "traefik.http.routers.static-https.tls.certresolver=letsencryptresolver"
       - "traefik.http.services.static-https.loadbalancer.server.port=80"
1 Like

Hi Idez,

Thank you so much. I feel like such an idiot. I've spent at least 8 hours working on this problem, tinkering. Reading the documentation inside out. I had a hunch though it was some little something I am looking past.

Just to give you an indication of the pain relieve you have given me: Here is my commit history..

Thanks again!