Proxy Portainer under sub path

hi
i'm try to proxy portainer to http://mylaptop.com/portainer but page not load (show one line and place holder)

this is my docker file

version: '3'
services:
  reverse-proxy:
    # The official v2.0 Traefik docker image
    image: traefik:v2.1
    container_name: reverse-proxy
    # Enables the web UI and tells Traefik to listen to docker
    command: --api.insecure=true --providers.docker
    ports:
      # The HTTP port
      - "80:80"
      # The Web UI (enabled by --api.insecure=true)
      - "8080:8080"
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock
      #- /home/abayoumy/Documents/traefik/traefik.toml:/traefik.toml
  portainer:
    image: portainer/portainer:latest
    container_name: portainer
    environment:
      - PUID=1000
      - PGID=1000
    #  - TZ=Asia/Riyadh
    restart: always
    command: --no-auth
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data:/data
    labels:
      - "traefik.http.routers.portainer.rule=Host(`mylaptop.com`) && PathPrefix(`/portainer`)"
      - "traefik.http.routers.portainer.middlewares=portainer-stripprefix"
      - "traefik.http.middlewares.portainer-stripprefix.stripprefix.prefixes=/portainer"
      - "traefik.http.routers.portainerwebsocket.rule=Host(`mylaptop.com`) && PathPrefix(`/portainer/api/websocket`)"
      - "traefik.http.routers.portainerwebsocket.middlewares=portainerwebsocket-stripprefix"
      - "traefik.http.middlewares.portainerwebsocket-stripprefix.stripprefix.prefixes=/portainer/api/websocket"
      - "traefik.http.services.portainer.loadbalancer.server.port=9000"
    

i'm try to proxy /portainer/api/websocket path becase this is how to work in nginx

location /portainer {
    return 301 $scheme://$host/portainer/;
}
location ^~ /portainer/ {
    # enable the next two lines for http auth
    #auth_basic "Restricted";
    #auth_basic_user_file /config/nginx/.htpasswd;

    # enable the next two lines for ldap auth, also customize and enable ldap.conf in the default conf
    #auth_request /auth;
    #error_page 401 =200 /login;

    include /config/nginx/proxy.conf;
    resolver 127.0.0.11 valid=30s;
    set $upstream_portainer portainer;
    rewrite /portainer(.*) $1 break;
    proxy_pass http://$upstream_portainer:9000;
    proxy_hide_header X-Frame-Options; # Possibly nott needed after Portainer 1.20.0
}

location ^~ /portainer/api/websocket/ {
    include /config/nginx/proxy.conf;
    resolver 127.0.0.11 valid=30s;
    set $upstream_portainer portainer;
    rewrite /portainer(.*) $1 break;
    proxy_pass http://$upstream_portainer:9000;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_hide_header X-Frame-Options; # Possibly nott needed after Portainer 1.20.0
}

I don't think you need the three labels for websocket. Use http://mylaptop.com/portainer/ note the trailing slash, to access portainer.

1 Like

Thx , thats work
I'm now try with transmission but got error in chrome

redirected you too many times.

  • [Try clearing your cookies]

ERR_TOO_MANY_REDIRECTS

      - "traefik.http.routers.transmission.rule=Host(`mylaptop.com`) && PathPrefix(`/transmission/web`)"
      - "traefik.http.routers.transmission.middlewares=transmission-stripprefix"
      - "traefik.http.middlewares.transmission-stripprefix.stripprefix.prefixes=/transmission/web"
      - "traefik.http.services.transmission.loadbalancer.server.port=9091"

I try without middlewares bit still same

Some applications are not designed to be run behind reverse proxies on urls they know nothing above. May be transmission is one of them.

it's runing in nginx fine !!!

location ^~ /transmission {
    # enable the next two lines for http auth
    #auth_basic "Restricted";
    #auth_basic_user_file /config/nginx/.htpasswd;

    # enable the next two lines for ldap auth, also customize and enable ldap.conf in the default conf
    #auth_request /auth;
    #error_page 401 =200 /login;

    include /config/nginx/proxy.conf;
    resolver 127.0.0.11 valid=30s;
    set $upstream_transmission transmission;
    proxy_pass_header  X-Transmission-Session-Id;
    proxy_pass http://$upstream_transmission:9091;
}

