Installing the ShinobiCCTV as a dedicated NVR for to replace my current surveillance system. I have been searching for a new NVR. I am currently using Reolink desktop client as my NVR on a Windows 10 VM. Yes, the only Windows node in my network.
I am running the following specs for my: Windows VM with Reolink Desktop Client
- 4x vCPU
- 4GB RAM
- 60GB vDisk
- SMB share for recordings
I have been meaning to replace this VM for a better and less hungry system. I even considered getting a 2-bay Synology or QNAP since I heard good things about these NAS servers as a surveillance system. The issue that I have with these NAS servers are:
- Licenses make the whole setup really expensive for both Synology and QNAP
- Synology has a max of 15 IP cameras (QNAP supports more cameras)
- I would need a rack space to store this NAS (I don’t have any space in my rack cabinet)
I am going to deploy the ShinobiCCTV and run it alongside my Windows VM. I am hoping that Shinobi could replace my current setup. I also set up a Zoneminder, but leaning towards the ShinobiCCTV.
This doesn’t mean I am going to abandon Zoneminder. Zoneminder works really well with RMTP. I am leaning towards ShinobiCCTV because of the following reasons:
- Mobile friendly – I don’t need another app to manage and view my NVR. It also includes audio
- The web UI looks really nice
- I was making progress with Shinobi than with Zoneminder
- It seems to be less CPU extensive as Zoneminder
Mounting an NFS share
If you are not mounting an NFS share then skip this section and jump straight to Motion Detection section. We are going to mount an NFS share from our NAS. I am using Unraid server. Yours probably different, but since this guide is NFS it should be the same. I created a directory on my Unraid server called Shinobi. I enabled (exported) NFS on this folder. The Unraid server IP address is 192.168.7.12.
The reason why we are using a shared NFS is to utilize the storage capacity of the NAS server.
On the Shinobi Server do the following:
- Install the nfs-common
- Make a directory where to mount the NFS share
- Mount the NFS share
- Edit the fstab to make the mount permanent after a reboot
apt install -y nfs-common mkdir -p /mnt/nfs_shares # # You probably need to be a root user to run the echo like it # is shown here # The -e enable interpretation of backslash escapes. # So when we view the /etc/fstab it would look clean. echo -e "192.168.7.12:/mnt/user/Video/Shinobi\t/mnt/nfs_shares\tnfs\tdefaults\t0\t0" >> /etc/fstab # # The command below would simply just mount anything that needs # to be mounted. In our case, the line we added to the fstab. mount -a
If you cat
your /etc/fstab
, at the bottom, it should look like similar to this
192.168.7.12:/mnt/user/Video/Shinobi /mnt/nfs_shares nfs defaults 0 0
If you checked your disk filesystem with df -h
command, you should see at the bottom new entry which is the NFS share we mounted.
root@shinobi:/home/Shinobi# df -h Filesystem Size Used Avail Use% Mounted on udev 1.9G 0 1.9G 0% /dev tmpfs 395M 1.1M 394M 1% /run /dev/vda2 9.8G 4.7G 4.6G 51% / tmpfs 2.0G 0 2.0G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup /dev/loop0 91M 91M 0 100% /snap/core/6350 tmpfs 395M 0 395M 0% /run/user/1000 192.168.7.12:/mnt/user/Video/Shinobi 34T 13T 21T 39% /mnt/nfs_shares
Now that the NFS share is mounted to our Shinobi VM, we need to modify the conf.json file. This file is located in /home/Shinobi
. We need to modify the conf.json, so that we can use the NFS share that we mounted earlier for the surveillance storage.
Just for reference this is the default content of the conf.json file:
{ "port": 8080, "passwordType": "sha256", "detectorMergePamRegionTriggers": true, "addStorage": [ {"name":"second","path":"__DIR__/videos2"} ], "db": { "host": "127.0.0.1", "user": "majesticflame", "password": "", "database": "ccio", "port":3306 }, "mail":{ "service": "gmail", "auth": { "user": "[email protected]", "pass": "your_password_or_app_specific_password" } }, "cron":{ "key":"change_this_to_something_very_random__just_anything_other_than_this" }, "pluginKeys":{} }
We are going to modify the line 6. It should look like this:
{"name":"nfs_shares","path":"/mnt/nfs_shares"}
Then restart the Shinobi service to activate the modified conf.json
pm2 restart all

If you are following this guide, I am going to assume that you already configure a user to login to the web UI.
Adding an IP Camera
We need to add an IP camera that supports RTSP. I am using Reolink IP cameras. Login to the http://shinobi-ip:8080.
- Click on the + sign (Add Monitor)
- Fill out the following
Identity
Name | Value | Notes |
Mode | Watch-Only | Watch-Only need to be set for the motion dection to work |
Name | frontdoor | Name of the camera |
Number of Days to keep Videos | 90 | How long you wanted to keep the videos |
Storage Location | nfs_shares | The NFS share that was mounted earlier |
Connection
Name | Value | Notes |
Input Type | H.264 / H.265 / H.265+ | |
Automatic | No | |
Connection Type | RTSP | |
RTSP Transport | TCP | |
Username | ip-camera-username | |
Password | ip-camera-password | |
Host | 192.168.5.21 | IP address of the IP camera |
Port | 554 | RTSP port |
Stream
Name | Value | Notes |
Stream Type | Poseidon | |
Connection Type | Websocket | |
Video Codec | copy | |
Audio Codec | aac | The dev recommends to use AAC if your camera supports it |
Motion Detection

When creating a user that can add/remove cameras, make sure that you change the storage limit that this user can use. By default, this is set to 10000MB (10GB) for all the cameras you have added. Therefore, if you want to keep the recordings at specified days make sure that you increase this limit. Obviously, make sure that you have storage to support that desired limit you would specify.
I did not follow the ShinobiCCTV settings because it seems too sensitive. The settings literally generate a video after the other. However, I did use it as a reference. Below are my settings for Motion Detection.
Global Detector Settings
Name | Value | Notes |
Enabled | Yes | Enabling this will open more options |
Send Frames | Yes | |
Allow Next Trigger | 2000 | In milliseconds. A amount of time between the first event and next event. Basically, a pause before the next motion recording |
Save Events to SQL | Yes | This will add dots to the timeline. The dots represents motion |
Detector Rate(FPS) | 3 | |
Feed-in Image Width | 640 | |
Feed-in Image Height | 480 | |
How to Record | Traditional (Watch-Only, Includes Buffers) | |
Trigger Record | Yes | |
Recording Timeout | 2 | In minutes |
Motion Detection
Name | Value | Notes |
Use Built-In | Yes | |
Indifference | 5 | The percentage of change between two frames |
Full Frame Detection | Yes |
Traditional Recording
Name | Value | Notes |
Video Encoder | copy | |
Audio Encoder | aac | The dev recommends to use AAC if your camera supports it |
I didn’t explain some contents here since I still don’t fully understand most of it. I just got this to a point that is functional for my use case. I am still playing with the settings and trying to find a correct config combination.
Cheers!