vuls: init at 0.27.0 (#348530)
[NixPkgs.git] / nixos / modules / services / web-apps / suwayomi-server.nix
blobcaa091685d2fb662297044456b6e1921e04fbbeb
1 { config, pkgs, lib, ... }:
3 let
4   cfg = config.services.suwayomi-server;
5   inherit (lib) mkOption mkEnableOption mkIf types;
7   format = pkgs.formats.hocon { };
8 in
10   options = {
11     services.suwayomi-server = {
12       enable = mkEnableOption "Suwayomi, a free and open source manga reader server that runs extensions built for Tachiyomi";
14       package = lib.mkPackageOption pkgs "suwayomi-server" { };
16       dataDir = mkOption {
17         type = types.path;
18         default = "/var/lib/suwayomi-server";
19         example = "/var/data/mangas";
20         description = ''
21           The path to the data directory in which Suwayomi-Server will download scans.
22         '';
23       };
25       user = mkOption {
26         type = types.str;
27         default = "suwayomi";
28         example = "root";
29         description = ''
30           User account under which Suwayomi-Server runs.
31         '';
32       };
34       group = mkOption {
35         type = types.str;
36         default = "suwayomi";
37         example = "medias";
38         description = ''
39           Group under which Suwayomi-Server runs.
40         '';
41       };
43       openFirewall = mkOption {
44         type = types.bool;
45         default = false;
46         description = ''
47           Whether to open the firewall for the port in {option}`services.suwayomi-server.settings.server.port`.
48         '';
49       };
51       settings = mkOption {
52         type = types.submodule {
53           freeformType = format.type;
54           options = {
55             server = {
56               ip = mkOption {
57                 type = types.str;
58                 default = "0.0.0.0";
59                 example = "127.0.0.1";
60                 description = ''
61                   The ip that Suwayomi will bind to.
62                 '';
63               };
65               port = mkOption {
66                 type = types.port;
67                 default = 8080;
68                 example = 4567;
69                 description = ''
70                   The port that Suwayomi will listen to.
71                 '';
72               };
74               basicAuthEnabled = mkEnableOption ''
75                 basic access authentication for Suwayomi-Server.
76                 Enabling this option is useful when hosting on a public network/the Internet
77               '';
79               basicAuthUsername = mkOption {
80                 type = types.nullOr types.str;
81                 default = null;
82                 description = ''
83                   The username value that you have to provide when authenticating.
84                 '';
85               };
87               # NOTE: this is not a real upstream option
88               basicAuthPasswordFile = mkOption {
89                 type = types.nullOr types.path;
90                 default = null;
91                 example = "/var/secrets/suwayomi-server-password";
92                 description = ''
93                   The password file containing the value that you have to provide when authenticating.
94                 '';
95               };
97               downloadAsCbz = mkOption {
98                 type = types.bool;
99                 default = false;
100                 description = ''
101                   Download chapters as `.cbz` files.
102                 '';
103               };
105               extensionRepos = mkOption {
106                 type = types.listOf types.str;
107                 default = [];
108                 example = [
109                   "https://raw.githubusercontent.com/MY_ACCOUNT/MY_REPO/repo/index.min.json"
110                 ];
111                 description = ''
112                   URL of repositories from which the extensions can be installed.
113                 '';
114               };
116               localSourcePath = mkOption {
117                 type = types.path;
118                 default = cfg.dataDir;
119                 defaultText = lib.literalExpression "suwayomi-server.dataDir";
120                 example = "/var/data/local_mangas";
121                 description = ''
122                   Path to the local source folder.
123                 '';
124               };
126               systemTrayEnabled = mkOption {
127                 type = types.bool;
128                 default = false;
129                 description = ''
130                   Whether to enable a system tray icon, if possible.
131                 '';
132               };
133             };
134           };
135         };
136         description = ''
137           Configuration to write to {file}`server.conf`.
138           See <https://github.com/Suwayomi/Suwayomi-Server/wiki/Configuring-Suwayomi-Server> for more information.
139         '';
140         default = { };
141         example = {
142           server.socksProxyEnabled = true;
143           server.socksProxyHost = "yourproxyhost.com";
144           server.socksProxyPort = "8080";
145         };
146       };
147     };
148   };
150   config = mkIf cfg.enable {
152     assertions = [{
153       assertion = with cfg.settings.server; basicAuthEnabled -> (basicAuthUsername != null && basicAuthPasswordFile != null);
154       message = ''
155         [suwayomi-server]: the username and the password file cannot be null when the basic auth is enabled
156       '';
157     }];
159     networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.settings.server.port ];
161     users.groups = mkIf (cfg.group == "suwayomi") {
162       suwayomi = { };
163     };
165     users.users = mkIf (cfg.user == "suwayomi") {
166       suwayomi = {
167         group = cfg.group;
168         # Need to set the user home because the package writes to ~/.local/Tachidesk
169         home = cfg.dataDir;
170         description = "Suwayomi Daemon user";
171         isSystemUser = true;
172       };
173     };
175     systemd.tmpfiles.settings."10-suwayomi-server" = {
176       "${cfg.dataDir}/.local/share/Tachidesk".d = {
177         mode = "0700";
178         inherit (cfg) user group;
179       };
180     };
182     systemd.services.suwayomi-server =
183       let
184         configFile = format.generate "server.conf" (lib.pipe cfg.settings [
185           (settings: lib.recursiveUpdate settings {
186             server.basicAuthPasswordFile = null;
187             server.basicAuthPassword =
188               if settings.server.basicAuthEnabled
189               then "$TACHIDESK_SERVER_BASIC_AUTH_PASSWORD"
190               else null;
191           })
192           (lib.filterAttrsRecursive (_: x: x != null))
193         ]);
194       in
195       {
196         description = "A free and open source manga reader server that runs extensions built for Tachiyomi.";
198         wantedBy = [ "multi-user.target" ];
199         wants = [ "network-online.target" ];
200         after = [ "network-online.target" ];
202         script = ''
203           ${lib.optionalString cfg.settings.server.basicAuthEnabled ''
204             export TACHIDESK_SERVER_BASIC_AUTH_PASSWORD="$(<${cfg.settings.server.basicAuthPasswordFile})"
205           ''}
206           ${lib.getExe pkgs.envsubst} -i ${configFile} -o ${cfg.dataDir}/.local/share/Tachidesk/server.conf
207           ${lib.getExe cfg.package} -Dsuwayomi.tachidesk.config.server.rootDir=${cfg.dataDir}
208         '';
210         serviceConfig = {
211           User = cfg.user;
212           Group = cfg.group;
214           Type = "simple";
215           Restart = "on-failure";
217           StateDirectory = mkIf (cfg.dataDir == "/var/lib/suwayomi-server") "suwayomi-server";
218         };
219       };
220   };
222   meta = {
223     maintainers = with lib.maintainers; [ ratcornu ];
224     doc = ./suwayomi-server.md;
225   };