55 lines
2.1 KiB
Bash
55 lines
2.1 KiB
Bash
#!/usr/bin/env bash
|
|||
|
|
# Runs once, when the postgres container starts on an empty pgdata volume.
|
||
|
|
# Creates the two login roles and the packetstation database.
|
||
|
|
# ps_migrate owns the database and its schema. Migrations run as this role.
|
||
|
|
# ps_app may connect. Table grants come from the migrations (0001).
|
||
|
|
# Passwords are read from the compose secret files, never from the environment or argv.
|
||
|
|
# The official image may source this file instead of executing it, so the body runs in a
|
||
|
|
# subshell and leaves the image's own shell options alone.
|
||
|
|
|
||
|
|
ps_create_roles() (
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
for name in postgres_migrate_password postgres_app_password; do
|
||
|
|
f="/run/secrets/$name"
|
||
|
|
if [[ ! -r "$f" ]]; then
|
||
|
|
echo "01-roles: secret $name is missing or unreadable" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
if [[ ! -s "$f" ]]; then
|
||
|
|
echo "01-roles: secret $name is empty" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
if [[ "$(wc -l < "$f")" -gt 1 ]] || grep -q $'\r' "$f"; then
|
||
|
|
echo "01-roles: secret $name must be one line with no carriage return" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
|
||
|
|
# psql reads the passwords itself through backtick \set, so they never appear on a
|
||
|
|
# command line. :'name' quotes each value as a SQL literal.
|
||
|
|
psql -v ON_ERROR_STOP=1 --no-psqlrc --username "${POSTGRES_USER:-postgres}" --dbname postgres <<'SQL'
|
||
|
|
\set migrate_pw `cat /run/secrets/postgres_migrate_password`
|
||
|
|
\set app_pw `cat /run/secrets/postgres_app_password`
|
||
|
|
|
||
|
|
CREATE ROLE ps_migrate LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION PASSWORD :'migrate_pw';
|
||
|
|
CREATE ROLE ps_app LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION PASSWORD :'app_pw';
|
||
|
|
\unset migrate_pw
|
||
|
|
\unset app_pw
|
||
|
|
|
||
|
|
CREATE DATABASE packetstation OWNER ps_migrate ENCODING 'UTF8' TEMPLATE template0;
|
||
|
|
REVOKE ALL ON DATABASE packetstation FROM PUBLIC;
|
||
|
|
GRANT CONNECT ON DATABASE packetstation TO ps_app;
|
||
|
|
|
||
|
|
\connect packetstation
|
||
|
|
-- PostgreSQL 15+ already denies CREATE on public to PUBLIC. Make it explicit and give
|
||
|
|
-- the schema to the migrate role.
|
||
|
|
REVOKE ALL ON SCHEMA public FROM PUBLIC;
|
||
|
|
ALTER SCHEMA public OWNER TO ps_migrate;
|
||
|
|
SQL
|
||
|
|
|
||
|
|
echo "01-roles: created ps_migrate, ps_app and database packetstation"
|
||
|
|
)
|
||
|
|
|
||
|
|
ps_create_roles
|