Traefik and Docker : Proxy the Dashboard as site sub-path

How have a docker-compose to be configured to proxy the dashboard to [myDomain.at/node-red-dashboard] (http://myDomain.at/node-red-dashboard) ?
current path : http://myDomain.at:1880/ui
->
http://myDomain.at/node-red-dashboard
Thanks!

Have you followed along with the excellent recent tutorial and NR, Traefik, SSL and Docker ?

You can see it here

Craig

I am using traefik (version 2) to proxy the node-red dashboard and node-red editor.
... but in order to proxy the dashboard I had to append /ui to the URL.

Note that I couldn't get traefik authentication working in combination with the node-red editor or node-red UI authentication. So to fix this I had to disable the node-red editor and node-red ui authentication.

Not sure exactly what your problem is.

I am using traefik (version 2) to proxy the node-red dashboard and node-red editor.

this is working fine.

... but in order to proxy the dashboard I had to append /ui to the URL.

this is working too.
But I want to separate the dashboard from the node-red editor by using another URL. The reason is to expose the GUI without access to the editor.

Example:
traefik shall route
.) editor.myDomain.local to the node-red editor and with /ui to the dashboaed
.) gui.myDomain.local or myDomain.local/gui to the dashboard only

I see. That is a bit more sophisticated setup than mine.

Is it not possible to achieve this by defining a separate traefik "router" for dashboard and another one for editor ?

FYI - here an extract of my docker-compose configuration:

  traefik:
    build: traefik
    container_name: "traefik"
    restart: always
    command:
      #- "--log.level=DEBUG"
      #- "--accesslog=true"
      - "--api.dashboard=true"
      #- "--api.insecure=true"
      - "--providers.file.filename=config.yml"
      - "--providers.file.watch=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.email=${MY_EMAIL_ADDRESS}"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
      # The Web UI (enabled by --api.insecure=true)
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./letsencrypt:/letsencrypt"
    environment:
      # WAN_HOSTNAME is used in traefik config.yml file !
      - WAN_HOSTNAME
    labels:
      - "traefik.enable=true"
    # Tell Traefik to use the port opened for the traefik web ui to connect to.
      - traefik.http.services.traefik.loadbalancer.server.port=8080
    # HTTP (LAN) connection
      - "traefik.http.routers.traefik_lan.rule=Host(`traefik.${LAN_HOSTNAME}`)"
      - "traefik.http.routers.traefik_lan.service=api@internal"
      - "traefik.http.routers.traefik_lan.entrypoints=web"
    # HTTPS (WAN) connection
      - "traefik.http.routers.traefik_wan.rule=Host(`traefik.${WAN_HOSTNAME}`)"
      - "traefik.http.routers.traefik_wan.service=api@internal"
      - "traefik.http.routers.traefik_wan.entrypoints=websecure"
      - "traefik.http.routers.traefik_wan.tls.certresolver=mytlschallenge"
      - "traefik.http.routers.traefik_wan.middlewares=traefik_auth"
      - "traefik.http.middlewares.traefik_auth.basicauth.users=${BASIC_AUTH_USER_PASSWORD}"
      - "traefik.http.middlewares.traefik_auth.basicauth.removeheader=true"
...
  node-red:
    build: node-red
    #privileged: true
    volumes:
       - 'node-red-data:/data'
    depends_on:
        - mqtt
    restart: always
    environment:
      - TZ=Europe/Brussels
    env_file:
      - .env.node-red
    labels:
      - "traefik.enable=true"
    # HTTP (LAN) connection
      - "traefik.http.routers.nodered_lan.rule=Host(`node-red.${LAN_HOSTNAME}`)"
      - "traefik.http.routers.nodered_lan.entrypoints=web"
      - "traefik.http.routers.nodered_lan.middlewares=traefik_auth"
    # HTTPS (WAN) connection
      - "traefik.http.routers.nodered_wan.rule=Host(`node-red.${WAN_HOSTNAME}`)"
      - "traefik.http.routers.nodered_wan.entrypoints=websecure"
      - "traefik.http.routers.nodered_wan.tls.certresolver=mytlschallenge"
      - "traefik.http.routers.nodered_wan.middlewares=traefik_auth"

