HOWTO: Installing ZoneMinder in a FreeNAS 11 Jail

francelife23

Cadet
Joined
Mar 5, 2018
Messages
3
Introduction

Disclaimer:

  • This is designed to provide a quick and dirty overview on getting ZoneMinder (ZM) up and running within a jail on FreeNAS. It is up to you to adapt this to your own circumstances and to ensure you secure everything after installation – this HOWTO does not result in a secure installation!!
  • This guide assumes you are familiar with the basics of FreeNAS, fundamental Linux etc, you will need to be able to access the FreeNAS web UI and thereafter use the web shell or access the server via SSH. It does not cover how to use or configure ZM.
  • I am not a Linux ninja and have compiled this guide based on my experience and information gleaned from the internet – feel free to contribute improvements however I will not be able to actively support people in their own adoption of this procedure.
  • This guide was written in March 2018 using FreeNAS build 11.1 U2. Mileage may vary depending on your installed version.
Credits:

I used myriad sources to piece this together, apologies to those not credited but the main sources were:
Overview

This will cover how to install and configure the ZM pre-requisites, there are different products/packages you can use, these are my preference:
  • Web server – Apache (v2.4)
  • Database server – MySQL (v5.6)
  • PHP – Not optional!
Then it will cover installing ZM and getting as far as the ZM homepage, the rest is up to you!

Method

Step 1 – Create the jail

  • Create a new jail from the default ‘blank’ template (for simplicity this guide assumes a brand-new jail, if you are using an existing FAMP jail etc you will have to adapt this and skip parts you have already done).
  • Change the network settings and note the IP address of the jail for later use. Add storage as required for your jail and start/restart it as necessary.
  • First ensure your package manager is up to date and configured (jails tend to get out of date, it might be easier to recreate your jail using a fresh downloaded template if you have issues here) along with a system update:
# pkg update -f
# pkg upgrade
  • Now is also the time to install an alternative text editor if you don’t like VI:
# pkg install nano

Step 2 – Install AMP

Execute the following steps on your new jail (not on the FreeNAS server)!!

Step 2A: Install Apache

  • Using the BSD package manager, install Apache with dependencies:
# pkg install apache24
  • Configure Apache to autostart:
# sysrc apache24_enable=yes
  • Then start Apache:
# service apache24 start
  • Now go to a web browser, go to your jail’s IP address (NOT the FreeNAS’s!) and check you get the default It Works! Homepage served by Apache to confirm it installed ok, if not troubleshoot this before proceeding
Step 2B – Install MySQL
  • Install MySQL with dependencies:
# pkg install mysql56-server
  • Configure MySQL to autostart:
# service mysql-server start
  • Now check your MySQL instance is running by entering:
# mysql
  • You should get a response that is not a Can't connect to local MySQL server… if not, troubleshoot this before proceeding.
Step 2C – Install PHP
  • Install PHP with dependencies and MySQL options:
# pkg install mod_php56 php56-mysql php56-mysqli
  • Copy the default PHP config:
# cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini
  • Now using your favourite editor (Nano here) open the Apache config file for writing:
# nano /usr/local/etc # nano apache24/httpd.conf
  • Add the following to the end of the file:
Code:
<IfModule dir_module>
	DirectoryIndex index.php index.html
<FilesMatch "\.php$">
		SetHandler application/x-httpd-php
	</FilesMatch>
	<FilesMatch "\.phps$">
		SetHandler application/x-httpd-php-source
	</FilesMatch>
</IfModule>

  • Now save and exit.
  • Open the PHP configuration file for writing:
# nano /usr/local/etc/php.ini
  • Uncomment the date.timezone line (if necessary) and append the appropriate details following the guidance at http://php.net/manual/en/timezones.php, the amended line should be (if you live in UK!):
date.timezone = Europe/London
  • Now conduct a restart of Apache to check you didn’t mess anything up, if Apache doesn’t start, troubleshoot before proceeding:
