Skip to content

Commit 1e5255c

Browse files
committed
feat: add initialScript option to postgres module
Add an initialScript option to the postgres module that allows users to specify a SQL script to be executed on the first startup of the PostgreSQL service. This is useful for setting up initial users, roles, or databases.
1 parent 7d578f0 commit 1e5255c

File tree

3 files changed

+77
-8
lines changed

3 files changed

+77
-8
lines changed

nix/systemConfigs.nix

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,20 @@
22
let
33
mkModules = system: [
44
self.systemModules.postgres
5-
({
6-
services.nginx.enable = true;
7-
nixpkgs.hostPlatform = system;
8-
supabase.services.postgres = {
9-
enable = true;
10-
package = self.packages.${system}."psql_17/bin";
11-
};
12-
})
5+
(
6+
{ pkgs, ... }:
7+
{
8+
services.nginx.enable = true;
9+
nixpkgs.hostPlatform = system;
10+
supabase.services.postgres = {
11+
enable = true;
12+
package = self.packages.${system}."psql_17/bin";
13+
initialScript = pkgs.writeText "init-script.sql" ''
14+
CREATE USER supabase_auth_admin NOINHERIT CREATEROLE LOGIN NOREPLICATION PASSWORD 'secret';
15+
'';
16+
};
17+
}
18+
)
1319
];
1420

1521
systems = [

nix/systemModules/postgres/default.nix

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,19 @@ in
183183
initialisation.
184184
'';
185185
};
186+
187+
initialScript = lib.mkOption {
188+
type = lib.types.nullOr lib.types.path;
189+
default = null;
190+
example = lib.literalExpression ''
191+
pkgs.writeText "init-sql-script" '''
192+
alter user postgres with password 'myPassword';
193+
''';'';
194+
195+
description = ''
196+
A file containing SQL statements to execute on first startup.
197+
'';
198+
};
186199
};
187200
};
188201

@@ -376,6 +389,45 @@ in
376389
];
377390
};
378391
};
392+
postgresql-setup = {
393+
description = "PostgreSQL Setup Scripts";
394+
395+
requires = [ "postgresql.service" ];
396+
after = [ "postgresql.service" ];
397+
398+
serviceConfig = {
399+
User = "postgres";
400+
Group = "postgres";
401+
Type = "oneshot";
402+
RemainAfterExit = true;
403+
};
404+
405+
path = [ cfg.package ];
406+
environment.PGPORT = builtins.toString cfg.settings.port;
407+
408+
# Wait for PostgreSQL to be ready to accept connections.
409+
script = ''
410+
check-connection() {
411+
psql -U ${cfg.superUser} -h localhost -d postgres -v ON_ERROR_STOP=1 <<-' EOF'
412+
SELECT pg_is_in_recovery() \gset
413+
\if :pg_is_in_recovery
414+
\i still-recovering
415+
\endif
416+
EOF
417+
}
418+
while ! check-connection 2> /dev/null; do
419+
if ! systemctl is-active --quiet postgresql.service; then exit 1; fi
420+
sleep 0.1
421+
done
422+
423+
if test -e "${cfg.dataDir}/.first_startup"; then
424+
${lib.optionalString (cfg.initialScript != null) ''
425+
psql -U ${cfg.superUser} -h localhost -f "${cfg.initialScript}" -d postgres
426+
''}
427+
rm -f "${cfg.dataDir}/.first_startup"
428+
fi
429+
'';
430+
};
379431
"setup-locales" = {
380432
description = "Setup locales on the system";
381433

nix/systemModules/tests/test_postgres.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,14 @@ def test_postgres_service_running(host):
197197
logs = host.run("journalctl -u postgresql.service --no-pager").stdout
198198
for log in required_logs:
199199
assert log in logs, f"Log '{log}' should be present in PostgreSQL logs"
200+
201+
202+
def test_postgres_setup_service_running(host):
203+
assert host.service("postgresql-setup.service").is_valid
204+
assert host.service("postgresql-setup.service").is_running, (
205+
"postgresql-setup service should be running but failed: {}".format(
206+
host.run(
207+
"systemctl status postgresql-setup.service; journalctl -n 100 -u postgresql-setup.service"
208+
).stdout
209+
)
210+
)

0 commit comments

Comments
 (0)