location ^~ /transmission/rpc {
    include /config/nginx/proxy.conf;
    resolver 127.0.0.11 valid=30s;
    set $upstream_transmission transmission;
    proxy_pass http://$upstream_transmission:9091;
}

This nginx configuration does not rewrite url, so transmission is running on the url it thinks it's running. In traefik configuraration you are trying to change that.

Okay, but what is the correct way to do this in trafik v2.2?

I have the same problem, with nginx it works, not with traefik.

Any way to achieve this?

Thanks.

What does not work? If it's the same as in OP, then do not rewrite the url :wink:

1 Like

Thanks @zespri. I had the same issue in my set up and your solution works perfectly.

Is there a way to get /portainer or any other subdomain for that matter to redirect to /portainer/ or to prefix the trailing /?

Also, what is the best source for learning about how this works i.e. redirection and paths etc for reverse proxy services?

@tam481 please share working transmission configration

2 Likes

I am having a similar issue trying to use portainer in docker-compose 3.6
traefik:2.1.8

      - "traefik.http.routers.portainer-server.rule=Host(`host.com`) && PathPrefix(`/portainer`)"
      - "traefik.enable=true"
      - "traefik.backend=portainer"
      - "traefik.http.services.portainer-server.loadbalancer.server.port=9000"
      - "traefik.http.routers.portainer-server.entrypoints=websecure"
      - "traefik.http.routers.portainer-server.tls=true"
      - "traefik.http.routers.portainer-server.tls.certresolver=myresolver"
      - "traefik.http.middlewares.replacepathregex.replacepathregex.regex=^/portainer/(.*)"
      - "traefik.http.middlewares.replacepathregex.replacepathregex.replacement=$$1/portainer/"
      - "traefik.passHostHeader=true"

This kind of config was working fine on 1.7 version. But when I havent been able to find a correct configuration
Can somebody give me a hand ?

This is not a valid traefik 2 label. The middleware is not referenced in the router. Check the doco for the replacepathregex. Use the playground to make sure that the expression after replacement correspond to an actual path portainer application understands. Or use stripprefix similar to the OP (make sure you do not make the same mistake(s)).

I am hitting the same issue when trying to proxy transmission with traefik:

This is my configuration:

            "traefik.enable": "true",
            "traefik.passHostHeader": "true",
            "traefik.http.routers.transmissionGateway.entrypoints": "web-secure",
            "traefik.http.routers.transmissionGateway.tls.certresolver": "gandiLetsencrypt",
            "traefik.http.routers.transmissionGateway.tls.domains[0].main": "get.example.com",
            "traefik.http.routers.transmissionGateway.rule": "Host(`get.example.com`) && PathPrefix(`/transmission/web`)",
            "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme": "https",
            "traefik.http.routers.transmissionGatewayRedirs.rule": "hostregexp(`{host:.+}`)",
            "traefik.http.routers.transmissionGatewayRedirs.entrypoints": "web",
            "traefik.http.routers.transmissionGatewayRedirs.middlewares": "redirect-to-https"

This is the error:

time="2020-09-22T22:17:37Z" level=error msg="no server for the service transmission_prod" applicationID=/transmission/prod providerName=marathon

When hitting http://get.example.com It shows:

# 409: Conflict

Your request had an invalid session-id header.

To fix this, follow these steps:

1. When reading a response, get its X-Transmission-Session-Id header and remember it
2. Add the updated header to your outgoing requests
3. When you get this 409 error message, resend your request with the updated header

This requirement has been added to help prevent [CSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery) attacks.

`X-Transmission-Session-Id: bysih4xeXU2Ak3RTJQCWy0ZnyIh4ObnUSFZHfe4AKxhfOE0W`

What else do I need to configure to setup traefik behind https using traefik ?

Edit

I finally managed to access the webui by adding a / after /transmission/web, but the /transmission/rpc is still returning 404 (adding a ending slash to it does not help).

The transmission udp/tcp port is not visible publicly, is that an issue for the web client? How do I export UDP/TCP

Here is how I was able to fix this slash issue.