Tested on Ubuntu Nobel 24/2/2025
Useful stuff:
journalctl -u caddy --no-pager | less +G
ps aux | grep caddy
sudo apt install mysql-server
sudo mysql_secure_installation
Choose password below by password
sudo mysql
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password by 'password';
exit
https://zoneminder.readthedocs.io/en/la ... buntu.html
For this one we are using the master branch
sudo apt-get update && sudo apt upgrade -y
sudo apt install -y software-properties-common
sudo add-apt-repository ppa:iconnor/zoneminder-master
sudo apt update
sudo apt install zoneminder -y
Warning this will uninstall apache, it can be skipped, but if you leave apache2 make sure port 80 is not being used
sudo apt purge apache2
sudo apt-get install devscripts
wget
https://raw.githubusercontent.com/ZoneM ... package.sh
chmod a+x do_debian_package.sh
sudo apt-get update
./do_debian_package.sh --snapshot=NOW --branch=master --type=local
N.B should change database user and pass below
cd zoneminder_release
cmake -DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_SKIP_RPATH=ON \
-DCMAKE_VERBOSE_MAKEFILE=OFF \
-DCMAKE_COLOR_MAKEFILE=ON \
-DZM_DB_USER=zmusercaddy \
-DZM_DB_PASS=zmpasscaddy \
-DZM_DB_NAME=zm \
-DZM_RUNDIR=/run/zm \
-DZM_SOCKDIR=/run/zm \
-DZM_TMPDIR=/var/tmp/zm \
-DZM_LOGDIR=/var/log/zm \
-DZM_WEBDIR=/usr/share/zoneminder/www \
-DZM_CONTENTDIR=/var/cache/zoneminder \
-DZM_CACHEDIR=/var/cache/zoneminder/cache \
-DZM_CGIDIR=/usr/lib/zoneminder/cgi-bin \
-DZM_PATH_ZMS=/zm/cgi-bin/nph-zms \
-DZM_DIR_EVENTS=/var/cache/zoneminder/events \
-DZM_WEB_USER=caddy \
-DZM_WEB_GROUP=caddy \
-DCMAKE_INSTALL_SYSCONFDIR=etc/zm \
-DZM_CONFIG_DIR=/etc/zm \
-DCMAKE_BUILD_TYPE=Debug .
make
sudo make install
cd misc
make
sudo make install
sudo mv zoneminder-tmpfiles.conf /usr/lib/tmpfiles.d/zoneminder.conf
This mv sets the ownership and permissions for the /run/zm pid and camera sockets
cd ../
cd db
mysql -u root -p
DROP DATABASE zm;
DROP USER 'zmuser'@'localhost';
exit
mysql -u root -p < ./zm_create.sql
mysql -u root -p
CREATE USER 'zmusercaddy'@'localhost' IDENTIFIED WITH mysql_native_password by 'zmpasscaddy';
GRANT ALL PRIVILEGES ON zm.* TO 'zmusercaddy'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
exit
sudo apt install php8.3-fpm
sudo apt install gedit
sudo cp /etc/php/8.3/fpm/pool.d/
www.conf /etc/php/8.3/fpm/pool.d/caddy.conf
sudo gedit /etc/php/8.3/fpm/pool.d/caddy.conf
Change pool name and others like below and save
[caddy]
user = caddy
group = caddy
listen.owner = caddy
listen.group = caddy
listen = /run/php/php8.3-caddy.sock
sudo gedit /etc/php/8.3/fpm/php.ini
Search, uncomment and save, you might want to google what these session settings do, but i think they should be on if you are going to expose zoneminder online over https
date.timezone = Australia/Perth
session.cookie_secure = 1
session.cookie_httponly = 1
https://go.dev/doc/install
Download Go zip form go
cd ~/Downloads
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.24.0.linux-amd64.tar.gz
sudo nano ~/.bashrc
Add to bottom
export PATH=$PATH:/usr/local/go/bin
Save and open new terminal
Check
go version
https://caddyserver.com/docs/build#pack ... turaspbian
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf '
https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf '
https://dl.cloudsmith.io/public/caddy/s ... an.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
sudo mkdir /var/lib/caddy
sudo chown -R caddy:caddy /var/lib/caddy
sudo caddy trust
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf '
https://dl.cloudsmith.io/public/caddy/xcaddy/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-xcaddy-archive-keyring.gpg
curl -1sLf '
https://dl.cloudsmith.io/public/caddy/x ... an.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-xcaddy.list
sudo apt update
sudo apt install xcaddy
xcaddy build --with=github.com/aksdb/caddy-cgi/v2
sudo dpkg-divert --divert /usr/bin/caddy.default --rename /usr/bin/caddy
sudo mv ./caddy /usr/bin/caddy.custom
sudo update-alternatives --install /usr/bin/caddy caddy /usr/bin/caddy.default 10
sudo update-alternatives --install /usr/bin/caddy caddy /usr/bin/caddy.custom 50
You can change between the custom and default caddy binaries by executing the below, and following the on screen information. Then, restart the Caddy service.
sudo update-alternatives --config caddy
sudo systemctl restart caddy
sudo nano /etc/caddy/Caddyfile
{
debug
order cgi before respond
}
zone.localhost {
root * /usr/share/zoneminder/www
log
redir / /zm 301
header {
Permissions-Policy interest-cohort=()
Strict-Transport-Security max-age=31536000;
X-Content-Type-Options nosniff
X-Frame-Options DENY
}
handle_errors {
respond "{err.status_code} {err.status_text}"
}
handle_path /cache/* {
root * /var/cache/zoneminder/cache
}
cgi /zm/cgi-bin/nph-zms /usr/lib/zoneminder/cgi-bin/nph-zms {
unbuffered_output
}
php_fastcgi unix//run/php/php8.3-caddy.sock
file_server
}
sudo mkdir /etc/systemd/system/zoneminder.service.d
sudo nano /etc/systemd/system/zoneminder.service.d/override.conf
[Service]
User=caddy
sudo chown -R caddy:caddy /usr/share/zoneminder
sudo chown -R caddy:caddy /var/cache/zoneminder
sudo chown -R caddy:caddy /var/log/zm
sudo chown caddy:caddy /etc/zm/zm.conf
sudo chmod 740 /etc/zm/zm.conf
sudo adduser caddy video
sudo cp -r /usr/share/zoneminder/www/fonts /usr/share/zoneminder/www/skins/classic/css/fonts
Reboot the computer
sudo systemctl daemon-reload
sudo systemctl enable zoneminder
sudo systemctl enable caddy
sudo systemctl start zoneminder
sudo systemctl start caddy
Extra; Iphone presence detection
Change the home /home/dan bit
Change the user pass bit
Change the MAC Address bit
You might need to change the --interface=eno1 one bit your own network adaptor
Ifconfig
The state matches a state created in zoneminder
You do need to change the Iphone wireless settings to be a fixed MAC Address
sudo apt install arp-scan
nano config.cnf
[client]
user = "zmusercaddy"
password = "zmpasscaddy"
host = "localhost"
nano home.sh
#!/bin/bash
STATE=$(mysql --defaults-extra-file=/home/dan/config.cnf --skip-column-names zm -e 'SELECT Name FROM `States` WHERE IsActive=1')
MAC_DAN_ROOM="********"
MAC_TYSON_HOUSE="**********"
for RUN in {1..5}; do
TEST+=$(arp-scan --interface=eno1 --localnet --destaddr=$MAC_DAN_ROOM | grep $MAC_DAN_ROOM | awk '{print $2 "\t"}') ;
TEST+=$(arp-scan --interface=eno1 --localnet --destaddr=$MAC_TYSON_HOUSE | grep $MAC_TYSON_HOUSE | awk '{print $2 "\t"}') ;
done
if [ ! -z "${TEST}" ] && [ "${STATE}" != "off" ]; then
/usr/bin/zmpkg.pl off
exit 0
fi
if [ -z "${TEST}" ] && [ "${STATE}" != "motion" ]; then
/usr/bin/zmpkg.pl motion
fi
sudo mv home.sh /home/dan/home.sh
cd /home/dan
sudo chmod +x home.sh
sudo crontab -e
MAILTO=""
*/5 * * * * bash /home/dan/home.sh
Extra; Email body for a motion filter, fixes images on Iphone
https://wiki.zoneminder.com/How_to_get_ ... Zoneminder
<!DOCTYPE html>
<html>
<head>
<title>ZoneMinder: Alarm - %MN%-%EI%</title>
</head>
<body>
<h1>ZM alarm detected</h1>
<p> %MN%</p>
<p> %ET% </p>
%EIMA%
</body>
</html>
So if anyone else has improvements please share