Traefik v2.5 no redirecting to portainer portal

I am trying to get traefik work with portainer but nothing so far. My goal is to just type http://localhost/portainer and let traefik redirect to portainer portal.

So far my docker-compose looks like this:

services:
  reverse-proxy:
    image: traefik
    container_name: "traefik"
    networks:
      - traefik_net
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "./traefik.yml:/traefik.yml:ro"

    portainer:
      image: "portainer/portainer-ce"
      container_name: "portainer"
      networks:
        - traefik_net
      volumes:
        - "/var/run/docker.sock:/var/run/docker.sock"
        - portainer_data:/data"
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.portainer.entrypoints=web"
        - "traefik.http.routers.portainer.rule=Host(`localhost`) && PathPrefix(`/portainer`)"
        - "traefik.http.services.portainer.loadbalancer.server.port=9000"
networks:
  traefik_net: {}
volumes:
  portainer_data:

And my traefik.yml file is:

log:
  level: INFO

api:
  insecure: true
  dashboard: true

entryPoints:
  web:
    address: ":80"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

I really do not know what is going on. When I try to connect to http://localhost/portainer I get 404 not found .

The dashboard is working fine. When I check the portainer servece is has the docker ip for portainer container and also the port 9000 so I think the problem is with the traefik receiving and redirecting the url to the portainer container.

Any help is welcomed, thanks.

I can do that but that would make traefik useless. The whole thing is to use traefik to redirect to the containers when it sees a user defined url string. If I open the port 9000 and use localhost:9000 then Iā€™m accessing portainer directly.

Hello,

the problem is related to the path.

A working example without a path
version: '3.7'

services:

  reverse-proxy:
    image: traefik:v2.5.4
    command:
      - --log.level=INFO
      - --api.insecure
      - --api.dashboard
      - --entrypoints.web.address=:80
      - --providers.docker.exposedbydefault=false
    container_name: traefik
    networks:
      - traefik_net
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"

  portainer:
    image: portainer/portainer-ce:2.9.1-alpine
    container_name: portainer
    networks:
      - traefik_net
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - portainer_data:/data"
    labels:
      traefik.enable: "true"
      traefik.http.routers.portainer.entrypoints: web
      traefik.http.routers.portainer.rule: Host(`portainer.localhost`)
      # traefik.http.routers.portainer.rule: Host(`localhost`) && PathPrefix(`/portainer`)
      traefik.http.services.portainer.loadbalancer.server.port: 9000

networks:
  traefik_net: {}
volumes:
  portainer_data:

Portainer doesn't really support a subpath.

Thanks. I will try this later and see. I guess I need to pass the Host name to curl or something for this to work without modifying the machine hostname.
I will come back later for results. I will also try other containers.

The xxx.localhost domains work by default.

I really don't understand how this technology works.

So I'm trying other thing to see if something work.

Goal: Go to url http://localhost/app and see the hello world in the browser.

Settings:

services:
  reverse-proxy:
    image: traefik:v2.5
    container_name: "traefik"
    networks:
      - traefik_net
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.yml:/traefik.yml:ro

  nginx:
    image: "training/webapp"
    container_name: "webapp"
    ports: 
      - 7080:5000
    networks:
      - traefik_net
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webapp.entrypoints=web"
      - "traefik.http.routers.webapp.rule=Host(`localhost`)&&Path(`/app`)"
#      - "traefik.http.services.nginx.loadbalancer.server.port=9000"
networks:
  traefik_net: {}

My traefik config file:

##STATIC COMFIGURATION
log:
  level: INFO

api:
  insecure: true
  dashboard: true

entryPoints:
  web:
    address: ":80"

providers:
  docker:
    endpoint: unix:///var/run/docker.sock
    exposedByDefault: false

What I get if I go to http://localhost:7080 is hello world as expected.

BUT!!! If I go to http://localhost/app receive a page not found which is from the web app server. My point is how difficult is to act as a reverse proxy? I used nginx and everything works as expected. Try to use traefik to redirect to nginx and receive the same 404 not found from the nginx server not the traefik server, it seems that traefik is forwarding something it should not to nginx and the web app.

If anyone knows what is happening please clear this enigma for me.

Ps: All this is from a local network environment. I don't know if traefik need for an actual domain name to work properly. That is the only thing I have not done yet.

You just have to take my docker-compose file in my previous post:

The problem with the path is related to Portainer not to Traefik.

Don't expose your ports, because you don't need to do that.

The management of the path always depends on how your application handles the baseurl or the paths.

A simple example with a whoami and a path
version: '3.7'

services:

  reverse-proxy:
    image: traefik:v2.5.4
    command:
      - --log.level=INFO
      - --api.insecure
      - --api.dashboard
      - --entrypoints.web.address=:80
      - --providers.docker.exposedbydefault=false
    container_name: traefik
    networks:
      - traefik_net
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"

  whoami:
    image: traefik/whoami:v1.6.0
    labels:
      traefik.enable: 'true'
      # traefik.http.routers.whoami.rule: Host(`whoami.localhost`)
      traefik.http.routers.whoami.rule: Host(`localhost`) && PathPrefix(`/whoami`)
      traefik.http.routers.whoami.entrypoints: web
    networks:
      - traefik_net

networks:
  traefik_net: {}
A simple example with a training/webapp and a path
version: '3.7'

services:

  reverse-proxy:
    image: traefik:v2.5.4
    command:
      - --log.level=INFO
      - --api.insecure
      - --api.dashboard
      - --entrypoints.web.address=:80
      - --providers.docker.exposedbydefault=false
    container_name: traefik
    networks:
      - traefik_net
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"

  training:
    image: training/webapp
    labels:
      traefik.enable: 'true'
      # traefik.http.routers.training.rule: Host(`training.localhost`)
      traefik.http.routers.training.rule: Host(`localhost`) && PathPrefix(`/training`)
      traefik.http.routers.training.entrypoints: web
      traefik.http.routers.training.middlewares: strip

      traefik.http.middlewares.strip.stripprefix.prefixes: /training

    networks:
      - traefik_net

networks:
  traefik_net: {}

All my examples work without any extra files: click on the arrows and to copy-paste the content to your docker-compose.yml file.

As you are using a dedicated network (traefik_net) don't forget to clean your environment:

docker-compose down

or

docker network prune

Hi,
to do this work you have to strip /portainer prefix. Look at this doc - Traefik StripPrefix Documentation - Traefik - " Use a StripPrefix middleware if your backend listens on the root path (/) but should be exposed on a specific prefix."

Just add the below-mentioned to the labels:

  • "traefik.http.middlewares.remove-path.stripprefix.prefixes=/portainer"
  • "traefik.http.routers.portainer.middlewares=remove-path@docker"

Regards,

Yuriy