Postgres docker configuration

This commit is contained in:
Sam 2024-07-06 20:53:26 +01:00
parent 529fc394ef
commit 947ddaca43
1 changed files with 75 additions and 41 deletions

View File

@ -1,6 +1,72 @@
{ pkgs, lib, inputs, config, ... }:
let
admin_dbPasswordFile = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."software/postgres/admin_db/password".path;
initScript = pkgs.writeText "init.sh" ''
#!/bin/bash
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
# 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
'';
pg_hbaConfig = pkgs.writeText "pg_hba.conf" ''
none
'';
pgsqlConfig = pkgs.writeText "postgresql.conf" ''
listen_addresses = '*'
port = 5432
max_connections = 100
shared_buffers = 24GB
work_mem = 1GB
maintenance_work_mem = 10GB
autovacuum_work_mem = 2GB
dynamic_shared_memory_type = posix
wal_level = minimal
checkpoint_timeout = 60min
checkpoint_completion_target = 0.9
max_wal_size = 10GB
min_wal_size = 80MB
max_wal_senders = 0
random_page_cost = 1.0
effective_cache_size = 25GB
jit = off
log_line_prefix = '%m [%p] %q%u@%d '
log_timezone = 'Etc/UTC'
cluster_name = 'postgres-docker'
datestyle = 'iso, dmy'
timezone = 'Etc/UTC'
default_text_search_config = 'pg_catalog.english'
'';
in
{
sops.secrets = {
@ -12,7 +78,7 @@ in
"db".settings.services."db".service = {
restart = "unless-stopped";
build.context = "/nix/store";
build.dockerfile = builtins.baseNameOf "${pkgs.writeScript "pgDockerfile" ''
build.dockerfile = builtins.baseNameOf "${pkgs.writeText "pgDockerfile" ''
FROM postgres:16
# install packages
RUN apt-get update \
@ -21,6 +87,7 @@ in
jq \
&& rm -rf /var/lib/apt/lists/*
''}";
command = [ "postgres" "-c" "config_file=/etc/postgresql/postgresql.conf" ];
environment = {
POSTGRES_PASSWORD_FILE = admin_dbPasswordFile;
POSTGRES_USER = "admin";
@ -48,59 +115,26 @@ in
"user": "dbt",
"extensions": []
}
"test": {
"user": "test",
"extensions": [hstore]
}
}
]
'';
};
ports = [ "5432:5432" ];
volumes = [
# Mount pgdata to external zfs volume
"/mnt/postgres:/var/lib/postgresql/data"
# Mount config files
# "${pg_hbaConfig}:/var/lib/postgres/data/pgdata/pg_hba.conf"
"${pgsqlConfig}:/etc/postgresql/postgresql.conf"
# 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
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
# 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"
"${initScript}:/docker-entrypoint-initdb.d/init.sh"
];
};
};