Multple Services (Ports) Same Host?

I am hoping to get some help here with configuring access with a external (non-docker) service with Traefik. Specifically my issue is I have a octoprint server on Ubuntu. I have created a toml file for the HTTP router and HTTP service and access to the Octoprint web interface works like all my other HTTP router and services configured with Traefik. I created the HTTP service to route to port 5000.

Where I need help is the webcam stream. Currently I can direct access the webcam stream at http://192.168.x.10:8002/?action=stream. If I access http://192.168.x.10:8002/ I get the uStreamer web help page. I have tried to make an additional HTTP route and service and a TCP route and service and could not get it to work either way. When using https://octoprint1.example.com/?action=stream it would redirect to the web UI on port 5000 rule.

I'm not sure what the best way to do this is. I tried to capture octoprint1.example.com with a pathprefix /?action=stream but couldn't really get that to work. I thought about it more and wonder should i try something like a multi-level subdomain of cam.octoprint1.example.com pointing to http://192.168.x.10:8002 with a addprefix of /?action=stream? However my understanding with this is that currently traefik is only generating certs for *.example.com. To use cam.octoprint1.example.com I would need a separate wildcard cert of *.octoprint1.example.com which I'm not exactly sure how to generate multi-level subdomain wildcard certs with Cloudflare.

I think this specific service needs to be set as a TCP router/service but I'm not sure what the best way to handle this is. Either trying to redirect just the /?action=stream URL to the correct port or utilize a multi-subdomain URL. I've spent quite a while looking through documentation and can't seem to find examples of how to configure this or what I'm doing wrong.

Here is my Octoprint file with the HTTP route/service and the most recent attempt at getting the webcam stream to work.

[http.routers]
  [http.routers.octoprint1-rtr]
      entryPoints = ["https"]
      rule = "Host(`octoprint1.example.com`)"
      service = "octoprint1-svc"
      middlewares = ["octoprint-ipwhitelist", "middlewares-basic-auth@file"]
      [http.routers.octoprint1-rtr.tls]
        certresolver = "dns-cloudflare"

[http.middlewares]
  [http.middlewares.octoprint-ipwhitelist.ipWhiteList]
    sourceRange = ["192.168.x.7", "192.168.x.10"]

[http.services]
  [http.services.octoprint1-svc]
    [http.services.octoprint1-svc.loadBalancer]
      passHostHeader = true
      [[http.services.octoprint1-svc.loadBalancer.servers]]
        url = "http://192.168.x.10:5000"

[tcp.routers]
  [tcp.routers.octoprint1cam-tcp]
      entryPoints = ["https"]
      rule = "HostSNI(`cam.octoprint1.example.com`)"
      service = "octoprint1cam-svc"
      [tcp.routers.octoprint1cam-tcp.tls]
        passthrough = true

[tcp.services]
  [tcp.services.octoprint1cam-svc]
    [[tcp.services.octoprint1cam-svc.loadBalancer.servers]]
      address = "192.168.x.10:8002"

If it uses http you can use a http router.

If you declare a fixed (sub-)domain in Host() (even multi-level), you don’t need a wildcard cert when using LE. You just need to create the DNS entry to point to Traefik.

It is usually best practice to use sub-domains for services, because the web-app might send redirects and links with full paths in the response, those don’t work when manipulating paths with StripPrefix.

1 Like

Thanks for the help. I was finally able to get it working.

The one thing that I noticed though was that I already have a DNS entry for octoprint1.example.com that is working. I may have been confused by your comment but I also added cam.octoprint1.example.com as a DNS entry pointing to Traefik (not sure if I was suppose to for the multi-level subdomain). With the cam DNS entry I was able to access cam.octoprint1.example.com but it said it was the self signed Traefik cert not my LE cert. I removed that entry for cam from DNS so I only have one for octoprint1.example.com and then cam.octoprint1.example.com worked as expected with my LE cert.

In the Octoprint app plugin Dashboard I had to enable the function "Disable nonce for Octoprint webcam" under the Webcam widget in Dashboard.

I was then able to get https://cam.octoprint1.example.com/?action=stream to work as the URL in the Webcam & Timelapse Stream URL in Octoprint. I do not get errors of mixed (secure and unsecure) content anymore.

[http.routers]
  [http.routers.octoprint1cam-rtr]
      entryPoints = ["https"]
      rule = "Host(`cam.octoprint1.example.com`)"
      service = "octoprint1cam-svc"
      middlewares = ["octoprint-ipwhitelist"]
      [http.routers.octoprint1cam-rtr.tls]
        certresolver = "dns-cloudflare"
  [http.routers.octoprint1-rtr]
      entryPoints = ["https"]
      rule = "Host(`octoprint1.example.com`)"
      service = "octoprint1-svc"
      middlewares = ["octoprint-ipwhitelist", "middlewares-basic-auth@file"]
      [http.routers.octoprint1-rtr.tls]
        certresolver = "dns-cloudflare"

[http.middlewares]
  [http.middlewares.octoprint-ipwhitelist.ipWhiteList]
    sourceRange = ["192.168.y.7", "192.168.y.10"]

[http.services]
  [http.services.octoprint1cam-svc]
    [http.services.octoprint1cam-svc.loadBalancer]
      passHostHeader = true
      [[http.services.octoprint1cam-svc.loadBalancer.servers]]
        url = "http://192.168.x.10:8002"
  [http.services.octoprint1-svc]
    [http.services.octoprint1-svc.loadBalancer]
      passHostHeader = true
      [[http.services.octoprint1-svc.loadBalancer.servers]]
        url = "http://192.168.x.10:5000"

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