at 25.11-pre 5.6 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8let 9 cfg = config.services.calibre-web; 10 dataDir = if lib.hasPrefix "/" cfg.dataDir then cfg.dataDir else "/var/lib/${cfg.dataDir}"; 11 12 inherit (lib) 13 concatStringsSep 14 mkEnableOption 15 mkIf 16 mkOption 17 optional 18 optionals 19 optionalString 20 types 21 ; 22in 23{ 24 options = { 25 services.calibre-web = { 26 enable = mkEnableOption "Calibre-Web"; 27 28 package = lib.mkPackageOption pkgs "calibre-web" { }; 29 30 listen = { 31 ip = mkOption { 32 type = types.str; 33 default = "::1"; 34 description = '' 35 IP address that Calibre-Web should listen on. 36 ''; 37 }; 38 39 port = mkOption { 40 type = types.port; 41 default = 8083; 42 description = '' 43 Listen port for Calibre-Web. 44 ''; 45 }; 46 }; 47 48 dataDir = mkOption { 49 type = types.str; 50 default = "calibre-web"; 51 description = '' 52 Where Calibre-Web stores its data. 53 Either an absolute path, or the directory name below {file}`/var/lib`. 54 ''; 55 }; 56 57 user = mkOption { 58 type = types.str; 59 default = "calibre-web"; 60 description = "User account under which Calibre-Web runs."; 61 }; 62 63 group = mkOption { 64 type = types.str; 65 default = "calibre-web"; 66 description = "Group account under which Calibre-Web runs."; 67 }; 68 69 openFirewall = mkOption { 70 type = types.bool; 71 default = false; 72 description = '' 73 Open ports in the firewall for the server. 74 ''; 75 }; 76 77 options = { 78 calibreLibrary = mkOption { 79 type = types.nullOr types.path; 80 default = null; 81 description = '' 82 Path to Calibre library. 83 ''; 84 }; 85 86 enableBookConversion = mkOption { 87 type = types.bool; 88 default = false; 89 description = '' 90 Configure path to the Calibre's ebook-convert in the DB. 91 ''; 92 }; 93 94 enableKepubify = mkEnableOption "kebup conversion support"; 95 96 enableBookUploading = mkOption { 97 type = types.bool; 98 default = false; 99 description = '' 100 Allow books to be uploaded via Calibre-Web UI. 101 ''; 102 }; 103 104 reverseProxyAuth = { 105 enable = mkOption { 106 type = types.bool; 107 default = false; 108 description = '' 109 Enable authorization using auth proxy. 110 ''; 111 }; 112 113 header = mkOption { 114 type = types.str; 115 default = ""; 116 description = '' 117 Auth proxy header name. 118 ''; 119 }; 120 }; 121 }; 122 }; 123 }; 124 125 config = mkIf cfg.enable { 126 systemd.tmpfiles.settings = lib.optionalAttrs (lib.hasPrefix "/" cfg.dataDir) { 127 "10-calibre-web".${dataDir}.d = { 128 inherit (cfg) user group; 129 mode = "0700"; 130 }; 131 }; 132 133 systemd.services.calibre-web = 134 let 135 appDb = "${dataDir}/app.db"; 136 gdriveDb = "${dataDir}/gdrive.db"; 137 calibreWebCmd = "${cfg.package}/bin/calibre-web -p ${appDb} -g ${gdriveDb}"; 138 139 settings = concatStringsSep ", " ( 140 [ 141 "config_port = ${toString cfg.listen.port}" 142 "config_uploading = ${if cfg.options.enableBookUploading then "1" else "0"}" 143 "config_allow_reverse_proxy_header_login = ${ 144 if cfg.options.reverseProxyAuth.enable then "1" else "0" 145 }" 146 "config_reverse_proxy_login_header_name = '${cfg.options.reverseProxyAuth.header}'" 147 ] 148 ++ optional ( 149 cfg.options.calibreLibrary != null 150 ) "config_calibre_dir = '${cfg.options.calibreLibrary}'" 151 ++ optionals cfg.options.enableBookConversion [ 152 "config_converterpath = '${pkgs.calibre}/bin/ebook-convert'" 153 "config_binariesdir = '${pkgs.calibre}/bin/'" 154 ] 155 ++ optional cfg.options.enableKepubify "config_kepubifypath = '${pkgs.kepubify}/bin/kepubify'" 156 ); 157 in 158 { 159 description = "Web app for browsing, reading and downloading eBooks stored in a Calibre database"; 160 after = [ "network.target" ]; 161 wantedBy = [ "multi-user.target" ]; 162 163 serviceConfig = 164 { 165 Type = "simple"; 166 User = cfg.user; 167 Group = cfg.group; 168 169 ExecStartPre = pkgs.writeShellScript "calibre-web-pre-start" ( 170 '' 171 __RUN_MIGRATIONS_AND_EXIT=1 ${calibreWebCmd} 172 173 ${pkgs.sqlite}/bin/sqlite3 ${appDb} "update settings set ${settings}" 174 '' 175 + optionalString (cfg.options.calibreLibrary != null) '' 176 test -f "${cfg.options.calibreLibrary}/metadata.db" || { echo "Invalid Calibre library"; exit 1; } 177 '' 178 ); 179 180 ExecStart = "${calibreWebCmd} -i ${cfg.listen.ip}"; 181 Restart = "on-failure"; 182 } 183 // lib.optionalAttrs (!(lib.hasPrefix "/" cfg.dataDir)) { 184 StateDirectory = cfg.dataDir; 185 }; 186 }; 187 188 networking.firewall = mkIf cfg.openFirewall { 189 allowedTCPPorts = [ cfg.listen.port ]; 190 }; 191 192 users.users = mkIf (cfg.user == "calibre-web") { 193 calibre-web = { 194 isSystemUser = true; 195 group = cfg.group; 196 }; 197 }; 198 199 users.groups = mkIf (cfg.group == "calibre-web") { 200 calibre-web = { }; 201 }; 202 }; 203 204 meta.maintainers = with lib.maintainers; [ pborzenkov ]; 205}