Compare commits

...

1 Commits

Author SHA1 Message Date
Sam 7367f73216 always init pg database script in entrypoint 2024-07-06 17:14:44 +01:00
1 changed files with 90 additions and 36 deletions

View File

@ -1,71 +1,52 @@
{ pkgs, lib, inputs, config, ... }: { pkgs, lib, inputs, config, ... }:
let let
admin_dbPasswordFile = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."software/postgres/admin_db/password".path; admin_dbPasswordFile = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."software/postgres/admin_db/password".path;
in customEntryPointScript = pkgs.writeScript "custom-entrypoint.sh" ''
{ #!/usr/bin/env bash
sops.secrets = { ## copied from: https://github.com/docker-library/postgres/pull/496#issue-358838955
"software/postgres/admin_db/password" = { }; set -Eeo pipefail
};
virtualisation.arion = { echo "🐘 custom-entry-point"
backend = "docker"; # Example using the functions of the postgres entrypoint to customize startup to always run files in /always-initdb.d/
projects = {
"db".settings.services."db".service = { source "$(which docker-entrypoint.sh)"
restart = "unless-stopped";
build.context = "/nix/store"; docker_setup_env
build.dockerfile = builtins.baseNameOf "${pkgs.writeScript "pgDockerfile" '' docker_create_db_directories
FROM postgres:16 # assumption: we are already running as the owner of PGDATA
# install packages
RUN apt-get update \ # This is needed if the container is started as `root`
&& apt-get install -y --no-install-recommends \ #if [ "$1" = 'postgres' ] && [ "$(id -u)" = '0' ]; then
postgresql-16-postgis \ if [ "$(id -u)" = '0' ]; then
jq \ exec gosu postgres "$BASH_SOURCE" "$@"
&& rm -rf /var/lib/apt/lists/* fi
''}";
environment = {
POSTGRES_PASSWORD_FILE = admin_dbPasswordFile; if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
POSTGRES_USER = "admin"; echo "🐘 db is missing"
POSTGRES_DB = "admin_db"; docker_verify_minimum_env
PGDATA = "/var/lib/postgresql/data/pgdata"; docker_init_database_dir
POSTGRES_MULTIPLE_DATABASES = '' pg_setup_hba_conf
[
{ # only required for '--auth[-local]=md5' on POSTGRES_INITDB_ARGS
"osm": { export PGPASSWORD="''${PGPASSWORD:-$POSTGRES_PASSWORD}"
"user": "gis",
"extensions": [ docker_temp_server_start "$@" -c max_locks_per_transaction=256
"hstore", docker_setup_db
"postgis" docker_process_init_files /docker-entrypoint-initdb.d/*
] docker_temp_server_stop
}, else
"bitcoin": { echo "🐘 db already exists"
"user": "satoshi", docker_temp_server_start "$@"
"extensions": [] docker_process_init_files /always-initdb.d/*
}, docker_temp_server_stop
"btc_models": { fi
"user": "dbt",
"extensions": [] echo "🐘 .. starting!"
}, exec postgres "$@"
"dev_btc_models": {
"user": "dbt",
"extensions": []
}
"test": {
"user": "test",
"extensions": [hstore]
}
}
]
''; '';
};
ports = [ "5432:5432" ];
volumes = [
"/mnt/postgres:/var/lib/postgresql/data"
# Need to mount secret file initScript = pkgs.writeScript "init.sh" ''
"${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 #!/bin/bash
function create_user_and_database() { function create_user_and_database() {
local database=$1 local database=$1
@ -100,7 +81,80 @@ in
create_user_and_database "$db_name" "$user" "$extensions" create_user_and_database "$db_name" "$user" "$extensions"
done done
fi fi
''}:/docker-entrypoint-initdb.d/init.sh" '';
in
{
sops.secrets = {
"software/postgres/admin_db/password" = { };
};
virtualisation.arion = {
backend = "docker";
projects = {
"db".settings.services."db".service = {
restart = "unless-stopped";
build.context = "/nix/store";
build.dockerfile = builtins.baseNameOf "${pkgs.writeScript "pgDockerfile" ''
FROM postgres:16
# install packages
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
postgresql-16-postgis \
jq \
&& rm -rf /var/lib/apt/lists/*
RUN mkdir -p /scripts/ /always-initdb.d/
COPY ${builtins.baseNameOf customEntryPointScript} /scripts/custom-entrypoint.sh
RUN chmod -R a+x /scripts
ENTRYPOINT /scripts/custom-entrypoint.sh
''}";
environment = {
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"
# 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.
"${initScript}:/always-initdb.d/init.sh"
]; ];
}; };
}; };