Zoneminder NVR 1.34 Docker by dlandon includes object vision

Hi All,
I figure if it takes me a while to set up, documenting it may help others who stumble across this page.
SO FIRSTLY - important note - dlandon’s docker contains a bunch of options to enable face / object detection with yolo/tiny and others. This made it more interesting to me as I was shifting back from Shinobi.

My set up is on a docker using IP cameras (some Wifi most PoE) and a Synology NAS reverse proxy (NGINX) under the hood.
I use (this hits my Synology Box which forwards the relevant subdomain to the correct IP and port).

SECONDLY - dlandon has done a great job, even down to autocreating self-signed certs etc to make like easier!

LASTLY - before the steps, the Zoneminder component is also very well built and makes ingesting the components (cameras, switches etc super easy).
Step 1: run the command to show GUID and PUID:
Step 2: Docker command (info here)

docker run -d --name="Zoneminder" \
--net="bridge" \
--privileged="true" \
-p 8080:80/tcp \
-p 9000:9000/tcp \
-e TZ="America/Los_Angeles" \
-e SHMEM="50%" \
-e PUID="1000" \
-e PGID="1000" \
-v "/home/docker/Zoneminder":"/config":rw \
-v "/home/docker/Zoneminder/data":"/var/cache/zoneminder":rw \

Notice the changes I made. I also plan to add a mount to my Synology NAS storage, but that’s down the list.
It takes a fair while to build the first time so be patient.

Step 3: Configure Zoneminder:
i) Add Monitors
ii) customise alarm settings
iii) Add associated zones
v) Enable 3rd Party Event Server
vi) create a new admin user, be sure to provide adequate access.
vii) Enable Auth login

Step 4: Edit the secrets.
for whatever reason I only got a result with this, not the other one. not sure why:


zm_user & zm_pass are from the new admin user you just created
zm_portal for testing should be http://<IP_of_docker>:8080/zm
same for api http://<IP_of_docker>:8080/zm/api
make sure to add the IP_of_docker to the top line of the “ServerName” file under the keys folder:


Now delete the .key and .crt files (ZM will recreate them) and restart)

