This commit is contained in:
Fabian Montero 2026-02-03 15:12:59 -06:00
commit b4974a7fc6
9 changed files with 381 additions and 29 deletions

View file

@ -0,0 +1,11 @@
{
config,
doctrine,
...
}:
doctrine.lib.mkModule {
inherit config;
name = "socialpredict";
options = ./options.nix;
sys = ./sys.nix;
}

View file

@ -0,0 +1,78 @@
{
config,
doctrine,
lib,
modulesPath,
pkgs,
...
}:
with lib.types; let
inherit (pkgs.${doctrine.prefix}) socialpredict;
in {
sys = {
frontend = lib.mkOption {
type = package;
default = socialpredict.frontend;
defaultText = "pkgs.\${doctrine.prefix}.frontend";
description = "socialpredict frontend package";
};
backend = lib.mkOption {
type = package;
default = socialpredict.backend;
defaultText = "pkgs.\${doctrine.prefix}.backend";
description = "socialpredict backend package";
};
package = lib.mkOption {
type = package;
default = pkgs.${doctrine.prefix}.socialpredict;
defaultText = "pkgs.\${doctrine.prefix}.socialpredict";
description = "socialpredict package";
};
database = lib.mkOption {
type = str;
default = "socialpredict";
description = "database name";
};
user = lib.mkOption {
type = str;
default = "socialpredict";
description = "user that will run the backend";
};
group = lib.mkOption {
type = str;
default = "socialpredict";
description = "group that will run the backend";
};
backendPort = lib.mkOption {
type = port;
description = "backend port";
};
initialAdminPassword = lib.mkOption {
type = str;
default = "change-me";
description = "initial password of the 'admin' user";
};
domain = lib.mkOption {
type = nullOr str;
default = null;
description = "domain host";
};
nginx = lib.mkOption {
type = submodule (
lib.recursiveUpdate (import "${modulesPath}/services/web-servers/nginx/vhost-options.nix" {inherit config lib;}) {}
);
default = {};
description = "extra nginx virtual host config";
};
};
}

View file

@ -0,0 +1,102 @@
{
cfg,
doctrine,
lib,
pkgs,
...
}: {
services = {
nginx = lib.mkIf (cfg.domain != null) {
enable = true;
virtualHosts.${cfg.domain} = lib.mkMerge [
cfg.nginx
{
locations = {
"/" = {
root = "${cfg.frontend}";
index = "index.html";
tryFiles = "$uri $uri/ /index.html =404";
};
"/api/" = {
proxyPass = "http://localhost:${toString cfg.backendPort}/";
};
"= /env-config.js" = {
alias = "${pkgs.writeText "socialpredict-env-config.js" ''
window.__ENV__ = {
DOMAIN_URL: "https://${cfg.domain}",
API_URL: "https://${cfg.domain}/api"
};
''}";
};
};
}
];
};
postgresql = {
enable = true;
ensureUsers = [
{
name = cfg.user;
ensureDBOwnership = cfg.user == cfg.database;
}
];
ensureDatabases = [cfg.database];
};
};
systemd.services.socialpredict = {
after = ["postgresql.service"];
wants = ["postgresql.service"];
wantedBy = ["multi-user.target"];
environment = {
ADMIN_PASSWORD = cfg.initialAdminPassword;
BACKEND_PORT = toString cfg.backendPort;
POSTGRES_URL = "postgresql:///${cfg.database}?host=/var/run/postgresql";
};
serviceConfig = {
Group = cfg.group;
User = cfg.user;
ExecStart = lib.getExe cfg.backend;
KeyringMode = "private";
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateMounts = "yes";
PrivateTmp = "yes";
ProtectControlGroups = true;
ProtectHome = "yes";
ProtectHostname = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectSystem = "strict";
RemoveIPC = true;
RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
ReadWritePaths = [
"/var/run/postgresql"
];
};
};
users = {
groups.${cfg.group} = {};
users.${cfg.user} = {
inherit (cfg) group;
isSystemUser = true;
};
};
}