at 25.11-pre 6.3 kB view raw
1{ 2 config, 3 pkgs, 4 lib, 5 ... 6}: 7 8let 9 cfg = config.services.pingvin-share; 10 inherit (lib) 11 mkOption 12 mkEnableOption 13 mkIf 14 mkPackageOption 15 types 16 ; 17in 18 19{ 20 options = { 21 services.pingvin-share = { 22 enable = mkEnableOption "Pingvin Share, a self-hosted file sharing platform"; 23 24 user = mkOption { 25 type = types.str; 26 default = "pingvin"; 27 description = '' 28 User account under which Pingvin Share runs. 29 ''; 30 }; 31 32 group = mkOption { 33 type = types.str; 34 default = "pingvin"; 35 description = '' 36 Group under which Pingvin Share runs. 37 ''; 38 }; 39 40 openFirewall = mkOption { 41 type = types.bool; 42 default = false; 43 description = '' 44 Whether to open the firewall for the port in {option}`services.pingvin-share.frontend.port`. 45 ''; 46 }; 47 48 dataDir = mkOption { 49 type = types.path; 50 default = "/var/lib/pingvin-share"; 51 example = "/var/lib/pingvin"; 52 description = '' 53 The path to the data directory in which Pingvin Share will store its data. 54 ''; 55 }; 56 57 hostname = mkOption { 58 type = types.str; 59 default = "localhost:${toString cfg.backend.port}"; 60 defaultText = lib.literalExpression "localhost:\${options.services.pingvin-share.backend.port}"; 61 example = "pingvin-share.domain.tdl"; 62 description = '' 63 The domain name of your instance. If null, the redirections will be made to localhost. 64 ''; 65 }; 66 67 https = mkOption { 68 type = types.bool; 69 default = false; 70 example = true; 71 description = '' 72 Whether to enable HTTPS for the domain. 73 ''; 74 }; 75 76 backend = { 77 package = mkPackageOption pkgs [ 78 "pingvin-share" 79 "backend" 80 ] { }; 81 82 port = mkOption { 83 type = types.port; 84 default = 8080; 85 example = 9000; 86 description = '' 87 The port that the backend service of Pingvin Share will listen to. 88 ''; 89 }; 90 }; 91 92 frontend = { 93 package = mkPackageOption pkgs [ 94 "pingvin-share" 95 "frontend" 96 ] { }; 97 98 port = mkOption { 99 type = types.port; 100 default = 3000; 101 example = 8000; 102 description = '' 103 The port that the frontend service of Pingvin Share will listen to. 104 ''; 105 }; 106 }; 107 108 nginx = { 109 enable = mkEnableOption "a Nginx reverse proxy for Pingvin Share."; 110 }; 111 }; 112 }; 113 114 config = mkIf cfg.enable { 115 116 users.groups = mkIf (cfg.group == "pingvin") { pingvin = { }; }; 117 118 users.users = mkIf (cfg.user == "pingvin") { 119 pingvin = { 120 group = cfg.group; 121 description = "Pingvin Share daemon user"; 122 isSystemUser = true; 123 }; 124 }; 125 126 networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.frontend.port ]; 127 128 systemd.services.pingvin-share-backend = { 129 description = "Backend service of Pingvin Share, a self-hosted file sharing platform."; 130 131 wantedBy = [ 132 "multi-user.target" 133 "pingvin-share-frontend.service" 134 ]; 135 before = [ "pingvin-share-frontend.service" ]; 136 after = [ 137 "network.target" 138 "network-online.target" 139 ]; 140 wants = [ "network-online.target" ]; 141 142 environment = { 143 PRISMA_SCHEMA_ENGINE_BINARY = "${pkgs.prisma-engines}/bin/schema-engine"; 144 PRISMA_QUERY_ENGINE_BINARY = "${pkgs.prisma-engines}/bin/query-engine"; 145 PRISMA_QUERY_ENGINE_LIBRARY = "${pkgs.prisma-engines}/lib/libquery_engine.node"; 146 PRISMA_INTROSPECTION_ENGINE_BINARY = "${pkgs.prisma-engines}/bin/introspection-engine"; 147 PRISMA_FMT_BINARY = "${pkgs.prisma-engines}/bin/prisma-fmt"; 148 BACKEND_PORT = toString cfg.backend.port; 149 DATABASE_URL = "file:${cfg.dataDir}/pingvin-share.db?connection_limit=1"; 150 DATA_DIRECTORY = cfg.dataDir; 151 }; 152 153 path = with pkgs; [ 154 cfg.backend.package 155 openssl 156 prisma-engines 157 ]; 158 159 serviceConfig = { 160 User = cfg.user; 161 Group = cfg.group; 162 Type = "simple"; 163 Restart = "on-failure"; 164 ExecStartPre = [ 165 "${cfg.backend.package}/node_modules/.bin/prisma migrate deploy" 166 "${cfg.backend.package}/node_modules/.bin/prisma db seed" 167 ]; 168 ExecStart = "${cfg.backend.package}/node_modules/.bin/ts-node dist/src/main"; 169 StateDirectory = mkIf (cfg.dataDir == "/var/lib/pingvin-share") "pingvin-share"; 170 WorkingDirectory = cfg.backend.package; 171 }; 172 }; 173 174 systemd.services.pingvin-share-frontend = { 175 description = "Frontend service of Pingvin Share, a self-hosted file sharing platform."; 176 177 wantedBy = [ "multi-user.target" ]; 178 wants = [ 179 "network-online.target" 180 "pingvin-share-backend.service" 181 ]; 182 after = [ 183 "network-online.target" 184 "pingvin-share-backend.service" 185 ]; 186 187 environment = { 188 PORT = toString cfg.frontend.port; 189 API_URL = "${if cfg.https then "https" else "http"}://${cfg.hostname}"; 190 }; 191 path = [ cfg.frontend.package ]; 192 193 serviceConfig = { 194 User = cfg.user; 195 Group = cfg.group; 196 Type = "simple"; 197 Restart = "on-failure"; 198 ExecStart = "${cfg.frontend.package}/node_modules/.bin/next start"; 199 StateDirectory = mkIf (cfg.dataDir == "/var/lib/pingvin-share") "pingvin-share"; 200 WorkingDirectory = cfg.frontend.package; 201 }; 202 }; 203 204 services.nginx = mkIf cfg.nginx.enable { 205 enable = lib.mkDefault true; 206 virtualHosts."${cfg.hostname}" = { 207 enableACME = cfg.https; 208 forceSSL = cfg.https; 209 210 locations."/" = { 211 proxyPass = "http://localhost:${toString cfg.frontend.port}"; 212 recommendedProxySettings = true; 213 }; 214 locations."/api" = { 215 proxyPass = "http://localhost:${toString cfg.backend.port}"; 216 recommendedProxySettings = true; 217 }; 218 }; 219 }; 220 }; 221 222 meta = { 223 maintainers = with lib.maintainers; [ ratcornu ]; 224 doc = ./pingvin-share.md; 225 }; 226}