Step 5: Download ZMninja (PC or iOS - if you want to test FCM alerts you’ll need the paid iOS app.

Step 6: Edit the zmeventnotification.ini
I use MQTT so set the correct IP address and credentials.
I left this as default so use WSS (not WS):

# Enable SSL (default: yes)
enable = yes

cert = !ES_CERT_FILE
key = !ES_KEY_FILE

I amended this (but only as I had chosen to enable that in the docker).

use_hooks = yes

Step 7: Test local setup. Use ZMninja to connect to the docker.
using ZM Authentication add the new user creds you created
use the url http://<IP_of_docker>:8080/zm (the others should auto-populate)
save settings, and then check the “Event Server”. this should be:

If it is working correctly, ZMninja should offer to alert you. you can always turn off websockets and use FCM in the Event Server menu.

Step 8: prepare your Synology box for incoming traffic. This is pretty unique to each person, but hopefully this will give you the idea. -> Nameserver A record -> public IP of my Synology -> IP address and port (remembering to forward port 443 on your router to the Synology IP address)

I use two subdomains, one for the portal, and one for the zmninja websockets.
Once you have validated everything works internally, now is the time to move to your subdomain A records on your provider.

First off add 2 new reverse proxies in the application portal.
https 443 —> http 8080 <IP_of_docker>
zmninja 443 —> https 9000 <IP_of_docker> (note https as WSS)

You will need to edit the zmninja one to enable parsing of websocks [(info here)](``` ZMES_PICTURE_URL=http://<IP_of_docker>:8080/zm/index.php?view=image&eid=EVENTID&fid=snapshot&width=600 ````)

You will need to change secrets.ini
zm_portal is now (no port)
same for picture:


You will also need to make the changes in the ZMninja App
including the event server.


Updated as now 1.34

Works well with object/person detection and sends alerts to MQTT :slight_smile:

Do you have MQTT sensors setup in HA to let you know about detections?

I actually use Node-red. Then do the processing from there.
Haven’t quite figured out how to grab the image from Zoneminder yet though.

But Zoneminder event service sends the topic

There is JSON output with a name that includes what is detected, percentage of confidence, monitor number etc.

I’ve also asked on the community if that output of JSON can be customised

Odd mine doesn’t ever create the zoneminder topic in MQTT likely have something configured wrong.

In the zmeventnotification.ini have you set the MQTT host, username and password?

Also for some reason some of the monitors are excluded (I think it happens if you turn on the “3rd party event service” in options before you add some monitors).
Also assuming you did that step too.
Best way to check is to open the Zoneminder logs console and select

Walk in front of a camera and check it triggers the alarm. For that it needs the zone set up for that monitor (not sure what you have / haven’t done so listing all I can remember). Then the Monitor should be on Modect.
That alarm should then trigger the hook (and for that you need the hook enabled in the docket, and also the right object vision model - I use tiny yolo). You also need to ensure use_hooks = yes (again off memory right now) in the zmevennotication.ini (and that your zm_detect and start scripts are there - should be by default in 1.34)

Assuming all that is set up, it will scan the object and the logs should either give you a successful scan.
After which you’ll see what it sends the result too.
Initially in my log I had something like “not sending alarm as monitor excluded”

To fix that I had to go into ZMNinja mobile app (iOS) and under settings > event server > monitor (open up each monitor and ensure it was enabled to send alerts).

Also check when MQTT is being sent alerts. In one of the .ini files only “fcm, web” was selected. You can either change that to “all” or “mqtt, fcm” for example.

HTH troubleshoot

1 Like

Ya configured the MQTT info.

I get events showing zmeventnotification’s bit showing up in the log about Monitor 1 (the only camera I have currently)

Yup regular Modect is working fine and triggers the hook.

Just stick that somewhere at the end of the ini?

I’ll look into that when I’m off work.

This might be the issue, I’ll have to comb through the files again.

Thanks for your input.

its in zmeventnotification.ini around line 105 (before the [hook] section.
Should be set by default, but always worth checking.

Good luck
Oh and also found out I can grab the alarm snapshot using the URL:


next up to use HA to send as an alert and test the timing

1 Like

and just for posterity this is for the event video:](https://url/zm/index.php?username=blah&password=blah&action=login&view=view_video&eid=eventID#&fid=snapshot&width=600)

I noticed the ini files I was using were from a previous version. I’ve made modifications to the defaults and re-created the ini files, hopefully this will help :slight_smile:

ah yeah i ended up starting again at 1.34 as I couldnt get all the things working in 1.32

FYI - the Eventserver has been updated to allow customization of the JSON as per this Github:

Ya I got it working seems some of the models didn’t download since I was just upgrading from the old docker image. Got it all sorted. I’ll wait for the container to get update with the new JSON string stuff. :slight_smile:

Nice to see what you guys are doing. I have integrated Zoneminder alerts with HA via AppDaemon. Working nice, I am using it to send alert text messages with image from the object detection provided by ZM-ES. Take a look at this discussion thread:

I am now working to enable GPU acceleration via OpenCV + Yolo3. I am running on unraid using the dlandon/zoneminder docker container.

Anxious to hear if anyone is running with CUDA acceleration.


I don’t use docker but the detection supports CUDA. I am using CUDA on my system. When I find time I’ll update the code to leverage the huge performance improvements in OpenCV 4.1.2

Please note there was an issue with my tokens.txt file when using ZMninja iOS app.

The tokens file only showed one monitor and the logs wouldnt send alerts.

i edited this file to show:

This enabled the remaining monitors to send alerts (in my case monitors 1,2,3,4,5 & 6).


I’ve just released 5.4.7 of the ES that leverages OpenCV 4.1.2’s CUDA DNN backend support. While your performance improvements will vary depending on what CPU and GPU you have, here are some of my performance observations on my low(-ish)-end GPU

For those looking to leverage CUDA with docker images, looks pretty straight forward, at least theoretically. Like I said, I don’t use docker.

All that being said, I am not sure if dlandon will directly add CUDA support to his docker image. If I recall, his primary audience is the unraid community and I’m not sure that supports a GPU. You should however be able to modify his docker compose and do it yourself as another option and then run either local detection (packaged in his image) or remote detection (mlapi)

Thank you for the response… looking forward to the new release. I am responding to your edits…
Here are a few notes:

  • UNRAID support NVIDIA GPUs via ‘UNRAID Nvidia plugin’. There are several tutorials on how to leverage this plug for plex docker (hardware decoding for video).
  • dropped into the docker container for dlandon/zoneminder to check the python modules.
    opencv-contrib-python (
    opencv-python (
    I find this a bit confusing since I have read it should be one or the other (not both).
  • also did a quick check by running cv2.getBuildInformation() and see the following as unavailable:
    cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev

Isn’t opencv the critical python module to provide GPU acceleration via nvidia-cuda?
I guess I will start getting up to speed on building docker images …


  • UNRAID support NVIDIA GPUs via ‘UNRAID Nvidia plugin’. There are several tutorials on how to leverage this plug for plex docker (hardware decoding for video).

Good to know. I’ve asked dlandon on slack if he plans to add support, but unless he has a GPU himself, it would be hard to test. I’ll leave it to him to decide. You may also want to ask him directly.

  • dropped into the docker container for dlandon/zoneminder to check the python modules.
    opencv-contrib-python (
    opencv-python (
    I find this a bit confusing since I have read it should be one or the other (not both).

Correct. Only opencv-contrib-python is required. This was actually an error on my side - my old instructions suggested both which I have since changed. Also note that if you go the pip route, OpenCV will not have GPU support, so you really do need to build from source. See this.

  • also did a quick check by running cv2.getBuildInformation() and see the following as unavailable:
    cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev

Correct. The odd part is even if you install opencv-contrib-python it seems to leave out certain packages. This affects software like zmMagik but not what you are using. However, this entire point is moot with pip install because GPU support is not built in anyway. Therefore, go with source compilation

Coming to docker: I’ve let dlandon know of these issues on slack. The advantage of the pip route is it is quite fast and doesn’t need the various dev packages for source build, but the negative is you won’t get GPU support this way. Building opencv from source takes a very long time (a function of your system specs though). I’m not familiar enough with docker to know if a source build can be catered to as an additional layer/host link/whatever, but maybe some of you who are very familiar with docker can work with dlandon directly and figure out the best path.

1 Like

Yep, I read the pyimagesearch article you provide in your docs. Makes sense now that you have to build from scratch given the vast set of Nvidia cards + cuda versions. Wondering if adding an option to dlandon/zoneminder to pull from an alternate pypi server would simplify this? I am in the process now of creating an internal pypi server and building opencv python package. This internal pypi server can redirect for any packages not available locally.