1{ config, lib, pkgs, ... }:
2
3let
4 cfg = config.services.kavita;
5in {
6 options.services.kavita = {
7 enable = lib.mkEnableOption (lib.mdDoc "Kavita reading server");
8
9 user = lib.mkOption {
10 type = lib.types.str;
11 default = "kavita";
12 description = lib.mdDoc "User account under which Kavita runs.";
13 };
14
15 package = lib.mkPackageOptionMD pkgs "kavita" { };
16
17 dataDir = lib.mkOption {
18 default = "/var/lib/kavita";
19 type = lib.types.str;
20 description = lib.mdDoc "The directory where Kavita stores its state.";
21 };
22
23 tokenKeyFile = lib.mkOption {
24 type = lib.types.path;
25 description = lib.mdDoc ''
26 A file containing the TokenKey, a secret with at 128+ bits.
27 It can be generated with `head -c 32 /dev/urandom | base64`.
28 '';
29 };
30 port = lib.mkOption {
31 default = 5000;
32 type = lib.types.port;
33 description = lib.mdDoc "Port to bind to.";
34 };
35 ipAdresses = lib.mkOption {
36 default = ["0.0.0.0" "::"];
37 type = lib.types.listOf lib.types.str;
38 description = lib.mdDoc "IP Addresses to bind to. The default is to bind
39 to all IPv4 and IPv6 addresses.";
40 };
41 };
42
43 config = lib.mkIf cfg.enable {
44 systemd.services.kavita = {
45 description = "Kavita";
46 wantedBy = [ "multi-user.target" ];
47 after = [ "network.target" ];
48 preStart = ''
49 umask u=rwx,g=rx,o=
50 cat > "${cfg.dataDir}/config/appsettings.json" <<EOF
51 {
52 "TokenKey": "$(cat ${cfg.tokenKeyFile})",
53 "Port": ${toString cfg.port},
54 "IpAddresses": "${lib.concatStringsSep "," cfg.ipAdresses}"
55 }
56 EOF
57 '';
58 serviceConfig = {
59 WorkingDirectory = cfg.dataDir;
60 ExecStart = "${lib.getExe cfg.package}";
61 Restart = "always";
62 User = cfg.user;
63 };
64 };
65
66 systemd.tmpfiles.rules = [
67 "d '${cfg.dataDir}' 0750 ${cfg.user} ${cfg.user} - -"
68 "d '${cfg.dataDir}/config' 0750 ${cfg.user} ${cfg.user} - -"
69 ];
70
71 users = {
72 users.${cfg.user} = {
73 description = "kavita service user";
74 isSystemUser = true;
75 group = cfg.user;
76 home = cfg.dataDir;
77 };
78 groups.${cfg.user} = { };
79 };
80 };
81
82 meta.maintainers = with lib.maintainers; [ misterio77 ];
83}