... maybe the "Add Prefix" option have to be used, but how ?

  - traefik.http.routers.nodered.middlewares=add-ui
  - traefik.http.middlewares.add-ui.addprefix.prefix=/ui

when looking at https://docs.traefik.io/routing/routers/
I would expect something like:

"traefik.http.routers.nodered_wan.rule=(Host(`node-red.${WAN_HOSTNAME}`) && Path(`/ui`))"

Isn't that the wrong way round? I thought @Noschvie wanted a request of http://myDomain.at/node-red-dashboard to be routed to the /ui path in node-red, rather than routing based on a request of /ui?

Yes, the "URL rewriting" is the challenge.
Thanks for clarification!

I focused on the above user request which didn't exclude the use of paths in the URL.

So you can expose the GUI by defining a traefik router for path /ui which won't give you access to the editor.

How to define the traefik router for path /ui ? See snippet below, thanks!

  nodered:
    image: ctmagazin/ctnodered:latest
    container_name: node-red
    restart: always
    volumes:
      - nodered_data:/data
      - /etc/localtime:/etc/localtime
    environment:
      - TZ=Europe/Berlin
    labels:
    #### Labels define the behavior and rules of the traefik proxy for this container ####
      - traefik.enable=true                   # <== Enable traefik to proxy this container
      # The domain the service will respond to
      - traefik.http.routers.nodered.rule=Host(`dashboard.mydomain.at`)
      # Allow request only from the predefined entry point named "web"
      - traefik.http.routers.nodered.entrypoints=web
      - traefik.http.routers.nodered.middlewares=add-ui
      - traefik.http.middlewares.add-ui.addprefix.prefix=/ui
      - traefik.http.routers.nodered.middlewares=auth
      # Declaring the user list
      - traefik.http.middlewares.auth.basicauth.users=admin:<password>

Oh yes, I see what you mean.

I think for node-red we must use PathPrefix and not Path

I have changed your docker-compose for this.

... one thing to double check (as we use PathPrefix) is to check if this doesn't give access to the node-red editor by using the path dashboard.mydomain.at/ui/.. or dashboard.mydomain.at/ui../

  nodered:
    image: ctmagazin/ctnodered:latest
    container_name: node-red
    restart: always
    volumes:
      - nodered_data:/data
      - /etc/localtime:/etc/localtime
    environment:
      - TZ=Europe/Berlin
    labels:
    #### Labels define the behavior and rules of the traefik proxy for this container ####
      - traefik.enable=true                   # <== Enable traefik to proxy this container
      # The domain the service will respond to
      - traefik.http.routers.nodered.rule=Host(`dashboard.mydomain.at`) && PathPrefix(`/ui`)
      # Allow request only from the predefined entry point named "web"
      - traefik.http.routers.nodered.entrypoints=web
      # JVA - traefik.http.routers.nodered.middlewares=add-ui
      # JVA- traefik.http.middlewares.add-ui.addprefix.prefix=/ui
      - traefik.http.routers.nodered.middlewares=auth
      # Declaring the user list
      - traefik.http.middlewares.auth.basicauth.users=admin:<password>

In the way already suggested by @janvda by adding the path requirement to the Host spec. Isn't it

PathPrefix(`/ui`)

though?
However I think your orginal suggestion with the different urls could also work if in addition you use addPrefix to add the /ui
https://docs.traefik.io/middlewares/addprefix/

I am also wondering if you should not define all middlewares for a specific router on one line instead of 2 lines.
So like this:

 - traefik.http.routers.nodered.middlewares=add-ui,auth

I had missed that adddprefix has been included in the second example.
So what isn't working?

with this options it's working.
Perfect, thanks and all the best!
Norbert

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.