# service apache24 restart
  • If you want to be sure, you can also check PHP is installed correctly by setting up a PHP page calling the PHP info function and temporarily configuring Apache to host it – Google it for more info.
  • If you have got this far, you are now ready to install ZM.
Step 3 – Install ZM
  • Install ZM with dependencies:
# pkg install zoneminder
  • Configure ZM to autostart:
# sysrc zoneminder_enable=yes
  • Now we configure the core ZM elements, starting with initialising the ZM database:
# mysql -uroot -p < /usr/local/share/zoneminder/db/zm_create.sql
  • Troubleshoot any errors before proceeding
mysql -uroot -p -e "grant select,insert,update,delete,create,alter,index,lock tables on zm.* to 'zmuser'@localhost identified by 'zmpass';"
  • Troubleshoot any errors before proceeding, now ensure some key permissions are set (EDIT: you may need to try 744 for zm.conf if you get permission denied errors later):
# chmod 740 /usr/local/etc/zm.conf
# chmod 740 /usr/local/my.cnf
  • Restart MySQL to take changes into effect:
# service mysql-server restart
  • Open the Apache config file for writing:
# nano /usr/local/etc/apache24/httpd.conf
  • Append the following:
Code:
<VirtualHost *:80>
	ServerName zm.freenas.local
	ServerAdmin email@example.com
	DocumentRoot "/usr/local/www/zoneminder/"
	<Directory "/usr/local/www/zoneminder">
		Options FollowSymLinks
		AllowOverride All
	Require all granted
	</Directory>
	ScriptAlias /cgi-bin "/usr/local/www/zoneminder/cgi-bin"
	<Directory "/usr/local/www/zoneminder/cgi-bin">
		Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
		AllowOverride All
	Require all granted
	</Directory>
	LogLevel debug
</VirtualHost>

  • Save and exit. Then restart Apache again, troubleshooting any issues:
# service apache24 restart
  • In a browser, go to the ZM jail’s IP address, you should get to the ZM main page – hooray! If not, review the above steps and troubleshoot as necessary.
  • Finally, restart the jail and re-check ZM in the browser as above to ensure everything restarts ok.
Step 4 - Secure your installation!
Key things to do next:
  • Secure MySQL, run: mysql_secure_installation
  • Check and update permissions on all directories and folders are appropriate/secure
  • Change settings/passwords etc as required
  • Reconfigure PHP/Apache/MySQL to use production settings

Hope this helps someone.
 
Last edited:

mgranger

Cadet
Joined
Mar 2, 2018
Messages
1
First off this was a great help to me. The only problem is I get to the last stage in Step 3 and when I restart Apache I don't get an error however when I log in to the jail's IP address there is just a black page. Nothing is shown.

I have looked into this a little more and I am guessing this is a permission thing because when I type

service zoneminder status

I get:

Code:
Can't open config file '/usr/local/etc/zm.conf': Permission denied at /usr/local/lib/perl5/site_perl/ZoneMinder/Config.pm line 129
 
Last edited:

joebad1

Explorer
Joined
Nov 21, 2015
Messages
58
Beautiful! Well done! Worked like a charm. Many thanks for publishing this!
 

joebad1

Explorer
Joined
Nov 21, 2015
Messages
58
# chmod 740 /usr/local/etc/zm.conf
# chmod 740 /usr/local/my.cnf

When I issue the commands above, I get an error because I don't have my.cnf. I'm assuming I have to create it manually. I found the my.cnf.example file in /usr/local/etc/mysql/. Can you give me an idea of what changes you made to my.cnf.example?
 

francelife23

Cadet
Joined
Mar 5, 2018
Messages
3
I'm afraid I don't know, does it work just doing cp /usr/local/etc/mysql/my.cnf.example /usr/local/my.cnf ?
 

tagcart

Cadet
Joined
Mar 13, 2018
Messages
4
Having a problem viewing the live stream. Seems to be recording fine.

