ZoneMinder video camera security and surveillance

ZoneMinder usually runs with Apache, but in this short how-to we use Lighttpd.
==Base Install==
ZoneMinder is found in the community repositories, please enable it by following the instructions here
Then, add the packages for zoneminder to our system
 apk add zoneminder mariadb mysql-client lighttpd php-fpm php-pdo php-pdo_mysql php-intl php-session php-ctype 
Note: You will need to adjust the above to use the appropriate php version. For example, in alpine 3.17 php 8.1 is used therefore you would enter php81-fpm. In alpine 3.20 php 8.3 is used so you would enter php83-fpm. You can look up the php version by typing apk search php and sorting through the results for your given release. This version suffix should be added to each php package.
===Database===
Initialize MySQL database
 rc-service mariadb setup
Start the database
 rc-service mariadb start
Set root password for MySQL as instructed by MySQL setup
 /usr/bin/mysqladmin -u root password 'your_secure_root_mysql_password'
You can log into MySQL as current root user with
 mysql
Create a ZoneMinder MySQL database and user
 mysql> create database zm;
 mysql> CREATE USER zmuser@localhost IDENTIFIED BY 'your_zm_password_as_set_in_config';
 mysql> grant ALL on zm.* to zmuser@localhost;
===Web Server===
We are running lighttpd, so let's run php-fpm as lighttpd user/group
 vi /etc/php8/php-fpm.conf
Note: for php 8.1
 vi /etc/php81/php-fpm.conf
Add this section to the bottom of the file:
 ; Unix user/group of processes
 ; Note: The user is mandatory. If the group is not set, the default user's group
 ; will be used.
 ;user = nobody
 ;group = nobody
 user = lighttpd
 group = lighttpd
Enable the php cgi fpm config in lighttpd.conf
 vi /etc/lighttpd/lighttpd.conf
Go down to the server modules section and uncomment mod_alias, which is needed for the cgi-bin, and mod_rewrite, for the api. It should look like:
 # 
Go down to the includes section, it should look like:
 # 
In order for video streaming to work in 1.36, you'll need the following
added to /etc/lighttpd/lighttpd.conf:
 server.stream-response-body = 1
In lighttpd.conf for the API, we will want to redirect any api+ requests to cakephp. Thus, add:
 url.rewrite = (
 "^/zm/api(.+)$" => "/zm/api/index.php"
 )
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign
 vi /etc/lighttpd/mod_cgi.conf
which should look like
 cgi.assign = (
 "" => "",
 ".pl" => "/usr/bin/perl",
 ".cgi" => "/usr/bin/perl"
 )
Also add the following to alias.url in mod_cgi.conf so that it looks like
 alias.url = (
 "/cgi-bin/" => var.basedir + "/cgi-bin/",
 "/zm/api" => "/usr/share/webapps/zoneminder/htdocs/api/app/webroot/",
 "/zm/" => "/usr/share/webapps/zoneminder/htdocs/"
 )
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). 
 unlink /var/www/localhost/htdocs/zm
Start php-fpm
 rc-service php-fpm8 start
Note: for php-fpm81, use the following command:
 rc-service php-fpm81 start
Start lighttpd
 rc-service lighttpd start
===Zoneminder===
Set the MySQL hostname, username, password.
Change the ZoneMinder user (ZM_WEB_USER) and group (ZM_WEB_GROUP) to lighttpd
And set ZM_SERVER_HOST to your ZoneMinder hostname/ipaddress
 vi /etc/zm/zm.conf
Which should look like:
 # Username and group that web daemon (httpd/apache) runs as
 ZM_WEB_USER=lighttpd
 ZM_WEB_GROUP=lighttpd
 ZM_PATH_DATA=/usr/share/zoneminder
 # ZoneMinder database type: so far only mysql is supported
 ZM_DB_TYPE=mysql
 
 # ZoneMinder database hostname or ip address
 ZM_DB_HOST=localhost
 
 # ZoneMinder database name
 ZM_DB_NAME=zm
 
 # ZoneMinder database user
 ZM_DB_USER=zmuser
 
 # ZoneMinder database password
 ZM_DB_PASS=your_zm_password_as_set_in_config
 
 # Host of this machine
 ZM_SERVER_HOST=yourserver
Change ownership of zm.conf to lighttpd
 chown lighttpd.lighttpd /etc/zm/zm.conf
Zoneminder will create a cache in /var/cache/zoneminder which isn't created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.
 mkdir /var/cache/zoneminder
 chown lighttpd.lighttpd /var/cache/zoneminder
Initialize the ZoneMinder database
 rc-service zoneminder setup
Start ZoneMinder
 rc-service zoneminder start
Profit!
===Conclusion===
To access ZoneMinder, browse to http://yourserver/zm/
To test the API, run
 curl -X GET http://yourserver/zm/api/host/getVersion.json
(This assumes you aren't using authentication.)
To make it start automatically on boot:
 rc-update add lighttpd default
 rc-update add mariadb default
 rc-update add php-fpm8 default
 rc-update add zoneminder default
== Added notes to work with Nginx ==
Later to add some notes about running via nginx
== Troubleshooting ==
===General troubleshooting of lighttpd===
You can enable debugging on lighttpd by uncommenting the debug options in /etc/lighttpd/lighttpd.conf (which in 3.20 were): 
 debug.log-request-header = "enable"
 debug.log-response-header = "enable"
 debug.log-request-handling = "enable"
 debug.log-file-not-found = "enable"
Note that since 3.14, mod_alias is now built into lighttpd and is not a module (.so file).
For further troubleshooting, refer to the alpine build logs (https://pkgs.alpinelinux.org/package/v3.21/main/x86_64/lighttpd or https://pkgs.alpinelinux.org/package/v3.21/main/x86_64/zoneminder) or alternatively, the lighttpd redmine wiki & forums. The ZoneMinder forum/discord/github issues tracker is also available for any errors related to ZoneMinder.
===PHP Fatal Error in /var/log/lighttpd/error.log===
Sometimes the php extensions are missing. For example, in 3.20 I had to manually install php83-ctype, which was not required in previous versions. This is confusing because, there is php82 and php-fpm83 installed. Testing ctype from the php82 interactive shell will succeed, but ZM is using php-fpm83, and phpinfo() from an index.php lists ctype (which you might assume is installed) however ctype is listed as 'enable=shared' which I assume means you have to install the shared library for ctype.
===ZM is not compiled with LibVNC support in 3.20===
This is a missing feature, and should be resolved at some point in the future. This means source type:VNC will not work.
Category:Software
Category:Security