Skip to content

Instantly share code, notes, and snippets.

@bradparker
Last active February 26, 2025 06:13
Show Gist options
  • Save bradparker/be611ceae119f5881afbec031389db77 to your computer and use it in GitHub Desktop.
Save bradparker/be611ceae119f5881afbec031389db77 to your computer and use it in GitHub Desktop.
Nix development shell with PostgreSQL management scripts
use flake
export PGDATA=$PWD/database/pgdata
export PGHOST="localhost"
export PGPORT="5432"
export PGDATABASE="my-wonderful-database"
export PGUSER="postgres"
export PGPASSWORD="password"
{
description = "PostgreSQL Data Innards";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
scripts = {
database = rec {
init = pkgs.writeScriptBin "database-init" ''
#!${pkgs.runtimeShell}
set -uo pipefail
mkdir -p $PGDATA
if ! [ -e $PGDATA/postgresql.conf ]; then
pg_ctl -w init
else
echo "Database cluster already initialised."
fi
'';
start = pkgs.writeScriptBin "database-start" ''
#!${pkgs.runtimeShell}
mkdir -p logs
if ! [ -e $PGDATA/postmaster.pid ]; then
pg_ctl -w -l logs/database.log start
else
if ps -p $(head -n 1 $PGDATA/postmaster.pid) > /dev/null; then
echo "Database server already started."
else
echo "Database may have been improperly shut down. Remove $PGDATA/postmaster.pid and try again."
fi
fi
'';
status = pkgs.writeScriptBin "database-status" ''
#!${pkgs.runtimeShell}
set -uo pipefail
if ! [ -e $PGDATA/postmaster.pid ]; then
echo "Database is not running"
else
pid=$(head -n 1 $PGDATA/postmaster.pid)
lsof -p $pid -a -i
fi
'';
stop = pkgs.writeScriptBin "database-stop" ''
#!${pkgs.runtimeShell}
pg_ctl -w stop
'';
create = pkgs.writeScriptBin "database-create" ''
#!${pkgs.runtimeShell}
set -uo pipefail
if psql postgres --command "SELECT 1 FROM pg_database WHERE datname = '$PGDATABASE';" | grep -q 1; then
echo "Database already exists."
else
createdb $PGDATABASE
echo "Database created."
fi
'';
drop = pkgs.writeScriptBin "database-drop" ''
#!${pkgs.runtimeShell}
set -uo pipefail
if psql postgres --command "SELECT 1 FROM pg_database WHERE datname = '$PGDATABASE';" | grep -q 1; then
dropdb $PGDATABASE
echo "Database dropped."
else
echo "Database doesn't exist."
fi
'';
load-schema = pkgs.writeScriptBin "database-load-schema" ''
#!${pkgs.runtimeShell}
SCHEMA_FILE="database/schema.sql"
if [ -e $SCHEMA_FILE ]; then
psql -f $SCHEMA_FILE
else
echo "No schema file ($SCHEMA_FILE) found."
exit 1
fi
'';
setup = pkgs.writeScriptBin "database-setup" ''
#!${pkgs.runtimeShell}
set -o pipefail
${init}/bin/database-init
${start}/bin/database-start
${create}/bin/database-create
'';
reset = pkgs.writeScriptBin "database-reset" ''
#!${pkgs.runtimeShell}
set -o pipefail
${drop}/bin/database-drop
${create}/bin/database-create
'';
};
};
in
{
devShells = {
default = pkgs.mkShell {
packages = with pkgs; [
postgresql
(pkgs.lib.attrValues scripts.database)
];
};
};
}
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment