grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / web-apps / crabfit.nix
blobd58027a6965df82b35f8fe60fb110132f63b2c4e
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
8 let
9   inherit (lib)
10     literalExpression
11     mkEnableOption
12     mkIf
13     mkOption
14     mkPackageOption
15     ;
17   inherit (lib.types)
18     attrsOf
19     package
20     port
21     str
22     ;
24   cfg = config.services.crabfit;
28   options.services.crabfit = {
29     enable = mkEnableOption "Crab Fit, a meeting scheduler based on peoples' availability";
31     frontend = {
32       package = mkPackageOption pkgs "crabfit-frontend" { };
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         };
42         defaultText = literalExpression ''
43           cfg.package.override {
44             api_url = "https://''${cfg.api.host}";
45             frontend_url = cfg.frontend.host;
46           };
47         '';
49         description = ''
50           The patched frontend, using the correct urls for the API and frontend.
51         '';
52       };
54       environment = mkOption {
55         type = attrsOf str;
56         default = { };
57         description = ''
58           Environment variables for the crabfit frontend.
59         '';
60       };
62       host = mkOption {
63         type = str;
64         description = ''
65           The hostname of the frontend.
66         '';
67       };
69       port = mkOption {
70         type = port;
71         default = 3001;
72         description = ''
73           The internal listening port of the frontend.
74         '';
75       };
76     };
78     api = {
79       package = mkPackageOption pkgs "crabfit-api" { };
81       environment = mkOption {
82         type = attrsOf str;
83         default = { };
84         description = ''
85           Environment variables for the crabfit API.
86         '';
87       };
89       host = mkOption {
90         type = str;
91         description = ''
92           The hostname of the API.
93         '';
94       };
96       port = mkOption {
97         type = port;
98         default = 3000;
99         description = ''
100           The internal listening port of the API.
101         '';
102       };
103     };
104   };
106   config = mkIf cfg.enable {
107     systemd.services = {
108       crabfit-api = {
109         description = "The API for Crab Fit.";
111         wantedBy = [ "multi-user.target" ];
112         after = [ "postgresql.service" ];
114         serviceConfig = {
115           # TODO: harden
116           ExecStart = lib.getExe cfg.api.package;
117           User = "crabfit";
118         };
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       };
127       crabfit-frontend = {
128         description = "The frontend for Crab Fit.";
130         wantedBy = [ "multi-user.target" ];
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         };
140         environment = {
141           NEXT_PUBLIC_API_URL = "https://${cfg.api.host}";
142           PORT = builtins.toString cfg.frontend.port;
143         } // cfg.frontend.environment;
144       };
145     };
147     users = {
148       groups.crabfit = { };
150       users.crabfit = {
151         group = "crabfit";
152         isSystemUser = true;
153       };
154     };
156     services = {
157       postgresql = {
158         enable = true;
160         ensureDatabases = [ "crabfit" ];
162         ensureUsers = [
163           {
164             name = "crabfit";
165             ensureDBOwnership = true;
166           }
167         ];
168       };
169     };
170   };