{ config, pkgs, lib, ... }: let # Import nodes nodes = import ./../../nodes.nix; myName = config.hostName; myNode = nodes."${myName}"; # And mapping mapping = import ./../../mapping.nix; cfg = config.services.postgresql; masterNode = nodes.${mapping.db.master}; masterIP = "172.19.${toString masterNode.zone}.${toString masterNode.id}"; in { services.postgresql = { enable = true; # Force postgres package major version # to avoid any unwanted upgrades package = pkgs.postgresql_17; identMap = '' # ArbitraryMapName systemUser DBUser superuser_map root postgres superuser_map postgres postgres ''; # Replication tasks are not authenticated # The wireguard mesh cryptographically # ensures the sender is who we expect. authentication = lib.mkForce (builtins.concatStringsSep "\n" (['' #type database DBuser auth-method optional_ident_map local all all peer map=superuser_map ''] ++ lib.optionals (myName == mapping.db.master) (map (slaveName: let slaveNode = nodes.${slaveName}; in "host replication replication 172.19.${toString slaveNode.zone}.${toString slaveNode.id}/32 trust" ) mapping.db.slaves) ++ lib.optionals (builtins.elem myName mapping.db.slaves) [ "host replication replication ${masterIP}/32 trust" ])); ensureUsers = lib.mkIf (myName == mapping.db.master) [{ name = "replication"; ensureClauses.replication = true; }]; settings = { listen_addresses = lib.mkForce "localhost,172.19.${toString myNode.zone}.${toString myNode.id}"; port = 5432; log_connections = true; log_statement = "none"; logging_collector = true; log_disconnections = true; max_wal_senders = 16; wal_level = "logical"; } // lib.optionalAttrs (myName == mapping.db.master) { wal_sender_timeout = "60s"; wal_keep_size = 1000; # In MB } // lib.optionalAttrs (builtins.elem myName mapping.db.slaves) { wal_receiver_timeout = "60s"; hot_standby = "on"; primary_conninfo = "host=${masterIP} port=5432 user=replication"; }; }; # This preStart script sync the slaves to the master # systemd.services..preStart has a mergeable type, # this code will be prepend to the default one systemd.services.postgresql.preStart = lib.mkIf (builtins.elem myName mapping.db.slaves) (lib.mkBefore '' if ! test -e ${cfg.dataDir}/PG_VERSION; then echo "Setting up PostgreSQL slave replication..." # Perform base backup from master echo "Starting base backup from master: ${masterIP}" ${cfg.package}/bin/pg_basebackup \ -h "${masterIP}" \ -U replication \ -p ${toString cfg.settings.port} \ -D "${cfg.dataDir}" \ -P \ -Xs \ -R echo "PostgreSQL slave setup completed successfully" else echo "PostgreSQL standby already configured (standby.signal exists), skipping base backup" fi ''); }