feat: add TimescaleDB to nix dev shell

- Use postgresql_16.withPackages to include timescaledb extension
- Add shared_preload_libraries to PostgreSQL config
- Enable TimescaleDB for both dev and test databases
- Disable TimescaleDB telemetry in dev
This commit is contained in:
Graham McIntire 2026-02-14 10:20:11 -06:00
parent e9e1a29684
commit 6fd643a380

View file

@ -26,6 +26,9 @@
}: }:
let let
# PostgreSQL with TimescaleDB extension
pg = postgresql_16.withPackages (ps: [ ps.timescaledb ]);
# PostgreSQL data directory (local to project) # PostgreSQL data directory (local to project)
pgDataDir = ".nix-postgres"; pgDataDir = ".nix-postgres";
pgPort = "5432"; pgPort = "5432";
@ -53,7 +56,7 @@ let
# Initialize PostgreSQL if needed # Initialize PostgreSQL if needed
if [ ! -d "${pgDataDir}" ]; then if [ ! -d "${pgDataDir}" ]; then
echo "📦 Initializing PostgreSQL database..." echo "📦 Initializing PostgreSQL database..."
${postgresql_16}/bin/initdb -D ${pgDataDir} -U $USER --encoding=UTF8 --locale=en_US.UTF-8 ${pg}/bin/initdb -D ${pgDataDir} -U $USER --encoding=UTF8 --locale=en_US.UTF-8
# Configure PostgreSQL # Configure PostgreSQL
cat >> ${pgDataDir}/postgresql.conf << EOF cat >> ${pgDataDir}/postgresql.conf << EOF
@ -63,20 +66,23 @@ let
fsync = off # Faster for development (DO NOT use in production) fsync = off # Faster for development (DO NOT use in production)
synchronous_commit = off synchronous_commit = off
full_page_writes = off full_page_writes = off
# TimescaleDB
shared_preload_libraries = 'timescaledb'
timescaledb.telemetry_level = off
EOF EOF
fi fi
# Check if PostgreSQL is already running on this port # Check if PostgreSQL is already running on this port
if ${postgresql_16}/bin/pg_isready -h ${pgHost} -p ${pgPort} > /dev/null 2>&1; then if ${pg}/bin/pg_isready -h ${pgHost} -p ${pgPort} > /dev/null 2>&1; then
echo " PostgreSQL already running on port ${pgPort}" echo " PostgreSQL already running on port ${pgPort}"
else else
# Start PostgreSQL # Start PostgreSQL
echo "🐘 Starting PostgreSQL on port ${pgPort}..." echo "🐘 Starting PostgreSQL on port ${pgPort}..."
${postgresql_16}/bin/pg_ctl -D ${pgDataDir} -l ${pgDataDir}/logfile -o "-p ${pgPort}" start ${pg}/bin/pg_ctl -D ${pgDataDir} -l ${pgDataDir}/logfile -o "-p ${pgPort}" start
# Wait for PostgreSQL to be ready # Wait for PostgreSQL to be ready
for i in {1..30}; do for i in {1..30}; do
if ${postgresql_16}/bin/pg_isready -h ${pgHost} -p ${pgPort} > /dev/null 2>&1; then if ${pg}/bin/pg_isready -h ${pgHost} -p ${pgPort} > /dev/null 2>&1; then
break break
fi fi
if [ $i -eq 30 ]; then if [ $i -eq 30 ]; then
@ -90,22 +96,24 @@ let
fi fi
# Create postgres role if it doesn't exist (needed by some tools) # Create postgres role if it doesn't exist (needed by some tools)
${postgresql_16}/bin/psql -h ${pgHost} -p ${pgPort} -U $USER -d postgres -tc \ ${pg}/bin/psql -h ${pgHost} -p ${pgPort} -U $USER -d postgres -tc \
"SELECT 1 FROM pg_roles WHERE rolname='postgres'" | grep -q 1 || \ "SELECT 1 FROM pg_roles WHERE rolname='postgres'" | grep -q 1 || \
${postgresql_16}/bin/psql -h ${pgHost} -p ${pgPort} -U $USER -d postgres -c \ ${pg}/bin/psql -h ${pgHost} -p ${pgPort} -U $USER -d postgres -c \
"CREATE ROLE postgres WITH SUPERUSER LOGIN;" "CREATE ROLE postgres WITH SUPERUSER LOGIN;"
# Create development and test databases # Create development and test databases
for db in towerops_dev towerops_test; do for db in towerops_dev towerops_test; do
${postgresql_16}/bin/psql -h ${pgHost} -p ${pgPort} -U $USER -d postgres -tc \ ${pg}/bin/psql -h ${pgHost} -p ${pgPort} -U $USER -d postgres -tc \
"SELECT 1 FROM pg_database WHERE datname='$db'" | grep -q 1 || \ "SELECT 1 FROM pg_database WHERE datname='$db'" | grep -q 1 || \
${postgresql_16}/bin/createdb -h ${pgHost} -p ${pgPort} -U $USER $db ${pg}/bin/createdb -h ${pgHost} -p ${pgPort} -U $USER $db
done done
# Enable TimescaleDB extension (dev database only, test uses plain PostgreSQL) # Enable TimescaleDB extension for dev and test databases
${postgresql_16}/bin/psql -h ${pgHost} -p ${pgPort} -U $USER -d towerops_dev -c \ for db in towerops_dev towerops_test; do
"CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;" 2>/dev/null || \ ${pg}/bin/psql -h ${pgHost} -p ${pgPort} -U $USER -d $db -c \
echo " TimescaleDB not available (optional for development)" "CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;" 2>/dev/null || \
echo " TimescaleDB not available for $db (optional)"
done
echo " PostgreSQL started successfully" echo " PostgreSQL started successfully"
@ -155,7 +163,7 @@ let
# Stop PostgreSQL # Stop PostgreSQL
if [ -d "${pgDataDir}" ]; then if [ -d "${pgDataDir}" ]; then
${postgresql_16}/bin/pg_ctl -D ${pgDataDir} stop -m fast 2>/dev/null || true ${pg}/bin/pg_ctl -D ${pgDataDir} stop -m fast 2>/dev/null || true
echo " PostgreSQL stopped" echo " PostgreSQL stopped"
fi fi
@ -211,8 +219,8 @@ mkShell {
# Elixir/Erlang # Elixir/Erlang
elixir elixir
# Databases # Databases (PostgreSQL with TimescaleDB)
postgresql_16 pg
redis redis
# SNMP tools # SNMP tools