Intro
My original home surveillance system was two D-Link DCS-932LB cameras. The cameras had motion detection enabled and would upload photos to an FTP server. This served its purpose well until one night that I actually needed the footage. Unfortunately, the frame rate of this approach was so low that we couldn’t see what we needed. ZoneMinder would have given me what I needed, so I installed it and have been using it ever since.
Fast forward to now, and I want to move the ZoneMinder installation to another machine. Instead of going through the painstaking installation process again, I opted to used Docker. The ZoneMinder devs provide Docker images, which made this especially easy.
Prerequisites
I started with a clean installation of Ubuntu 16.04 Xenial and installed Docker following the official instuctions.
Installation instructions
Build the image, specifying the version in the tag list.
docker build -t='kylejohnson/release-1.30' github.com/ZoneMinder/ZoneMinder
Create a container named zoneminder:
docker create -t -p 80:80 --shm-size 512M --name zoneminder kylejohnson/release-1.30
This took some experimentation to get right. ZoneMinder uses /dev/shm
for its shared memory, and docker only uses 64M
by default. I was able to create a single monitor with the default setting, but anything beyond that didn’t work. /dev/shm
was at 100%. With 512M
, I’m sitting at 35% utilization. This gives me some room to grow.
Create a systemd service for starting zoneminder on boot.
[Unit]
Description=Zoneminder Container
Requires=docker.service
After=docker.service
[Service]
Restart=always
ExecStart=/usr/bin/docker start -a zoneminder
ExecStop=/usr/bin/docker stop -t 2 zoneminder
[Install]
WantedBy=default.target
This should be saved in /etc/systemd/system/zoneminder.service
, started using systemctl start zoneminder
and enabled using systemctl enable zoneminder
.
Setup your monitors.
Troubleshooting
There were a couple times I needed to access the ZoneMinder logs. To do this, I used docker to start a shell in the container.
docker exec -i -t zoneminder /bin/bash
Enabling SSL
First, get some valid SSL Certs using cerbot and Let’s Encrypt:
apt-get update
apt-get install software-properties-common
add-apt-repository ppa:certbot/certbot
apt-get update
apt-get install certbot
Then use the webroot plugin to obtain a cert
certbot certonly --webroot -w /usr/local/share/zoneminder/www -d [url]
Add a cron job for renewing the certificate automatically:
0 0 1 * * /usr/bin/certbot renew
The certs end up in:
/etc/letsencrypt/live/[url]/
Then update the apache config to use the new certs by adding the following to /etc/apache2/sites-enabled/000-default.conf
.
<VirtualHost *:443>
DocumentRoot /usr/local/share/zoneminder/www
DirectoryIndex index.php
ScriptAlias /cgi-bin/ /usr/local/libexec/zoneminder/cgi-bin/
<Directory />
Require all granted
</Directory>
<Directory "/usr/local/libexec/zoneminder/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Require all granted
</Directory>
ServerName [url]
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/[url]/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/[url]/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/[url]/chain.pem
</VirtualHost>
Get the image ID:
docker inspect zoneminder
Stop zoneminder:
sytemctl stop zoneminder
Then update /var/lib/docker/containers/[id]/config.v2.json
to include:
"ExposedPorts":{"443/tcp":{},"80/tcp":{}}
And /var/lib/docker/containers/[id]/hostconfig.json
"PortBindings":{"443/tcp":[{"HostIp":"","HostPort":"443"}],"80/tcp":[{"HostIp":"","HostPort":"80"}]}
And restart docker and zoneminder:
systemctl restart zoneminder docker
Conclusions
This is quick and easy to setup. From start to finish, it took me less than an hour to have a functioning installation. Figuring out the SSL setup probably took me a couple hours, but if I had to do it again, it would be much faster.