Skip to content

Instantly share code, notes, and snippets.

@drupol
Created April 2, 2024 12:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drupol/9447f40bfc4d0fe4d8d72f8587153dad to your computer and use it in GitHub Desktop.
Save drupol/9447f40bfc4d0fe4d8d72f8587153dad to your computer and use it in GitHub Desktop.
postgres.nix
{ lib
, dockerTools
, writeText
, writeShellScriptBin
, postgresql
, bash
, coreutils
, nss_wrapper
}:
let
postgresPackage = postgresql;
postgresInitdbArgs = [ "--locale=C" "--encoding=UTF8" ];
postgresPort = 5432;
postgresConf = writeText "postgresql.conf" ''
listen_addresses = '*'
port = ${toString postgresPort}
log_connections = on
log_destination = 'stderr'
log_disconnections = on
log_duration = on
log_statement = 'all'
'';
entrypoint = writeShellScriptBin "entrypoint" ''
set -euo pipefail
mkdir -p $PGDATA
if [ ! -f $PGDATA/PG_VERSION ]; then
# PostgreSQL initdb needs to see PGUSER user (postgres) in the system
# during initdb phase which doesn't exist when running container as
# our host system user. Below is the trick providing this illusion.
uid="$(id -u)"
gid="$(id -g)"
NSS_WRAPPER_PASSWD="$(mktemp)"
NSS_WRAPPER_GROUP="$(mktemp)"
export LD_PRELOAD=${nss_wrapper}/lib/libnss_wrapper.so NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP
printf 'postgres:x:%s:%s:PostgreSQL:%s:/bin/false\n' "$uid" "$gid" "$PGDATA" > "$NSS_WRAPPER_PASSWD"
printf 'postgres:x:%s:\n' "$gid" > "$NSS_WRAPPER_GROUP"
initdb \
--username $PGUSER \
--pgdata $PGDATA \
${lib.concatStringsSep " " postgresInitdbArgs}
cat "${postgresConf}" >> $PGDATA/postgresql.conf
echo "host all all 0.0.0.0/0 trust" >> $PGDATA/pg_hba.conf
# End of PGUSER illusion.
rm -f "$NSS_WRAPPER_PASSWD" "$NSS_WRAPPER_GROUP"
unset LD_PRELOAD NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP
echo -e "\nPostgreSQL init process complete. Ready for start up.\n"
fi
exec ${postgresPackage}/bin/"$@"
'';
in
dockerTools.buildLayeredImage
{
name = "postgresql";
tag = "latest";
contents = [
postgresPackage
entrypoint
bash
coreutils
nss_wrapper
];
extraCommands = ''
mkdir data tmp
chmod 777 data tmp
'';
config = {
Env = [
"PGDATA=/data"
"PGHOST=/data"
"PGUSER=postgres"
"PGPORT=${toString postgresPort}"
];
Entrypoint = [ "${entrypoint}/bin/entrypoint" ];
Cmd = [ "postgres" "-k" "/data" ];
Stopsignal = "SIGINT";
Volumes = {
"/data" = { };
};
ExposedPorts = {
"5432/tcp" = { };
};
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment