fix nix develop psql setup

This commit is contained in:
Jonas Rabenstein 2026-08-12 13:31:44 +02:00
commit 53329182bd

236
flake.nix
View file

@ -7,12 +7,20 @@
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { nixpkgs, rust-overlay, flake-utils, ... }:
outputs = {
nixpkgs,
rust-overlay,
flake-utils,
...
}:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ (import rust-overlay) ];
overlays = [
rust-overlay.overlays.default
];
};
rust = pkgs.rust-bin.stable.latest.default.override {
@ -21,104 +29,236 @@
"clippy"
];
};
in {
in
{
devShells.default = pkgs.mkShell {
packages = with pkgs; [
rust
# Database
postgresql
postgis
postgresqlPackages.postgis
sqlx-cli
# GIS
gdal
geos
proj
# Build dependencies
pkg-config
openssl
];
shellHook = ''
set -e
# ------------------------------------------------------------
# Local PostgreSQL
# ------------------------------------------------------------
export PGDATA="$PWD/.pgdata"
export PGHOST="$PWD/.pgsocket"
export PGPORT="5433"
export PGDATABASE="county_sprints"
export PGUSER="county_sprints"
mkdir -p "$PGHOST"
# ------------------------------------------------------------
# Initialise PostgreSQL cluster
# ------------------------------------------------------------
if [ ! -f "$PGDATA/PG_VERSION" ]; then
echo "initialising PostgreSQL..."
echo
echo "==> Initialising local PostgreSQL cluster"
initdb \
--auth=trust \
--no-locale \
"$PGDATA" >/dev/null
cat >> "$PGDATA/postgresql.conf" <<PGEOF
listen_addresses = ''
port = 5433
unix_socket_directories = '$PGHOST'
PGEOF
--encoding=UTF8 \
"$PGDATA" \
>/dev/null
fi
if ! pg_ctl -D "$PGDATA" status >/dev/null 2>&1; then
# ------------------------------------------------------------
# Configure PostgreSQL
# ------------------------------------------------------------
# Always write our development settings. This means changing
# the flake also updates an already existing local cluster.
cat > "$PGDATA/postgresql.conf" <<EOF
listen_addresses = '' + "''" + ''
port = 5433
unix_socket_directories = '$PGHOST'
EOF
# ------------------------------------------------------------
# Start PostgreSQL
# ------------------------------------------------------------
if ! pg_ctl \
-D "$PGDATA" \
status \
>/dev/null 2>&1
then
echo
echo "==> Starting local PostgreSQL"
pg_ctl \
-D "$PGDATA" \
-o "-k $PGHOST -p $PGPORT" \
-l "$PGDATA/postgresql.log" \
start >/dev/null
start \
>/dev/null
# Wait until PostgreSQL actually accepts connections.
for i in $(seq 1 30); do
if pg_isready \
-h "$PGHOST" \
-p "$PGPORT" \
>/dev/null 2>&1
then
break
fi
sleep 0.2
done
fi
# ------------------------------------------------------------
# Create application role
# ------------------------------------------------------------
if ! psql \
-h "$PGHOST" \
-p "$PGPORT" \
-d postgres \
-tAc "SELECT 1 FROM pg_roles WHERE rolname='$PGUSER'" |
-tAc \
"SELECT 1
FROM pg_roles
WHERE rolname = '$PGUSER'" |
grep -q 1
then
createuser \
-h "$PGHOST" \
-p "$PGPORT" \
"$PGUSER"
fi
echo
echo "==> Creating PostgreSQL role '$PGUSER'"
if ! psql \
-h "$PGHOST" \
-p "$PGPORT" \
-d postgres \
-tAc "SELECT 1 FROM pg_database WHERE datname='$PGDATABASE'" |
grep -q 1
then
createdb \
-h "$PGHOST" \
-p "$PGPORT" \
-O "$PGUSER" \
"$PGDATABASE"
fi
if ! psql \
-h "$PGHOST" \
-p "$PGPORT" \
-d "$PGDATABASE" \
-tAc "SELECT 1 FROM pg_extension WHERE extname='postgis'" |
grep -q 1
then
psql \
-h "$PGHOST" \
-p "$PGPORT" \
-d "$PGDATABASE" \
-c "CREATE EXTENSION postgis;" >/dev/null
-d postgres \
-v ON_ERROR_STOP=1 \
-c \
"CREATE ROLE \"$PGUSER\" LOGIN;"
fi
# ------------------------------------------------------------
# Create application database
# ------------------------------------------------------------
if ! psql \
-h "$PGHOST" \
-p "$PGPORT" \
-d postgres \
-tAc \
"SELECT 1
FROM pg_database
WHERE datname = '$PGDATABASE'" |
grep -q 1
then
echo
echo "==> Creating PostgreSQL database '$PGDATABASE'"
psql \
-h "$PGHOST" \
-p "$PGPORT" \
-d postgres \
-v ON_ERROR_STOP=1 \
-c \
"CREATE DATABASE \"$PGDATABASE\" OWNER \"$PGUSER\";"
fi
# ------------------------------------------------------------
# Make sure the application role owns the database
# ------------------------------------------------------------
psql \
-h "$PGHOST" \
-p "$PGPORT" \
-d postgres \
-v ON_ERROR_STOP=1 \
-c \
"ALTER DATABASE \"$PGDATABASE\" OWNER TO \"$PGUSER\";" \
>/dev/null
# ------------------------------------------------------------
# PostGIS
# ------------------------------------------------------------
echo
echo "==> Checking PostGIS"
psql \
-h "$PGHOST" \
-p "$PGPORT" \
-d "$PGDATABASE" \
-v ON_ERROR_STOP=1 \
-c \
"CREATE EXTENSION IF NOT EXISTS postgis;" \
>/dev/null
# ------------------------------------------------------------
# DATABASE_URL for sqlx / application
# ------------------------------------------------------------
export DATABASE_URL="postgresql://$PGUSER@/$PGDATABASE?host=$PGHOST&port=$PGPORT"
# ------------------------------------------------------------
# Environment
# ------------------------------------------------------------
export RUST_BACKTRACE=1
if [ -z "''${RUST_LOG:-}" ]; then
export RUST_LOG="info"
fi
# ------------------------------------------------------------
# Info
# ------------------------------------------------------------
echo
echo "========================================"
echo " county-sprints development environment"
echo "========================================"
echo "DATABASE_URL=$DATABASE_URL"
echo "=============================================="
echo " Landkreis-Sprints development environment"
echo "=============================================="
echo
echo "Rust:"
rustc --version
echo
echo "PostgreSQL:"
psql \
-h "$PGHOST" \
-p "$PGPORT" \
-d "$PGDATABASE" \
-tAc "SELECT version();" |
sed 's/^/ /'
echo
echo "PostGIS:"
psql \
-h "$PGHOST" \
-p "$PGPORT" \
-d "$PGDATABASE" \
-tAc "SELECT PostGIS_Full_Version();" |
sed 's/^/ /'
echo
echo "DATABASE_URL:"
echo " $DATABASE_URL"
echo
echo "Run:"
echo " sqlx migrate run"
echo " cargo test"
echo " cargo run"
echo
'';
};