Socket /var/run/zm/zms-804575s.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.

Any advice?

EDIT: I found the solution:

In /usr/local/etc/apache24/httpd.conf you need to find the lines

Code:
<IfModule mpm_prefork_module>
		#LoadModule cgi_module libexec/apache24/mod_cgi.so
</IfModule>


And remove the #.

Then
Code:
service apache24 restart


I now have live video feed.
 
Last edited:

joebad1

Explorer
Joined
Nov 21, 2015
Messages
58
Having a problem viewing the live stream. Seems to be recording fine.

Socket /var/run/zm/zms-804575s.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.

Any advice?

EDIT: I found the solution:

In /usr/local/etc/apache24/httpd.conf you need to find the lines

Code:
<IfModule mpm_prefork_module>
		#LoadModule cgi_module libexec/apache24/mod_cgi.so
</IfModule>


And remove the #.

Then
Code:
service apache24 restart


I now have live video feed.
Excellent! I was having the same problem. Will try your fix tonight.

(Edited: Found my.cnf right where it was supposed to be!!)
 
Last edited:

joebad1

Explorer
Joined
Nov 21, 2015
Messages
58
Also: Would appreciate recommendations on how you're handling storage. Where are you saving events and video files?
 

joebad1

Explorer
Joined
Nov 21, 2015
Messages
58
Live video feed works great thanks to the change noted above by "tagcart"

One other change to note: If you have problems adding/saving a camera, nano into your my.cnf file and change the line that says:

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

to

sql_mode=NO_ENGINE_SUBSTITUTION
 

tagcart

Cadet
Joined
Mar 13, 2018
Messages
4
Also: Would appreciate recommendations on how you're handling storage. Where are you saving events and video files?

By default, the folders get generated from the install at /usr/local/www/zonemidner. Basically you will be using your jails storage unless you choose a different location. As long as you're jail is running in a good sized pool, you should be fine.

The way you manage storage is through the Event Filters on the web gui. By default, there is a Purge When Full event already enabled. It is set to when your disk reaches 90%, it will record over the oldest event. I added my own event to delete anything older than 30 days, as I think that's a decent time frame. Here is a snip of what my filter looks like:

Capture.PNG


Once you save, just make sure you check the "run in background" or it won't run automatically.
 

joebad1

Explorer
Joined
Nov 21, 2015
Messages
58
By default, the folders get generated from the install at /usr/local/www/zonemidner. Basically you will be using your jails storage unless you choose a different location. As long as you're jail is running in a good sized pool, you should be fine.

The way you manage storage is through the Event Filters on the web gui. By default, there is a Purge When Full event already enabled. It is set to when your disk reaches 90%, it will record over the oldest event. I added my own event to delete anything older than 30 days, as I think that's a decent time frame. Here is a snip of what my filter looks like:

View attachment 23359

Once you save, just make sure you check the "run in background" or it won't run automatically.
Excellent information, thanks!
So out of ignorance, or habit, or both, I created a dataset on my pool called zoneminder. I then created the jail, and added storage to it pointing at the zoneminder dataset and telling it to map to /mnt/zm/ in my jail.

So color me confused . . .

Do I need to re-map the jail storage so that the /usr/local/www/zoneminder is pointing at the "zoneminder" dataset I created earlier?
 

tagcart

Cadet
Joined
Mar 13, 2018
Messages
4
I don't think you necessarily need the zoneminder dataset if your jail is running in a decent sized pool. Especially if you have some sort of replication.

Not 100% sure but if you really wanted to use the data set, you could possibly point zonemidner to it from the web gui. Options>Paths>DIR_EVENTS. Like i said, not totally sure that will work but worth a try.
 

joebad1

Explorer
Joined
Nov 21, 2015
Messages
58
I don't think you necessarily need the zoneminder dataset if your jail is running in a decent sized pool. Especially if you have some sort of replication.

