1 { config, lib, options, pkgs, utils, ... }:
4 cfg = config.services.unifi-video;
5 opt = options.services.unifi-video;
6 mainClass = "com.ubnt.airvision.Main";
8 ${pkgs.jsvc}/bin/jsvc \
14 -home ${cfg.jrePackage}/lib/openjdk \
15 -cp ${pkgs.commonsDaemon}/share/java/commons-daemon-1.2.4.jar:${stateDir}/lib/airvision.jar \
16 -pidfile ${cfg.pidFile} \
17 -procname unifi-video \
18 -Djava.security.egd=file:/dev/./urandom \
19 -Xmx${toString cfg.maximumJavaHeapSize}M \
22 -XX:+UseStringDeduplication \
23 -XX:MaxMetaspaceSize=768M \
24 -Djava.library.path=${stateDir}/lib \
25 -Djava.awt.headless=true \
26 -Djavax.net.ssl.trustStore=${stateDir}/etc/ufv-truststore \
27 -Dfile.encoding=UTF-8 \
28 -Dav.tempdir=/var/cache/unifi-video
31 mongoConf = pkgs.writeTextFile {
35 # for documentation of all options, see https://www.mongodb.com/docs/manual/reference/configuration-options/
38 dbPath: ${cfg.dataDir}/db
46 path: ${stateDir}/logs/mongod.log
55 slowOpThresholdMs: 500
61 mongoWtConf = pkgs.writeTextFile {
62 name = "mongowt.conf";
65 # for documentation of all options, see:
66 # https://www.mongodb.com/docs/manual/reference/configuration-options/
69 dbPath: ${cfg.dataDir}/db-wt
86 slowOpThresholdMs: 500
91 stateDir = "/var/lib/unifi-video";
96 options.services.unifi-video = {
102 Whether or not to enable the unifi-video service.
106 jrePackage = mkPackageOption pkgs "jre8" { };
108 unifiVideoPackage = mkPackageOption pkgs "unifi-video" { };
110 mongodbPackage = mkPackageOption pkgs "mongodb" {
111 default = "mongodb-5_0";
116 default = "${stateDir}/logs";
118 Where to store the logs.
124 default = "${stateDir}/data";
126 Where to store the database and other data.
130 openFirewall = mkOption {
134 Whether or not to open the required ports on the firewall.
138 maximumJavaHeapSize = mkOption {
139 type = types.nullOr types.int;
143 Set the maximum heap size for the JVM in MB.
149 default = "${cfg.dataDir}/unifi-video.pid";
150 defaultText = literalExpression ''"''${config.${opt.dataDir}}/unifi-video.pid"'';
151 description = "Location of unifi-video pid file.";
156 config = mkIf cfg.enable {
159 (options.services.unifi-video.openFirewall.highestPrio >= (mkOptionDefault null).priority)
160 "The current services.unifi-video.openFirewall = true default is deprecated and will change to false in 22.11. Set it explicitly to silence this warning.";
162 users.users.unifi-video = {
163 description = "UniFi Video controller daemon user";
165 group = "unifi-video";
168 users.groups.unifi-video = {};
170 networking.firewall = mkIf cfg.openFirewall {
171 # https://help.ui.com/hc/en-us/articles/217875218-UniFi-Video-Ports-Used
175 7445 # Video over HTTP (mobile app)
176 7446 # Video over HTTPS (mobile app)
177 7447 # RTSP via the controller
178 7442 # Camera management from cameras to NVR over WAN
181 6666 # Inbound camera streams sent over WAN
185 systemd.tmpfiles.rules = [
186 "d '${stateDir}' 0700 unifi-video unifi-video - -"
187 "d '/var/cache/unifi-video' 0700 unifi-video unifi-video - -"
189 "d '${stateDir}/logs' 0700 unifi-video unifi-video - -"
190 "C '${stateDir}/etc' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/etc"
191 "C '${stateDir}/webapps' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/webapps"
192 "C '${stateDir}/email' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/email"
193 "C '${stateDir}/fw' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/fw"
194 "C '${stateDir}/lib' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/lib"
196 "d '${stateDir}/data' 0700 unifi-video unifi-video - -"
197 "d '${stateDir}/data/db' 0700 unifi-video unifi-video - -"
198 "C '${stateDir}/data/system.properties' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/etc/system.properties"
200 "d '${stateDir}/bin' 0700 unifi-video unifi-video - -"
201 "f '${stateDir}/bin/evostreamms' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/evostreamms"
202 "f '${stateDir}/bin/libavcodec.so.54' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/libavcodec.so.54"
203 "f '${stateDir}/bin/libavformat.so.54' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/libavformat.so.54"
204 "f '${stateDir}/bin/libavutil.so.52' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/libavutil.so.52"
205 "f '${stateDir}/bin/ubnt.avtool' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/ubnt.avtool"
206 "f '${stateDir}/bin/ubnt.updater' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/ubnt.updater"
207 "C '${stateDir}/bin/mongo' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongo"
208 "C '${stateDir}/bin/mongod' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongod"
209 "C '${stateDir}/bin/mongoperf' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongoperf"
210 "C '${stateDir}/bin/mongos' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongos"
212 "d '${stateDir}/conf' 0700 unifi-video unifi-video - -"
213 "C '${stateDir}/conf/evostream' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/evostream"
214 "Z '${stateDir}/conf/evostream' 0700 unifi-video unifi-video - -"
215 "L+ '${stateDir}/conf/mongodv3.0+.conf' 0700 unifi-video unifi-video - ${mongoConf}"
216 "L+ '${stateDir}/conf/mongodv3.6+.conf' 0700 unifi-video unifi-video - ${mongoConf}"
217 "L+ '${stateDir}/conf/mongod-wt.conf' 0700 unifi-video unifi-video - ${mongoWtConf}"
218 "L+ '${stateDir}/conf/catalina.policy' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/catalina.policy"
219 "L+ '${stateDir}/conf/catalina.properties' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/catalina.properties"
220 "L+ '${stateDir}/conf/context.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/context.xml"
221 "L+ '${stateDir}/conf/logging.properties' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/logging.properties"
222 "L+ '${stateDir}/conf/server.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/server.xml"
223 "L+ '${stateDir}/conf/tomcat-users.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/tomcat-users.xml"
224 "L+ '${stateDir}/conf/web.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/web.xml"
227 systemd.services.unifi-video = {
228 description = "UniFi Video NVR daemon";
229 wantedBy = [ "multi-user.target" ];
230 after = [ "network.target" ] ;
231 unitConfig.RequiresMountsFor = stateDir;
232 # Make sure package upgrades trigger a service restart
233 restartTriggers = [ cfg.unifiVideoPackage cfg.mongodbPackage ];
234 path = with pkgs; [ gawk coreutils busybox which jre8 lsb-release libcap util-linux ];
237 ExecStart = "${(removeSuffix "\n" cmd)} ${mainClass} start";
238 ExecStop = "${(removeSuffix "\n" cmd)} stop ${mainClass} stop";
239 Restart = "on-failure";
241 User = "unifi-video";
242 WorkingDirectory = "${stateDir}";
248 (mkRenamedOptionModule [ "services" "unifi-video" "openPorts" ] [ "services" "unifi-video" "openFirewall" ])
251 meta.maintainers = with lib.maintainers; [ rsynnest ];