Traefik is blocking Zoneminder stream

Hello,

First, thank you for your work.

I am using Traefik on my personal server (Raspberry Pi) with several Docker containers. Zoneminder (CCTV software) is one of them.

My Zoneminder configuration is working. On local network, with local IP address, I can access the ZM dashboard and watch camera streams. It's using an apache web server to get IP camera streams, and display them on a single web page. The camera stream is collected with ffmpeg, via a http adress to the camera IP, with TCP protocol.

Now, I want to access ZM remotely, from outside my house, via https. I set everything correctly (port fowarding, DynDNS, Let's encrypt...). I can now access Zoneminder dashboard remotely. But I can't see camera streams, there is only a blank space. The log section of the software is also empty.

When I deactivate Traefik, and access ZM dashboard via public IP address, from another network, everything is working correctly and I can watch streams. That's why I think Traefik is blocking.

Http gives same result than https.

There is several topics about problems with reverse proxies and Zoneminder, but I don't know if it's related, and it's talking about Apache/Nginx reverse proxies. I don't know how to apply this to Traefik. Should I change something in the Apache ZM web server to make it work with Traefik ?



https://forums.zoneminder.com/viewtopic.php?t=27804

Here is my traefik.toml :

traefik.toml
[global]
checkNewVersion = true
sendAnonymousUsage = false

[api]
  insecure = true
  dashboard = true
  debug = true

[log]
  level = "DEBUG"

[providers]
  [providers.docker]
    exposedByDefault = false
    network = "traefik_webgateway"

[entryPoints]
 [entryPoints.web]
  address = ":80"
   [entryPoints.web.http]
    [entryPoints.web.http.redirections]
     [entryPoints.web.http.redirections.entryPoint]
      to = "web-secured"
      scheme = "https"
      permanent = true

 [entryPoints.web-secured]
  address = ":443"

[certificatesResolvers]
 [certificatesResolvers.default]
  [certificatesResolvers.default.acme]
   email = "XXXX@XXXX.fr"
   storage = "acme.json"
   caServer = "https://acme-v02.api.letsencrypt.org/directory"
   [certificatesResolvers.default.acme.httpChallenge]
    entryPoint = "web"

Here is my Traefik docker compose :

Traefik docker compose
version: "2"
services:
  traefik:
    image: traefik
    ports:
      - 80:80
      - 8080:8080
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /mnt/serveur/traefik/traefik.toml:/traefik.toml
      - /mnt/serveur/traefik/acme.json:/acme.json
    networks:
      - webgateway
    restart: always
networks:
  webgateway:
    driver: bridge

Here is my Zoneminder docker compose :

Zoneminder docker compose
version: "2"
services:
 zoneminder:
  restart: always
  privileged: true
  environment:
  - TZ=Europe/Paris
  - ZM_DB_HOST=zm_db
  - LANG=fr_FR.UTF-8
  - LANGUAGE=fr_FR.UTF-8
  - PUID=99
  - PGID=100
  - SHMEM=50%
  - INSTALL_HOOK=0
  - INSTALL_FACE=0
  - INSTALL_TINY_YOLO=0
  - INSTALL_YOLO=0
  ports:
  - 9999:9000
  - 8443:443
  - 8880:80
  image: mcdl/zoneminder:1.34
  labels:
  - "traefik.enable=true"
  - "traefik.docker.network=traefik_webgateway"
  - "traefik.http.routers.zoneminder-web.rule=Host(`XXX.XXX.XXX.fr`)"
  - "traefik.http.routers.zoneminder-web.entrypoints=web-secured"
  - "traefik.http.routers.zoneminder-web.tls=true"
  - "traefik.http.routers.zoneminder-web.tls.certresolver=default"
  - "traefik.http.middlewares.add-zm.addprefix.prefix=/zm"
  - "traefik.http.routers.zoneminder-web.middlewares=add-zm@docker"
  networks:
  - traefik
  volumes:
  - "/mnt/serveur/zoneminder/config:/config"
  - "/mnt/serveur/zoneminder/varcache:/var/cache/zoneminder"
networks:
 traefik:
  external:
   name: traefik_webgateway

How could I access ZM streams with Traefik ? Any help would be greatly appreciated :slight_smile:

Thank you !

I solved my problem. I had a bad configuration.

Since I didn't want to access Zoneminder with an URL looking like xyz/zm, I added the labels :

  • "traefik.http.middlewares.add-zm.addprefix.prefix=/zm"
  • "traefik.http.routers.zoneminder-web.middlewares=add-zm@docker"

in my Zoneminder docker-compose, so xyz would send me to xyz/zm without typing "/zm".
And the stream was sent by zoneminder to the adress :
https://xyz.fr/zm/cgi-bin/nph-zms?scale=...

But with my rule, I was looking at :
https://xyz.fr/zm/zm/cgi-bin/nph-zms?scale=...

So the path was wrong and I couldn't get the stream. I have to find a way to make it work with the prefix but at least my problem is solved.

Hi, were you able to solve this? Because I added prefix and my index.php and stream files still use /zm/ segment..
If I try manually to strip it, it works.. So is there a way to tell traefik to strip this /zm/ from all further references?

Traefik config:

http:

  routers:
    zoneminder.example.com:
      priority: 1
      entryPoints:
        - websecure
      rule: Host(`cam.example.com`)
      service: zoneminder.example.com
      middlewares:
        - zoneminder.example.com+addPrefix
        - zoneminder.example.com+replacePathRegex
        #- zoneminder.example.com+stripPrefix

  services:
    zoneminder.example.com:
      loadBalancer:
        passHostHeader: true
        servers:
          - url: 'http://192.168.255.12:50191'

  middlewares:
    zoneminder.example.com+addPrefix:
      addPrefix:
        prefix: /zm
    zoneminder.example.com+replacePathRegex:
      replacePathRegex:
        regex: "^/zm/index.php(.*)"
        replacement: "/index.php$1"
    zoneminder.example.com+stripPrefix:
      stripPrefix:
        prefixes:
          - "/zm"

Thanks!

Hi,

I gave up on removing the /zm, it was causing too much problems. Also, since I'm watching my IP cameras with another software called Home Assistant, I don't really care about zoneminder address anymore.

I can't have a look at it right now, but isn't there something to customize stream path in Zoneminder settings ? Maybe it could work.

I was able to solve the issues described by first stripping off any "/zm" prefix, then adding the /zm prefix, so there would only ever be one "/zm" prefix on the request going to the backend service.

http:
  routers:
    zoneminder:
      entryPoints:
        - websecure
      middlewares:
        - strip_extra_zm@file
        - add_zm@file
      rule: "Host(`zm.example.com`)"
      tls: { }
      service: zoneminder
  middlewares:
    add_zm:
      addprefix:
        prefix:
        - "/zm"
    strip_extra_zm:
      stripprefix:
        prefixes:
        - "/zm"