{ config, lib, pkgs, ... }: let cfg = config.services.gebos.postgres; in { options.services.gebos.postgres = { enable = lib.mkEnableOption "Gebos Postgres 17 + TimescaleDB"; listenAddresses = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ "127.0.0.1" ]; }; }; config = lib.mkIf cfg.enable { # TimescaleDB ships under the non-OSI "Timescale License" (TSL), which # nixpkgs flags as unfree. Allow just this package rather than opening the # whole config to unfree. nixpkgs.config.allowUnfreePredicate = pkg: lib.elem (lib.getName pkg) [ "timescaledb" ]; services.postgresql = { enable = true; package = pkgs.postgresql_17; # listen_addresses is managed explicitly below. The upstream postgresql # module also defines it (via its own default / enableTCPIP), so mkForce # makes this module the single source of truth and avoids the collision. settings = { listen_addresses = lib.mkForce (lib.concatStringsSep "," cfg.listenAddresses); shared_preload_libraries = "timescaledb,pg_stat_statements"; }; extensions = ps: with ps; [ timescaledb pgjwt pg_graphql pgsodium # supabase_vault — TODO: package or vendor ]; # Init script creates Supabase's `auth`, `storage`, `_analytics`, `_supavisor` # schemas, the gebos_ingest role (BYPASSRLS), and telemetry hypertables. initialScript = ../supabase/init.sql; }; }; }