Configure Wallabag with Traefik and Docker - Issue with subdirectory

Hi everyone,

I'm having issues with my configuration to forward the Traefik request in the form "DOMAIN + /subdirectory" to a Wallabag Docker container. For example, the request "https:// MY_DOMAIN:MY_PORT/wallabag" should be forwarded to the Wallabag container, but unfortunately the "/wallabag" part is truncated with a 404 error.

I would appreciate any advice or instructions on how to resolve this issue. The relevant configuration files are pasted below:

  1. docker-compose.yml
  2. traefik.toml
  3. traefik_dynamic.toml
  4. nginx.conf
  5. Wallabag is an open source Pocket (read later) replacement: https://github.com/wallabag/docker

$ cat docker-compose.yml

version: "3.3"
services:
  traefik:
    image: "traefik:v2.9"
    container_name: 'traefik'
    ports:
      - "4717:80"
      - "4718:443"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./traefik.toml:/traefik.toml"
      - "./traefik_dynamic.toml:/traefik_dynamic.toml"
      - "./acme.json:/acme.json"
  whoami:  ## Works
    image: "traefik/whoami"
    labels:
      - "traefik.enable=false"
      - "traefik.http.routers.whoami.rule=Host(`MY_DOMAIN`) && Path(`/whoami`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
  wallabag:
    image: wallabag/wallabag
    environment:
      - SYMFONY__ENV__DOMAIN_NAME=https://MY_DOMAIN:4718/wallabag
      - SYMFONY__ENV__SERVER_NAME="My Wallabag instance"
    volumes:
      - ./data:/var/www/wallabag/data
      - ./images:/var/www/wallabag/web/assets/images
      - ./nginx:/etc/nginx:ro
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wallabag.entrypoints=websecure"
      - "traefik.http.routers.wallabag.rule=Host(`MY_DOMAIN`) && PathPrefix(`/wallabag`)"

$ cat traefik.toml

[entryPoints]
  [entryPoints.web]
    address = ":80"
    [entryPoints.web.http.redirections.entryPoint]
      to = "websecure"
      scheme = "https"

  [entryPoints.websecure]
    address = ":443"

    [entryPoints.websecure.http.tls]
      certResolver = "lets-encrypt"

[api]
  dashboard = true

[certificatesResolvers.lets-encrypt.acme]
  email = "MY_EMAIL"
  storage = "acme.json"
  [certificatesResolvers.lets-encrypt.acme.tlsChallenge]

[providers.docker]
  watch = true
  network = "web"
  exposedByDefault = false

[providers.file]
  filename = "traefik_dynamic.toml"

$ cat traefik_dynamic.toml

[http.middlewares.simpleAuth.basicAuth]
  users = [
    "admin:bla"
  ]

[http.routers.api]
  rule = "Host(`MY_DOMAIN`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
  entrypoints = ["web","websecure"]
  middlewares = ["simpleAuth"]
  service = "api@internal"
  [http.routers.api.tls]
    certResolver = "lets-encrypt"

$ cat nginx/nginx.conf

user  nginx;
worker_processes  1;
pid        /var/run/nginx.pid;

events {
    worker_connections  2048;
    multi_accept on;
    use epoll;
}

http {

    server_tokens off;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 15;
    types_hash_max_size 2048;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    access_log on;
    error_log on;
    gzip on;
    gzip_disable "msie6";
    open_file_cache max=100;
    client_max_body_size 100M;

    map $http_x_forwarded_proto $fe_https {
        default $https;
        https on;
    }

    upstream php-upstream {
        server 127.0.0.1:9000;
    }

    server {
        listen 80;
        server_name _;
        root /var/www/wallabag/web;

        location / {
            # try to serve file directly, fallback to app.php
            try_files $uri /app.php$is_args$args;
        }

        location ~ ^/app\.php(/|$) {
            fastcgi_pass php-upstream;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            include fastcgi_params;
            # When you are using symlinks to link the document root to the
            # current version of your application, you should pass the real
            # application path instead of the path to the symlink to PHP
            # FPM.
            # Otherwise, PHP's OPcache may not properly detect changes to
            # your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
            # for more information).
            fastcgi_param  SCRIPT_FILENAME  $realpath_root$fastcgi_script_name;
            fastcgi_param DOCUMENT_ROOT $realpath_root;
            # Prevents URIs that include the front controller. This will 404:
            # http://domain.tld/app.php/some-path
            # Remove the internal directive to allow URIs like this
            internal;
        }

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;
    }

}

daemon off;

Enable Traefig debug log in traefik.toml to see what's happening.

Your Traefik container is listening on ports 4717 and 4718. As far as I know Traefik LetsEncrypt requires port 80 for HTTP challenge and port 443 for TLS challenge.

Not sure if wallabag exposes a single port, but that is what the Docker provider needs. Try adding the label to your wallabag container

 - traefik.http.services.wallabag.loadbalancer.server.port=80

Don't know if wallabag normally uses /wallabag. If not, it is usually saver to use a sub-domain like wallabag.example.com. Otherwise your app might use links and redirects to pages like /login, and then Traefik doesn't know what to do.

Why is nginx in the stack? The docs state they use nginx to expose the application (with TLS/SSL), but that part would be handled by Traefik.

Thanks! After 10+ hours the issue has been resolved with a subdomain. It works like a charm now.