Select your language

February 2022 - Here is my proven method for installing Zoneminder v1.34 on the Raspberry Pi 4 using only the Raspberry Pi distribution. Not using the ZMRepo site.

The following makes a number of assumptions:

  • A Raspberry Pi 4 with 8GB RAM - 4GB will be sufficient but more is better.
  • Networked camera(s) with ONVIF support.
  • Your knowledge of Linux is at least moderate ie. use of Linux shell for file editing and other basic command line functions.

The following are optional:

  • A local NAS system which supports NFS sharing and MariaDB server.
  • You have a useable SSL certificate for your server.
  • You will access the Zoneminder system remotely via the Internet.

The final outcome is a headless Raspberry Pi dedicated to Zoneminder operations using Apache 2.4 as the HTTP/HTTPS server and a remote NAS system for storage of the Zoneminder database and associated image/video files.
It is possible to use the local storage of the Raspberry Pi if no NAS is available and this will be indicated in the instructions but due to the nature of SDcard storage it has a limited lifespan and reliability will degrade over time.
The system also includes SSL encryption for the web server (which is seen as almost mandatory in this day and age). However, if no certificate is available then basic HTTP can be used. This will also be indicated in the text. If you do not have a SSL certificate for your domain then simply ignore the SSL sections.

Let's get started

Working on the local PC system we need to create a Raspios SDcard - I use a Linux desktop using the dd command but it is fairly simple to use a Windows system to prepare the SD card by following the instruction from the Raspberry Pi web site.

Download the latest Raspios image from the official site. The file will arrive compressed as zip, tar, gz etc.
Extract the image using tar, winzip or whatever suits your system.

Write the image to SDcard - Note that it is important to use the correct output device, in my case /dev/sdb, it is easy to destroy the local machine file system if the wrong device is specified. Check and check again.

dd if=<path-to-image-file> of=/dev/sdb bs=16M

Once the image write completes the two partitions ´boot´ and ´rootfs´ should automatically mount.
(Debian 10 with Cinnamon desktop mounts automatically to /media/uname/ folder)
You may have to manually mout the SDcard for the next stage.

To avoid having to attach a screen and keyboard to the Pi we enable SSH connections on first boot but it is entirely possible to use the Pi directly by connecting a screen, keyboard and mouse.

touch /path-to/boot-partition/ssh

Windows users should simply create a new empty file called 'ssh' (with no filename extension) in the root of the boot partition.

If SSL is not being used then skip this item.

To save effort later we copy the ssl certificate files to the target folder. Windows users will not normaly have access to the rootfs partition as it is formatted as a linux filesystem. In this case it is easier to copy the files to the boot partition and later, when logged onto the Pi you can just move the files to the correct target '/etc/ssl/private' .

