ZoneMinder with Raspberry PI: How to Install and Setup
Last Updated on 22nd March 2024 by peppe8o
This tutorial will help you to install and setup ZoneMinder with Raspberry PI computer boards, also bringing some tricks to make it work from a common ZoneMinder issue on boot.
Monitoring your spaces with cameras can help you get a better life to check if something requires your attention and keep your home more secure from malicious people. ZoneMinder with Raspberry PI is a free solution to create a monitoring system with advanced zones management and controlling cameras from a wide number of producers.
What is ZoneMinder
ZoneMinder is an open-source video surveillance software system, that uses your hardware with any camera out of the box. It allows you to design a system as large or as small as you need.
It provides a complete surveillance solution allowing to use of any CCTV or security cameras for advanced management like analysis, recording and monitoring.
It includes different access alternatives like the main web page, where you can fully configure your installation, as well as the Google Play app (for Android) and iOS app (for iPhone).
It is composed of different modules each one performing a specific task on the overall system. They are mainly binary executables, Perl and PHP scripts.
The ZoneMinder source is also available on GitHub for contributions and issues raising.
For this tutorial, I’m going to use a Raspberry PI 3 Model A+ (with the 64-bit Raspberry PI OS) in order to give you the commands to get it working. Please consider that this computer board is ok to work with a few cameras at a low definition, as getting higher video flow analysis and recording will require more CPU and RAM. For a more complex camera monitoring system, I would suggest a Raspberry PI 4 computer module, while for professional services with dozen of cameras it will be better to use a server. Nevertheless, Raspberry PI computer boards are still a good solution for professionals in order to test the cameras’ interfacing before going to production.
What We Need
As usual, I suggest adding from now to your favourite e-commerce shopping cart all the needed hardware, so that at the end you will be able to evaluate overall costs and decide if to continue with the project or remove them from the shopping cart. So, hardware will be only:
- Raspberry PI 3 Model A+ (including proper power supply or using a smartphone micro usb charger with at least 3A) or newer Raspberry PI Board
- high speed micro SD card (at least 16 GB, at least class 10)
- IP Cameras (this tutorial uses as example the good IeGeek IG62)
Check hardware prices with the following links:
Step-by-step Procedure
Prepare the Operating System
As I will use a low-capacity Raspberry PI computer board (the RPI 3 model A+), I will install (and I suggest you to use) the Raspberry PI OS Lite, which grants a fast and headless OS. For people having the newest Raspberry PI computer board with a more performing CPU and more RAM and dealing with few cameras, you can also install the Raspberry PI OS Desktop, in this case working from its terminal.
Make sure that your OS is updated. From the terminal, please issue the following command:
sudo apt update -y && sudo apt upgrade -y
Additionally, I also suggest increasing the OS Swap Space. This will manage the moments when software requires more RAM than available, by using SD card space instead of freezing the OS.
You can use my Set Raspberry PI Swap Memory tutorial, and changing to 1000MB the Swap size.
Install and Prepare the Database
We need also to install a database. A good choice for Raspberry PI, compatible with ZoneMinder, is MariaDB. You can find more info on how to install and secure MariaDB in my LAMP on Raspberry PI tutorial. Nevertheless, the main commands are the following:
sudo apt install mariadb-server -y
Create the database with related user, and assign the proper permissions with the following terminal commands (copy-paste line by line). Please change the user name and user password (marked in red) with your preferred ones:
sudo su
mariadb
CREATE DATABASE zm;
CREATE USER zmuser@localhost IDENTIFIED BY 'zmpass';
GRANT ALL ON zm.* TO zmuser@localhost;
FLUSH PRIVILEGES;
exit;
exit
Please note that the database name (“zm”) is linked in the following DB preparation script from ZoneMinder. If you want to change the name, you will have to edit the default database configuration script by using the new name..
Install ZoneMinder
We can now proceed with ZoneMinder installation. As it is already available from Aptitude repository (even if not the very last release, but anyway it is a tested release for our distribution), we can perform this task with one command line:
sudo apt install zoneminder -y
It will also install all the required dependencies.
Now we must prepare the database configuration for ZoneMinder. The software brings a ready-to-use SQL script that makes all the job for us. It is available at /usr/share/zoneminder/db/zm_create.sql path.
So, we can perform all the database configurations with this single line command, where “zmuser” and “zmpass” must be changed with the ones set a few lines before. Please note that the password is attached with the “-p” option:
mariadb -u zmuser -pzmpass < /usr/share/zoneminder/db/zm_create.sql
This script will create all the required database structures, setting up the required tables with the needed columns and charsets.
Tweak Zoneminder configuration for Raspberry PI
Before starting the services, we need to perform some configuration tweaks in order to make it work. Without these tweaks you will get no camera streaming and the following error:
Socket /var/run/zm/zms-887029s.sock does not exist. This file is created by zms, and since it does not exist, either zms did not run, or zms exited early. Please check your zms logs and ensure that CGI is enabled in apache and check that the PATH_ZMS is set correctly. Make sure that ZM is actually recording. If you are trying to view a live stream and the capture process (zmc) is not running then zms will exit. Please go to http://zoneminder.readthedocs.io/en/latest/faq.html#why-can-t-i-see-streamed-images-when-i-can-see-stills-in-the-zone-window-etc for more information.
Coming from the zoneminder.service that is not starting at boot.
So, the following commands will set the proper file permissions for zm.conf and ZoneMinder cache, in order to have the software working at boot. Moreover, there are also some Apache tweaks that will complete the settings for Raspberry PI:
sudo apt install php libapache2-mod-php php-mysql
sudo chmod 740 /etc/zm/zm.conf
sudo chown root:www-data /etc/zm/zm.conf
sudo chown -R www-data:www-data /var/cache/zoneminder/
sudo adduser www-data video
sudo a2enmod cgi
sudo a2enmod rewrite
sudo a2enconf zoneminder
sudo systemctl reload apache2.service
sudo systemctl enable zoneminder.service
sudo systemctl start zoneminder.service
At this point, you should have your zoneminder.service correctly running (check it with the systemctl status command):
pi@raspberrypi:~ $ sudo systemctl status zoneminder.service
● zoneminder.service - ZoneMinder CCTV recording and surveillance system
Loaded: loaded (/lib/systemd/system/zoneminder.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2022-11-10 13:23:15 CET; 2min 54s ago
Docs: http://zoneminder.readthedocs.org/en/latest/
Process: 567 ExecStart=/usr/bin/zmpkg.pl start (code=exited, status=0/SUCCESS)
Main PID: 646 (zmdc.pl)
Tasks: 5 (limit: 191)
CPU: 14.428s
CGroup: /system.slice/zoneminder.service
├─646 /usr/bin/perl -wT /usr/bin/zmdc.pl startup
├─690 /usr/bin/perl -wT /usr/bin/zmfilter.pl --filter_id=1 --daemon
├─723 /usr/bin/perl -wT /usr/bin/zmfilter.pl --filter_id=2 --daemon
├─752 /usr/bin/perl -wT /usr/bin/zmwatch.pl
└─758 /usr/bin/perl -wT /usr/bin/zmstats.pl
Connect Zoneminder Web UI
Now, your ZoneMinder service should be up and running. You can reach it by using the Raspberry PI’s IP Address with the “/zm” trailing as URL in your favourite browser. For example, as my RPI has internal IP “192.168.1.178”, the complete URL will be “https://192.168.1.178/zm”. This will show the Privacy note:
Read the Privacy note. You will be able to use ZoneMinder only accepting it. To accept, scroll down at the end of the page and select “Accept” instead of “Decline” in the drop-down menù:
Then click Apply. This will show you the ZoneMinder Console:
Set ZoneMinder Timezone
The first suggested action is to correctly set the Timezone. For this task, please go to Options -> System:
Find the TIMEZONE variable and set it to your local timezone (Rome in my case):
Once set, please scroll down the page and click “Save”.
Enable Authentication
By default, there is no authentication for the web interface. I strongly suggest enabling it.
Basic authentication can be activated from Options -> System, setting the following highlighted as in the following picture:
Please note that the “AUTH_HASH_SECRET” isn’t the admin password, but a key to hash the user password. You will get your login credentials after the following picture in this tutorial.
Then scroll down and click save. You will go to the login page:
The default username and password are admin/admin.
You will be able to change the admin password (also this, strongly suggested) from Options -> Users menu, then clicking the “admin” user link.
Add a Camera
ZoneMinder makes no sense without cameras. You can add a lot of camera models (a list is available at https://wiki.zoneminder.com/Hardware_Compatibility_List).
Go to ZoneMinder Console and click the ADD button:
This will open the form to add cameras to your dashboard. One note: ZoneMinder names the cameras in their docs as “monitor”, so look for this term when searching their documentation. More info to add cameras is available at ZoneMinder docs.
For this tutorial, I’m going to use my IeGeek IG62 IP camera, which allows using the ONVIF (Open Network Video Interface Forum) protocol. So, identify the ONVIF link on the top right of the following page and click it:
After a scan of your network, the following page will show you the detected cameras in the related drop-down menu. Select your desired camera.
IMPORTANT NOTE: please note that the page asks also for a Username and Password. These are the camera credentials (NOT the ZoneMinder credentials) and should be provided by your camera producer. Sometimes these are also shown on your camera label. For IeGeek IG62, for example, the default is admin / admin:
Once selected the camera and added its credentials, please click the next “button”.
The following page will allow you to choose the profile from those exposed by your camera. In my case, my camera offers 2 possible resolutions. Consider that lower resolution requires less CPU and RAM both for live showing and alarm detection, so allowing our Raspberry PI to manage more cameras. You can perform tests monitoring the CPU and RAM usage with the “htop” command, so deciding in a second moment what resolution to use. To change the resolution, you will probably need to remove the camera and add it again with the changed profile.
Going forward with this tutorial, I will choose the high-resolution profile (1920×1080):
Then click “Save”.
The page goes back to the camera addition form, where you can name the camera with your preferred label:
All the other settings can be changed at any time by editing the camera settings. Scroll down to the “Save” button and click it.
For a somewhat strange reason, the old camera add form remains open in our browser:
You can close it with the “Cancel” button as the Camera settings have been already saved with the previous step. You can now go back to the ZoneMinder Console and see the camera active:
From the camera name link (green “Garage Camera” in the previous picture), you can go to the live preview. “Scale” settings will help to fit the preview into our screen, while the “Back” button (at the right side of this) will bring us back to the Console:
Configure ZoneMinder Zones and Alarms
Finally, we can set the alarm triggers for our camera. Before doing that, please consider that ZoneMinder uses different Camera functions in order to set what that camera does. This means, in a few words, that depending on the value set for camera function, our camera will record or not the live preview and record/trigger or not the events. A summary table for available functions follows:
Function | Live Recording | Event Recording |
None | None | None |
Monitor | Yes | None |
Modect | None | On Motion Detection |
Record | Continuous | Events of a fixed length will be generated (No motion detection) |
Mocord | Continuous | On Motion Detection |
Nodect | Continuous | Only on external Triggers |
I will set my camera for recording both live preview and triggering alarms on event detection. This means that I will use the “Mocord” function. To do it, please select the camera by clicking the selection box at the right side of your camera row and click the “Edit” button, as shown in the following picture:
Here you will find the camera properties editing form (already seen in the camera addition step). Please change the “Function” value to Mocord (or your preferred one):
Click “Save”. Back to ZoneMinder Console, it will show your camera set to Mocord and capturing:
By default, ZoneMinder sets the detection to the whole camera area with a single, full-screen “zone”. But we can fine-tune it by working with the zones. Please click the zone number for your camera:
This will open a new window listing all the zones configured for your camera. Depending on your camera size and your PC display size, the zones list can be found scrolling down the page or at the right side of the running live camera preview:
You can change a specific zone area and settings by clicking the zone name:
The new window will allow you to change all the settings for the zone like the name, triggers and points defining the zone area. In the settings table, the “Presets” will allow a fast configuration of camera sensibility settings for your alarms. I suggest testing different presets in order to find the one that better fits your needs and then fine-tuning it if required:
Moreover, the points list will allow you to manage the area covered by your zone by editing their position and/or deleting/adding the zone corners. You can edit their position both by defining the X and Y or dragging from the live preview the red area corners.
Click “Save” when finished. From the Zone menu, you can also create multiple zones on the same camera with the “Add new Zone” button. This will allow you to better name the alarms, so getting more info on what’s happening and where. The final result shows all the zones mapped in your area. For example, the following picture shows 2 zones: one in front of the garage and one in the walking area beside the garage:
Back to the ZoneMinder Console, for each camera, you will be able to see the events number and, by clicking on them, watch and export videos.
At any time, you can refine the events triggering from the zone editing page.
Final Operations
ZoneMinder allows setting more features like defining actions on event detection (like sending warning emails) and creating custom views that better fit your monitoring needs.
As the Raspberry PI micro SD card could be too small to continuously record video and events, you can also use my Automount USB storage with Raspberry PI OS Lite: fstab and autofs tutorial to get a USB storage mounted automatically at boot and then move the camera recording on that storage.
Finally, please refer to the ZoneMinder User Guide for the complete manual.
What’s Next
If you want to discover many other projects for your Raspberry PI, you can take a look at peppe8o Raspberry PI tutorials.
Enjoy!
Me sorprende que le funcione, yo tengo una Rapsberry Pi 4 con el Raspbian oficial y una camara IP tapo, sigo exactamente los mismos pasos y obtengo el siguiente error:
ERR [zmc_m2] [Unable to open codec for video stream
Obviamente no tengo video en zoneminder pero el streaming de mis cámaras funciona perfectamente en VLC o en mi móvil, el problema esta en el sistema o en el zoneminder, en foros le ocurre a mas gente, la configuración mostrada aquí no esta preparada para funcionar, probablemente falte instalar algún codec pero me resulta imposible solucionarlo.
Hi Miguel. Have you tried to use the “Source Type” setting in your Monitor options? From what I know, it includes “Libvlc” which should use the same VLC libraries