Not 100% sure but if you really wanted to use the data set, you could possibly point zonemidner to it from the web gui. Options>Paths>DIR_EVENTS. Like i said, not totally sure that will work but worth a try.

Not at all! Thank-you.

I assumed, apparently incorrectly, that a jail's only method for storing data was by pointing to a dataset and assigning storage in the jail! I didn't know the jail had access to the pool otherwise.

Thanks for the info.
 

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,456
I didn't know the jail had access to the pool otherwise.
The jail is stored on a pool (typically your main data pool, though it doesn't have to be). Unless you set a quota for its dataset or otherwise limit it, it can use as much space as is there. It can't, however, access data that's stored outside the jail unless you assign storage in the jail.

We generally suggest configuring jails in such a way that their data is stored outside the jail itself. That isn't a hard requirement, but it would probably be considered a best practice.
 

joebad1

Explorer
Joined
Nov 21, 2015
Messages
58
We generally suggest configuring jails in such a way that their data is stored outside the jail itself. That isn't a hard requirement, but it would probably be considered a best practice.[/QUOTE]

I'm more than willing to do it, since it's fairly simple to do. Can you elaborate on why it would be considered "best practice"?
 

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,456
Can you elaborate on why it would be considered "best practice"?
The less that's stored inside the jail, the easier it is to rebuild the jail if necessary. If you look at some of the recent how-to documents for iocage jails (e.g., https://forums.freenas.org/index.ph...unifi-controller-with-lets-encrypt-iocage.81/ or https://forums.freenas.org/index.php?resources/fn11-jailed-crashplan-pro-with-vnc-iocage.79/), they're even putting the config files outside of the jail, so that the only thing stored in the jail itself is the actual software. That means you can destroy the jail and rebuild it with the latest software, even upgrading the underlying OS template, without disturbing your data or configuration.

There's also the fact that some users (like me) put jails on a separate, smaller (sometimes SSD) pool, and wouldn't want the large amount of data taking space on the smaller pool.
 

joebad1

Explorer
Joined
Nov 21, 2015
Messages
58
The less that's stored inside the jail, the easier it is to rebuild the jail if necessary. . . . means you can destroy the jail and rebuild it with the latest software, even upgrading the underlying OS template, without disturbing your data or configuration.

There's also the fact that some users (like me) put jails on a separate, smaller (sometimes SSD) pool, and wouldn't want the large amount of data taking space on the smaller pool.

Good info. Thanks for the knowledgeable answers!
 

joebad1

Explorer
Joined
Nov 21, 2015
Messages
58
EDITING THIS POST AS I MAKE DISCOVERIES . . .

Has anyone had any luck getting the API's to work? I downloaded zmninja, but it's giving me API errors when trying to connect. I'm finding the /api directory on my server right where is should be:

/usr/local/www/zoneminder/api

But many of the subdirectories are missing: For instance /api/host/ which is mentioned in other forums is not there. I do get a response from CakePHP when I browse to <server.IP>/api. So it makes me think some portion of the API's are working.

This may be a lost cause for ZoneMinder 1.30.4. I see many notes that API's are broken by this version on other systems (Ubuntu, Centros, etc.). But some have had success manually patching those other systems.

Does anyone have an idea where an error log might be located that can tell me what's happening when I try to connect with ZMNinja?

Regards!
 
Last edited:

bollar

Patron
Joined
Oct 28, 2012
Messages
411
danb35 said:
We generally suggest configuring jails in such a way that their data is stored outside the jail itself. That isn't a hard requirement, but it would probably be considered a best practice.

I'm more than willing to do it, since it's fairly simple to do. Can you elaborate on why it would be considered "best practice"?

In addition to @danb35 's answer, putting the data outside the jail allows you to set a quota and reserved space for the dataset and will allow ZoneMinder's auto file delete function to work within space less than the entire pool. That seems important for this application, since it's constantly recording to the pool.
 
Top