Files

157 lines
4.7 KiB
Nix

{
config,
lib,
pkgs,
...
}: let
txPort = config.m3ta.ports.get "pgbouncer-tx";
sessionPort = config.m3ta.ports.get "pgbouncer-session";
pgPort = config.m3ta.ports.get "postgres";
# Podman-Bridge-IP des Hosts
hostBridgeIP = "10.89.0.1";
# pgbouncer (1.24+ als auch 1.25.2) lädt bei JEDEM TLS-Setup eine CA — auch
# bei sslmode=prefer/require ohne Verifikation. Ohne explizite Datei fällt
# es auf die OpenSSL-Default-Verify-Paths zurück, die hier fehlschlagen:
# "TLS setup failed: failed to load CA: (null)" → Startabbruch.
# Explizites Bundle umgeht das (verifiziert 2026-08-20 gegen 1.24.1 + 1.25.2).
caBundle = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
commonSettings = {
listen_addr = "127.0.0.1,${hostBridgeIP}";
auth_type = "scram-sha-256";
auth_file = config.age.secrets.pgbouncer-userlist.path;
admin_users = "sascha_koenig";
stats_users = "sascha_koenig";
log_connections = 1;
log_disconnections = 1;
client_tls_sslmode = "prefer";
client_tls_cert_file = config.age.secrets.pgbouncer-tls-cert.path;
client_tls_key_file = config.age.secrets.pgbouncer-tls-key.path;
client_tls_protocols = "secure";
client_tls_ca_file = caBundle;
server_reset_query = "DISCARD ALL";
server_check_query = "SELECT 1";
server_check_delay = 30;
server_tls_sslmode = "prefer";
server_tls_protocols = "secure";
server_tls_ca_file = caBundle;
};
mkDatabases = dbs:
lib.listToAttrs (map (db:
lib.nameValuePair db "host=127.0.0.1 port=${toString pgPort} dbname=${db}")
dbs);
in {
services.pgbouncer = {
enable = true;
settings = {
pgbouncer =
commonSettings
// {
listen_port = txPort;
pool_mode = "transaction";
max_client_conn = 1000;
default_pool_size = 10;
min_pool_size = 2;
reserve_pool_size = 3;
reserve_pool_timeout = 3;
max_prepared_statements = 200;
};
databases = mkDatabases [
"baserow"
"litellm"
"librechat_rag"
"librechat_rag_dev"
"metabase"
"az_kpi_raw"
];
};
};
systemd.services.pgbouncer = {
after = ["postgresql.service"];
requires = ["postgresql.service"];
};
environment.etc."pgbouncer/pgbouncer-session.ini".text = let
dbLines =
lib.concatStringsSep "\n"
(lib.mapAttrsToList (name: conn: "${name} = ${conn}")
(mkDatabases [
"outline"
"zammad"
"zammad_hr"
"vaultwarden"
"dash"
]));
in ''
[databases]
${dbLines}
[pgbouncer]
listen_addr = ${commonSettings.listen_addr}
listen_port = ${toString sessionPort}
pool_mode = session
auth_type = ${commonSettings.auth_type}
auth_file = ${config.age.secrets.pgbouncer-userlist.path}
admin_users = ${commonSettings.admin_users}
stats_users = ${commonSettings.stats_users}
client_tls_sslmode = ${commonSettings.client_tls_sslmode}
client_tls_cert_file = ${commonSettings.client_tls_cert_file}
client_tls_key_file = ${commonSettings.client_tls_key_file}
client_tls_protocols = ${commonSettings.client_tls_protocols}
client_tls_ca_file = ${commonSettings.client_tls_ca_file}
max_client_conn = 300
default_pool_size = 30
min_pool_size = 1
query_wait_timeout = 30
log_connections = 1
log_disconnections = 1
server_reset_query = DISCARD ALL
server_check_query = SELECT 1
server_check_delay = 30
server_tls_sslmode = ${commonSettings.server_tls_sslmode}
server_tls_protocols = ${commonSettings.server_tls_protocols}
server_tls_ca_file = ${commonSettings.server_tls_ca_file}
# PID/Socket getrennt von der Haupt-Instanz halten.
pidfile = /run/pgbouncer-session/pgbouncer.pid
unix_socket_dir = /run/pgbouncer-session
'';
systemd.services.pgbouncer-session = {
description = "PgBouncer (session pool) for prepared-statement apps";
after = ["postgresql.service"];
requires = ["postgresql.service"];
wantedBy = ["multi-user.target"];
serviceConfig = {
User = "pgbouncer";
Group = "pgbouncer";
RuntimeDirectory = "pgbouncer-session";
ExecStart = "${pkgs.pgbouncer}/bin/pgbouncer /etc/pgbouncer/pgbouncer-session.ini";
Restart = "on-failure";
RestartSec = 5;
};
};
networking.firewall.extraCommands = ''
iptables -A INPUT -p tcp -s 127.0.0.1 --dport ${toString txPort} -j ACCEPT
iptables -A INPUT -p tcp -s 10.89.0.0/24 --dport ${toString txPort} -j ACCEPT
iptables -A INPUT -p tcp -s 127.0.0.1 --dport ${toString sessionPort} -j ACCEPT
iptables -A INPUT -p tcp -s 10.89.0.0/24 --dport ${toString sessionPort} -j ACCEPT
'';
}