From 2f0ddf8375db2b487d27ecaa474825de69f8198c Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 6 Jul 2024 16:02:10 +0100 Subject: [PATCH] Modify postgres docker container - add sops-secrets for admin pwd - POSTGRES_MULTIPLE_DATABASES as json to specify users and extensions - initdb docker entrypoint script to create dbs, users and extensions from json --- hosts/common/optional/docker/postgres.nix | 103 ++++++++++++++++------ 1 file changed, 75 insertions(+), 28 deletions(-) diff --git a/hosts/common/optional/docker/postgres.nix b/hosts/common/optional/docker/postgres.nix index 7ccc75f..c5d7c3e 100644 --- a/hosts/common/optional/docker/postgres.nix +++ b/hosts/common/optional/docker/postgres.nix @@ -1,5 +1,11 @@ -{ pkgs, ... }: +{ pkgs, lib, inputs, config, ... }: +let + admin_dbPasswordFile = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."software/postgres/admin_db/password".path; +in { + sops.secrets = { + "software/postgres/admin_db/password" = { }; + }; virtualisation.arion = { backend = "docker"; projects = { @@ -12,51 +18,92 @@ RUN apt-get update \ && apt-get install -y --no-install-recommends \ postgresql-16-postgis \ + jq \ && rm -rf /var/lib/apt/lists/* ''}"; environment = { - POSTGRES_PASSWORD = "balls1234"; + POSTGRES_PASSWORD_FILE = admin_dbPasswordFile; POSTGRES_USER = "admin"; POSTGRES_DB = "admin_db"; PGDATA = "/var/lib/postgresql/data/pgdata"; + POSTGRES_MULTIPLE_DATABASES = '' + [ + { + "osm": { + "user": "gis", + "extensions": [ + "hstore", + "postgis" + ] + }, + "bitcoin": { + "user": "satoshi", + "extensions": [] + }, + "btc_models": { + "user": "dbt", + "extensions": [] + }, + "dev_btc_models": { + "user": "dbt", + "extensions": [] + } + "test": { + "user": "test", + "extensions": [hstore] + } + } + ] + ''; }; ports = [ "5432:5432" ]; volumes = [ "/mnt/postgres:/var/lib/postgresql/data" - # PG init script + # Need to mount secret file + "${admin_dbPasswordFile}:${admin_dbPasswordFile}" + + # PG init script to parse json specified in POSTGRES_MULTIPLE_DATABASES + # creates databases, users and installs extensions for each database. "${pkgs.writeScript "init.sh" '' #!/bin/bash - - # Create additional databases - psql -v --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - create database bitcoin; - create database osm; + function create_user_and_database() { + local database=$1 + local user=$2 + local extensions=$3 + echo "### admin user: $POSTGRES_USER ###" + echo " Creating database '$database'" + echo " Creating user '$user'" + psql -v --username "$POSTGRES_USER" -d "$POSTGRES_DB" <<-EOSQL + CREATE USER $user; + CREATE DATABASE $database; + GRANT ALL PRIVILEGES ON DATABASE $database TO $user; EOSQL - - # Create additional users - psql -v --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - create user gis; - create user satoshi; - EOSQL - - # Setup bitcoin db - psql -v --username "$POSTGRES_USER" --dbname "bitcoin" <<-EOSQL - grant all privileges on database bitcoin to satoshi; - EOSQL - - # Setup osm db - psql -v --username "$POSTGRES_USER" --dbname "osm" <<-EOSQL - grant all privileges on database osm to gis; - create extension if not exists postgis; - create extension if not exists hstore; - EOSQL - + + # Loop through extensions and create them + for ext in $(echo "$extensions" | tr ',' ' '); do + echo " - Installing extention $ext" + psql -v --username "$POSTGRES_USER" -d "$database" -c "CREATE EXTENSION $ext;" + done + } + + if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then + + # Parse the JSON string + database_names=$(echo "$POSTGRES_MULTIPLE_DATABASES" | jq -r '.[0] | keys[]') + echo "Multiple database creation requested: $(echo "$database_names" | tr "\n" " ")" + + # Loop through each database and create it + for db_name in $database_names; do + user=$(echo "$POSTGRES_MULTIPLE_DATABASES" | jq -r ".[0] | .''${db_name} | .user") + extensions=$(echo "$POSTGRES_MULTIPLE_DATABASES" | jq -r ".[0] | .''${db_name} | .extensions | join(\",\")") + create_user_and_database "$db_name" "$user" "$extensions" + done + fi ''}:/docker-entrypoint-initdb.d/init.sh" ]; }; }; }; - }