Done Postgresql and Vaultwarden

This commit is contained in:
pazpi 2025-01-02 12:40:48 +01:00
parent 199db5b3bc
commit eab5c16eb3
3 changed files with 198 additions and 4 deletions

View file

@ -3,6 +3,7 @@
./media-mgr.nix ./media-mgr.nix
./nextcloud.nix ./nextcloud.nix
./plex.nix ./plex.nix
./postgres.nix
# ./searx.nix # ./searx.nix
./vaultwarden.nix ./vaultwarden.nix
]; ];

View file

@ -0,0 +1,177 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.postgresql;
upgrade-script =
old: new:
let
oldStr = builtins.toString old;
newStr = builtins.toString new;
oldPkg = pkgs.${"postgresql_${oldStr}"};
newPkg = pkgs.${"postgresql_${newStr}"};
in
pkgs.writeScriptBin "upgrade-pg-cluster-${oldStr}-${newStr}" ''
set -eux
# XXX it's perhaps advisable to stop all services that depend on postgresql
systemctl stop postgresql
export NEWDATA="/var/lib/postgresql/${newPkg.psqlSchema}"
export NEWBIN="${newPkg}/bin"
export OLDDATA="/var/lib/postgresql/${oldPkg.psqlSchema}"
export OLDBIN="${oldPkg}/bin"
install -d -m 0700 -o postgres -g postgres "$NEWDATA"
cd "$NEWDATA"
sudo -u postgres $NEWBIN/initdb -D "$NEWDATA"
sudo -u postgres $NEWBIN/pg_upgrade \
--old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \
--old-bindir $OLDBIN --new-bindir $NEWBIN \
"$@"
'';
in
{
options.my.services.postgresql = {
enable = lib.mkEnableOption "Enable Postgres module";
debug = lib.mkOption {
type = lib.types.bool;
description = ''
Enable debugging options.
Currently enables shared_preload_libraries = "auto_explain, pg_stat_statements"
See https://www.postgresql.org/docs/current/pgstatstatements.html'';
default = false;
};
enableTCPIP = lib.mkOption {
type = lib.types.bool;
description = "Enable TCP/IP connection on given port.";
default = false;
};
ensures = lib.mkOption {
description = "List of username, database and/or passwords that should be created.";
type = lib.types.listOf (
lib.types.submodule {
options = {
username = lib.mkOption {
type = lib.types.str;
description = "Postgres user name.";
};
database = lib.mkOption {
type = lib.types.str;
description = "Postgres database.";
};
passwordFile = lib.mkOption {
type = lib.types.nullOr lib.types.str;
description = "Optional password file for the postgres user. If not given, only peer auth is accepted for this user, otherwise password auth is allowed.";
default = null;
example = "/run/secrets/postgresql/password";
};
};
}
);
default = [ ];
};
};
config =
let
commonConfig = {
systemd.services.postgresql.serviceConfig.Restart = "always";
services.postgresql.settings = {
};
};
tcpConfig = {
services.postgresql.enableTCPIP = true;
services.postgresql.authentication = lib.mkOverride 10 ''
#type database DBuser origin-address auth-method
local all all peer
# ipv4
host all all 127.0.0.1/32 password
# ipv6
host all all ::1/128 password
'';
};
dbConfig = ensureCfgs: {
services.postgresql.enable = lib.mkDefault ((builtins.length ensureCfgs) > 0);
services.postgresql.ensureDatabases = map ({ database, ... }: database) ensureCfgs;
services.postgresql.ensureUsers = map (
{ username, database, ... }:
{
name = username;
ensureDBOwnership = true;
ensureClauses.login = true;
}
) ensureCfgs;
services.postgresql.authentication = pkgs.lib.mkOverride 10 ''
#type database DBuser auth-method
local all all trust
'';
};
pwdConfig = ensureCfgs: {
systemd.services.postgresql.postStart =
let
prefix = ''
$PSQL -tA <<'EOF'
DO $$
DECLARE password TEXT;
BEGIN
'';
suffix = ''
END $$;
EOF
'';
exec =
{ username, passwordFile, ... }:
''
password := trim(both from replace(pg_read_file('${passwordFile}'), E'\n', '''));
EXECUTE format('ALTER ROLE ${username} WITH PASSWORD '''%s''';', password);
'';
cfgsWithPasswords = builtins.filter (cfg: cfg.passwordFile != null) ensureCfgs;
in
if (builtins.length cfgsWithPasswords) == 0 then
""
else
prefix + (lib.concatStrings (map exec cfgsWithPasswords)) + suffix;
};
debugConfig =
enableDebug:
lib.mkIf enableDebug {
services.postgresql.settings.shared_preload_libraries = "auto_explain, pg_stat_statements";
};
in
lib.mkIf cfg.enable (
lib.mkMerge ([
commonConfig
(dbConfig cfg.ensures)
(pwdConfig cfg.ensures)
(lib.mkIf cfg.enableTCPIP tcpConfig)
(debugConfig cfg.debug)
{
environment.systemPackages = lib.mkIf config.services.postgresql.enable [
(upgrade-script 14 15)
(upgrade-script 15 16)
(upgrade-script 16 17)
];
}
])
);
}

View file

@ -6,8 +6,7 @@
}: }:
let let
cfg = config.my.services.vaultwarden; cfg = config.my.services.vaultwarden;
user = config.users.users.vaultwarden.name; rocketPort = 8222;
group = config.users.groups.vaultwarden.name;
in in
{ {
@ -41,6 +40,16 @@ in
age.secrets.vaultwarden-admin-pwd.file = ../../secrets/vaultwarden-admin-pwd.age; age.secrets.vaultwarden-admin-pwd.file = ../../secrets/vaultwarden-admin-pwd.age;
my.services.postgresql = {
enable = true;
ensures = [
{
username = "vaultwarden";
database = "vaultwarden";
}
];
};
services.vaultwarden = { services.vaultwarden = {
enable = true; enable = true;
dbBackend = "postgresql"; dbBackend = "postgresql";
@ -51,16 +60,23 @@ in
SIGNUPS_ALLOWED = false; SIGNUPS_ALLOWED = false;
WEBSOCKET_ENABLED = true; WEBSOCKET_ENABLED = true;
ROCKET_ADDRESS = "0.0.0.0"; ROCKET_ADDRESS = "0.0.0.0";
ROCKET_PORT = 8222; ROCKET_PORT = rocketPort;
DATABASE_URL = "postgresql:///vaultwarden?host=/run/postgresql";
SMTP_HOST = "smtp.eu.mailgun.org";
SMTP_FROM = "vault@pazpi.top";
SMTP_SECURITY = "starttls";
SMTP_USERNAME = "vault@pazpi.top";
}; };
}; };
networking.firewall.allowedTCPPorts = [ rocketPort ];
}) })
(lib.mkIf cfg.proxy.enable { (lib.mkIf cfg.proxy.enable {
services.caddy = with cfg.proxy; { services.caddy = with cfg.proxy; {
virtualHosts."vault.${domain}".extraConfig = '' virtualHosts."vault.${domain}".extraConfig = ''
reverse_proxy http://${host}:80 reverse_proxy http://${host}:${toString rocketPort}
import cloudflare import cloudflare
''; '';
}; };