Files
nixpkgs/nixos/modules/services/web-apps/crabfit.nix
Wolfgang Walther 41c5662cbe nixos/postgresql: move postStart into separate unit
This avoids restarting the postgresql server, when only ensureDatabases
or ensureUsers have been changed. It will also allow to properly wait
for recovery to finish later.

To wait for "postgresql is ready" in other services, we now provide a
postgresql.target.

Resolves #400018

Co-authored-by: Marcel <me@m4rc3l.de>
2025-06-24 15:26:47 +02:00

172 lines
3.6 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
literalExpression
mkEnableOption
mkIf
mkOption
mkPackageOption
;
inherit (lib.types)
attrsOf
package
port
str
;
cfg = config.services.crabfit;
in
{
options.services.crabfit = {
enable = mkEnableOption "Crab Fit, a meeting scheduler based on peoples' availability";
frontend = {
package = mkPackageOption pkgs "crabfit-frontend" { };
finalDrv = mkOption {
readOnly = true;
type = package;
default = cfg.frontend.package.override {
api_url = "https://${cfg.api.host}";
frontend_url = cfg.frontend.host;
};
defaultText = literalExpression ''
cfg.package.override {
api_url = "https://''${cfg.api.host}";
frontend_url = cfg.frontend.host;
};
'';
description = ''
The patched frontend, using the correct urls for the API and frontend.
'';
};
environment = mkOption {
type = attrsOf str;
default = { };
description = ''
Environment variables for the crabfit frontend.
'';
};
host = mkOption {
type = str;
description = ''
The hostname of the frontend.
'';
};
port = mkOption {
type = port;
default = 3001;
description = ''
The internal listening port of the frontend.
'';
};
};
api = {
package = mkPackageOption pkgs "crabfit-api" { };
environment = mkOption {
type = attrsOf str;
default = { };
description = ''
Environment variables for the crabfit API.
'';
};
host = mkOption {
type = str;
description = ''
The hostname of the API.
'';
};
port = mkOption {
type = port;
default = 3000;
description = ''
The internal listening port of the API.
'';
};
};
};
config = mkIf cfg.enable {
systemd.services = {
crabfit-api = {
description = "The API for Crab Fit.";
wantedBy = [ "multi-user.target" ];
after = [ "postgresql.target" ];
serviceConfig = {
# TODO: harden
ExecStart = lib.getExe cfg.api.package;
User = "crabfit";
};
environment = {
API_LISTEN = "127.0.0.1:${builtins.toString cfg.api.port}";
DATABASE_URL = "postgres:///crabfit?host=/run/postgresql";
FRONTEND_URL = "https://${cfg.frontend.host}";
} // cfg.api.environment;
};
crabfit-frontend = {
description = "The frontend for Crab Fit.";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
# TODO: harden
CacheDirectory = "crabfit";
DynamicUser = true;
ExecStart = "${lib.getExe pkgs.nodejs} standalone/server.js";
WorkingDirectory = cfg.frontend.finalDrv;
};
environment = {
NEXT_PUBLIC_API_URL = "https://${cfg.api.host}";
PORT = builtins.toString cfg.frontend.port;
} // cfg.frontend.environment;
};
};
users = {
groups.crabfit = { };
users.crabfit = {
group = "crabfit";
isSystemUser = true;
};
};
services = {
postgresql = {
enable = true;
ensureDatabases = [ "crabfit" ];
ensureUsers = [
{
name = "crabfit";
ensureDBOwnership = true;
}
];
};
};
};
}