grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / web-apps / calibre-web.nix
blob0ca9ed2fbcf3bc3dde7468a72acb9eae7a1c6b0e
1 { config, lib, pkgs, ... }:
3 let
4   cfg = config.services.calibre-web;
6   inherit (lib) concatStringsSep mkEnableOption mkIf mkOption optional optionalString types;
7 in
9   options = {
10     services.calibre-web = {
11       enable = mkEnableOption "Calibre-Web";
13       package = lib.mkPackageOption pkgs "calibre-web" { };
15       listen = {
16         ip = mkOption {
17           type = types.str;
18           default = "::1";
19           description = ''
20             IP address that Calibre-Web should listen on.
21           '';
22         };
24         port = mkOption {
25           type = types.port;
26           default = 8083;
27           description = ''
28             Listen port for Calibre-Web.
29           '';
30         };
31       };
33       dataDir = mkOption {
34         type = types.str;
35         default = "calibre-web";
36         description = ''
37           The directory below {file}`/var/lib` where Calibre-Web stores its data.
38         '';
39       };
41       user = mkOption {
42         type = types.str;
43         default = "calibre-web";
44         description = "User account under which Calibre-Web runs.";
45       };
47       group = mkOption {
48         type = types.str;
49         default = "calibre-web";
50         description = "Group account under which Calibre-Web runs.";
51       };
53       openFirewall = mkOption {
54         type = types.bool;
55         default = false;
56         description = ''
57           Open ports in the firewall for the server.
58         '';
59       };
61       options = {
62         calibreLibrary = mkOption {
63           type = types.nullOr types.path;
64           default = null;
65           description = ''
66             Path to Calibre library.
67           '';
68         };
70         enableBookConversion = mkOption {
71           type = types.bool;
72           default = false;
73           description = ''
74             Configure path to the Calibre's ebook-convert in the DB.
75           '';
76         };
78         enableKepubify = mkEnableOption "kebup conversion support";
80         enableBookUploading = mkOption {
81           type = types.bool;
82           default = false;
83           description = ''
84             Allow books to be uploaded via Calibre-Web UI.
85           '';
86         };
88         reverseProxyAuth = {
89           enable = mkOption {
90             type = types.bool;
91             default = false;
92             description = ''
93               Enable authorization using auth proxy.
94             '';
95           };
97           header = mkOption {
98             type = types.str;
99             default = "";
100             description = ''
101               Auth proxy header name.
102             '';
103           };
104         };
105       };
106     };
107   };
109   config = mkIf cfg.enable {
110     systemd.services.calibre-web = let
111       appDb = "/var/lib/${cfg.dataDir}/app.db";
112       gdriveDb = "/var/lib/${cfg.dataDir}/gdrive.db";
113       calibreWebCmd = "${cfg.package}/bin/calibre-web -p ${appDb} -g ${gdriveDb}";
115       settings = concatStringsSep ", " (
116         [
117           "config_port = ${toString cfg.listen.port}"
118           "config_uploading = ${if cfg.options.enableBookUploading then "1" else "0"}"
119           "config_allow_reverse_proxy_header_login = ${if cfg.options.reverseProxyAuth.enable then "1" else "0"}"
120           "config_reverse_proxy_login_header_name = '${cfg.options.reverseProxyAuth.header}'"
121         ]
122         ++ optional (cfg.options.calibreLibrary != null) "config_calibre_dir = '${cfg.options.calibreLibrary}'"
123         ++ optional cfg.options.enableBookConversion "config_converterpath = '${pkgs.calibre}/bin/ebook-convert'"
124         ++ optional cfg.options.enableKepubify "config_kepubifypath = '${pkgs.kepubify}/bin/kepubify'"
125       );
126     in
127       {
128         description = "Web app for browsing, reading and downloading eBooks stored in a Calibre database";
129         after = [ "network.target" ];
130         wantedBy = [ "multi-user.target" ];
132         serviceConfig = {
133           Type = "simple";
134           User = cfg.user;
135           Group = cfg.group;
137           StateDirectory = cfg.dataDir;
138           ExecStartPre = pkgs.writeShellScript "calibre-web-pre-start" (
139             ''
140               __RUN_MIGRATIONS_AND_EXIT=1 ${calibreWebCmd}
142               ${pkgs.sqlite}/bin/sqlite3 ${appDb} "update settings set ${settings}"
143             '' + optionalString (cfg.options.calibreLibrary != null) ''
144               test -f "${cfg.options.calibreLibrary}/metadata.db" || { echo "Invalid Calibre library"; exit 1; }
145             ''
146           );
148           ExecStart = "${calibreWebCmd} -i ${cfg.listen.ip}";
149           Restart = "on-failure";
150         };
151       };
153     networking.firewall = mkIf cfg.openFirewall {
154       allowedTCPPorts = [ cfg.listen.port ];
155     };
157     users.users = mkIf (cfg.user == "calibre-web") {
158       calibre-web = {
159         isSystemUser = true;
160         group = cfg.group;
161       };
162     };
164     users.groups = mkIf (cfg.group == "calibre-web") {
165       calibre-web = {};
166     };
167   };
169   meta.maintainers = with lib.maintainers; [ pborzenkov ];