at 25.11-pre 3.7 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8let 9 inherit (lib) 10 literalExpression 11 mkEnableOption 12 mkIf 13 mkOption 14 mkPackageOption 15 ; 16 17 inherit (lib.types) 18 attrsOf 19 package 20 port 21 str 22 ; 23 24 cfg = config.services.crabfit; 25in 26 27{ 28 options.services.crabfit = { 29 enable = mkEnableOption "Crab Fit, a meeting scheduler based on peoples' availability"; 30 31 frontend = { 32 package = mkPackageOption pkgs "crabfit-frontend" { }; 33 34 finalDrv = mkOption { 35 readOnly = true; 36 type = package; 37 default = cfg.frontend.package.override { 38 api_url = "https://${cfg.api.host}"; 39 frontend_url = cfg.frontend.host; 40 }; 41 42 defaultText = literalExpression '' 43 cfg.package.override { 44 api_url = "https://''${cfg.api.host}"; 45 frontend_url = cfg.frontend.host; 46 }; 47 ''; 48 49 description = '' 50 The patched frontend, using the correct urls for the API and frontend. 51 ''; 52 }; 53 54 environment = mkOption { 55 type = attrsOf str; 56 default = { }; 57 description = '' 58 Environment variables for the crabfit frontend. 59 ''; 60 }; 61 62 host = mkOption { 63 type = str; 64 description = '' 65 The hostname of the frontend. 66 ''; 67 }; 68 69 port = mkOption { 70 type = port; 71 default = 3001; 72 description = '' 73 The internal listening port of the frontend. 74 ''; 75 }; 76 }; 77 78 api = { 79 package = mkPackageOption pkgs "crabfit-api" { }; 80 81 environment = mkOption { 82 type = attrsOf str; 83 default = { }; 84 description = '' 85 Environment variables for the crabfit API. 86 ''; 87 }; 88 89 host = mkOption { 90 type = str; 91 description = '' 92 The hostname of the API. 93 ''; 94 }; 95 96 port = mkOption { 97 type = port; 98 default = 3000; 99 description = '' 100 The internal listening port of the API. 101 ''; 102 }; 103 }; 104 }; 105 106 config = mkIf cfg.enable { 107 systemd.services = { 108 crabfit-api = { 109 description = "The API for Crab Fit."; 110 111 wantedBy = [ "multi-user.target" ]; 112 after = [ "postgresql.service" ]; 113 114 serviceConfig = { 115 # TODO: harden 116 ExecStart = lib.getExe cfg.api.package; 117 User = "crabfit"; 118 }; 119 120 environment = { 121 API_LISTEN = "127.0.0.1:${builtins.toString cfg.api.port}"; 122 DATABASE_URL = "postgres:///crabfit?host=/run/postgresql"; 123 FRONTEND_URL = "https://${cfg.frontend.host}"; 124 } // cfg.api.environment; 125 }; 126 127 crabfit-frontend = { 128 description = "The frontend for Crab Fit."; 129 130 wantedBy = [ "multi-user.target" ]; 131 132 serviceConfig = { 133 # TODO: harden 134 CacheDirectory = "crabfit"; 135 DynamicUser = true; 136 ExecStart = "${lib.getExe pkgs.nodejs} standalone/server.js"; 137 WorkingDirectory = cfg.frontend.finalDrv; 138 }; 139 140 environment = { 141 NEXT_PUBLIC_API_URL = "https://${cfg.api.host}"; 142 PORT = builtins.toString cfg.frontend.port; 143 } // cfg.frontend.environment; 144 }; 145 }; 146 147 users = { 148 groups.crabfit = { }; 149 150 users.crabfit = { 151 group = "crabfit"; 152 isSystemUser = true; 153 }; 154 }; 155 156 services = { 157 postgresql = { 158 enable = true; 159 160 ensureDatabases = [ "crabfit" ]; 161 162 ensureUsers = [ 163 { 164 name = "crabfit"; 165 ensureDBOwnership = true; 166 } 167 ]; 168 }; 169 }; 170 }; 171}