cp /path/to/cert-files/* /path-to/rootfs-partition/etc/ssl/private/

Unmount and remove the SDcard

Working on the Raspberry Pi

Note: The Pi must be on a wired network for this process, to setup WiFi access the system must be used with a screen, keyboard and mouse to enable the WiFi interface. Since this machine will be used as a dedicated webcam surveillance system I would highly recommend using a wired network at minimum 100Mb/s rather than a wireless network. If you set up WiFi and then follow the remaining procedure then the system will no doubt function but performance may be compromised.

Install the SDcard
Boot the Pi
System will automatically expand filesystem and reboot

Identify the machine on the network to determine the ip address
Using your favourite SSH client (PuTTY is my choice) connect via SSH (port 22) and login with 'pi' / 'raspberry'.

start raspi-config.

sudo raspi-config

Within 1. System Options:

  • Set a new 'pi' password
  • Set hostname
  • Set boot mode to 'Console only'

Within 4. Performance Options

  • Set GPU memory = 512M

Within 5. Localisation Options

  • Set your locale

Within 6. Advance Otions

  • Disable xcompmgr with the A3 Compositor option

<Finish> and allow system to reboot.

Login with 'pi' / 'new-password'

For simplicity I prefer to work as a root user - we are in a single user system at this point and the same disasters can happen using sudo, but if you prefer you can omit the 'sudo su' command and then precede all the commands with sudo if that makes more sense.

First ensure the system is up to date and then install some necessary software.

sudo su

apt update && apt upgrade -y

apt install apache2 mariadb-server nfs-common -y

apt install php libapache2-mod-php php-mysql -y

At this stage if you do not wish to use a NAS for storage skip to 'Install Zoneminder' below.

Set-up NFS share

We need a NFS connection so create the target folder.

mkdir /nfs && mkdir /nfs/public

Add the NAS share to fstab, the location of the share on the NAS system will be different on your system so use the correct ip address and exported folder name as appropriate.

echo "192.168.1.250:/nas-share/folder /nfs/public nfs defaults 0 0" >> /etc/fstab

Mount the share.

mount -a

Test the share by creating the ZM-Log folder - if this fails then the problem could be misconfigured NFS exports at the server or incorrect permissions. There is much info available to resolve share problems. Resolve any issues before moving to the next stage or just do not use remote storage for the time being.

mkdir /nfs/public/ZM-Log

Install Zoneminder

apt install zoneminder

Create an empty database called 'zm' on the server and create a user called 'zmuser' with required privileges.
I typically use phpMyAdmin for this but you could use the mysql command and manually issue the commands.

mysql --host=<server-ip> --port=<port> -u root
Enter password:
Welcome to the MariaDB monitor. [... Intro cut out ...]
MariaDB [(None)]>
MariaDB [(None)]>create database zm;
MariaDB [(None)]>grant all on zm.* to 'zmuser'@'%' identified by '<db-password>';
MariaDB [(None)]>quit;

Build Zoneminder database on target server, replace <server-ip> with that of your server or 127.0.0.1 for the local Pi and <port> with 3306 as default but my NAS uses port 3307. Note: the following command is all one line.

mysql --host=<server-ip> --port=<port> -p -uzmuser zm < /usr/share/zoneminder/db/zm_create.sql

Add www-data user to video group.

adduser www-data video

Edit php.ini to set your timezone.

nano /etc/php/7.4/apache2/php.ini

Search (ctrl-w) for the text '[Date]'
Uncomment the 'date.timezone' line add 'Europe/Lisbon' - or your own timezone identifier.
Save the file (ctrl-o) and exit (ctrl-x)

Now enable various required apache modules.

a2enmod headers rewrite cgi expires SSL Certificate

If you do not wish to use a SSL certificate then skip to 'Zoneminder Configuration' below.

Windows users should now move the certificate files from the /boot area to the /etc/ssl/private folder.

Enable the Apache ssl module.

a2enmod ssl

chmod/chown the certificate files copied previously to comply with security.

chmod 640 /etc/ssl/private/*
chown root:ssl-cert /etc/ssl/private/*

Edit the default-ssl.conf file to include the correct certificate entries.

nano /etc/apache2/sites-available/default-ssl.conf

Insert the following in the section where the certificates are located (find the snakeoil certificate entry), the filenames will be different for your system and there may not be an intermediate (chain) file.

# Certificate for <mydomain>
SSLCertificateFile /etc/ssl/private/mydomain_ssl_certificate.cer
SSLCertificateKeyFile /etc/ssl/private/mydomain_private_key.key
SSLCertificateChainFile /etc/ssl/private/mydomain_ssl_certificate_INTERMEDIATE.cer

Comment out the existing snakeoil certificate.

Save the file.

Enable the default ssl site.

a2ensite default-ssl

Zoneminder Configuration

Edit /etc/zm/zm.conf to point at the database.

nano /etc/zm/zm.conf

Change the following entries to values for your system :
ZM_DB_HOST=<ip-address-of-mariadb-server>:<port-number>
ZM_DB_NAME=zm
ZM_DB_USER=zmuser
ZM_DB_PASS=<db-password>

Save the file and exit.

Now it is time to start the services and see it in action.

systemctl enable zoneminder.service
systemctl start zoneminder
a2enconf zoneminder
systemctl restart apache2

That´s it, all should be up and running.

Open up a browser and connect to the Zoneminder using either the ip address or the domain name of your server:

For example http://192.168.0.10/zm or https://mydomain.com/zm

The main Zoneminder console should open and everything else is now configured through the Zoneminder interface.

By default Zoneminder starts with an automatic login as admin - this is clearly a security issue especially if the server is open to the internet. The first thing to do is create a new admin user and turn on authentication.

Options->Users

  • Create a new user as your master administrator role, give it all the privileges and save.

Options->System

  • Enable OPT_USE_AUTH
  • Change AUTH_HASH_SECRET to a new string, the content is unimportant.

Save

Now login with your new administrator user and return to Options->Users
Mark the original 'admin' user checkbox and select Delete to remove the user. This prevents the known username 'admin' being used in brute force attacks. You may also create further users with less privileges as required.

If you are using a remote NAS for storage then that needs to be added to the storage list in Zoneminder as follows, otherwise skip this step as the Default storage will be used.

Options > Storage > Add New Storage
Name: <My NAS Server>
Path: <path-to-the-nfs-share-on-nas>

Options > Images
Set MPEG_LIVE_FORMAT and MPEG_REPLAY_FORMAT to mpg
Ensure OPT_FFMPEG is enabled

Options > Logging
Unset LOG_FFMPEG - Turn it on for debugging if necessary.
Reduce all other logging to 'Error' and use lower levels for debugging if required.

Now it is necessary to configure the appropriate camera sources.

Normally use ONVIF to detect your camera(s). Obviously the camera(s) must be running and connected to the same network either by ethernet or wifi.
Once the relevant device and video stream have been chosen there are some important settings to change.
General: Give the camera a name
Source: Set DecoderHWAccelName to 'vaapi'
Set DecoderHWAccelDevice to 'renderD128'
Storage: Change Video Writer to 'Camera Passthrough' and set storage area to your NAS server if desired.
Buffers: This is the crucial setting, there is a huge amount of scope in these settings and a lot can go wrong but the following values have been reliable for my system:
Image Buffer Size = 192 (This can be 96 or maybe 128 for 4GB Pi)
Warmup Frames = 24
Pre Event Count = 32
Post Event Count = 32
Stream Replay Image Buffer = 0
Alarm Frame Count = 1

Save the camera definition and wait a few seconds for the system to stabilise. If all goes well, the line for the monitor will change from red to green and will show as capturing at a reasonable frame rate. Selecting the monitor entry or the 'Montage' option should bring up a live view of the camera video.

Getting cameras to work with Zoneminder can be a tedious task which is why I exclusively use ONVIF compliant devices. I also set the frame rate on the camera to a value of 24fps and a key frame interval of 48 for video at 1280x720. Do not use Zoneminder to reduce the frame rate if the images and video are poor quality - this is a fruitless task which leads to further problems.

With the above configuration I run 3 cameras capturing and analysing in modect mode at 20fps in daylight, this drops to 10fps once the infra-red switches in. Alert events are captured and stored as mp4 files almost in real time. The Pi is not stressed by this and remains responsive in a command shell, the processor rarely goes over 80%.

Zoneminder has many features for capturing video and images using motion sensing, the advaced features are beyond the scope of this guide. The Zoneminder documentation has detailed information.

Accessing your Zoneminder system from the internet

Once the system is running stable you may wish to access it remotely. This is usually a simple process of configuring the router to allow port forwarding to your Pi device. There are many different router models and config methods, you would need to research the process for your router. The basic procedure is to create a port forwarding rule which points TCP port 80 (and port 443 if SSL is used) to your Raspberry Pi's ip address.

If you do not know how port forwarding works it is easy to google your router´s model number and port forwarding.

 

No comments on “How-to Zoneminder on R-Pi 4”

Comments are closed

The comments for this content have been closed automatically; it's been a while since it was published.