add nix development environment

Provide a direnv-loaded Laravel and future Vue toolchain with isolated worktree ports and a process-compose stack. Use PostgreSQL for local runtime services while retaining in-memory SQLite for PHPUnit.
This commit is contained in:
Yisroel Baum 2026-07-30 22:54:20 +03:00
parent 2d25c28596
commit 83ca2cf43c
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
12 changed files with 345 additions and 13 deletions

127
nix/shell-hook.sh Normal file
View file

@ -0,0 +1,127 @@
#!/usr/bin/env bash
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
GIT_DIR_PATH="$(git rev-parse --git-dir 2>/dev/null)"
GIT_COMMON_PATH="$(git rev-parse --git-common-dir 2>/dev/null)"
# Linked worktrees get their own runtime state and port range.
if [ -n "$GIT_COMMON_PATH" ] \
&& [ "$GIT_DIR_PATH" != "$GIT_COMMON_PATH" ]; then
IS_WORKTREE=1
MAIN_REPO_ROOT="$(cd "$GIT_COMMON_PATH/.." && pwd)"
else
IS_WORKTREE=0
MAIN_REPO_ROOT="$REPO_ROOT"
fi
if [ "$IS_WORKTREE" = 1 ]; then
if [ -n "$PORT_OFFSET" ]; then
OFFSET="$PORT_OFFSET"
else
PORT_HASH="$(printf '%s' "$REPO_ROOT" | cksum | cut -d' ' -f1)"
OFFSET=$(( (PORT_HASH % 49 + 1) * 100 ))
fi
else
OFFSET=0
fi
export CADDY_PORT=$((8000 + OFFSET))
export BACKEND_PORT=$((8001 + OFFSET))
export VITE_PORT=$((5173 + OFFSET))
export MAILPIT_SMTP_PORT=$((2525 + OFFSET))
export MAILPIT_UI_PORT=$((8025 + OFFSET))
export PC_PORT_NUM=$((8080 + OFFSET))
export PGDATA="$REPO_ROOT/.postgres"
export PGHOST="$PGDATA"
export PGUSER="postgres"
export PGDATABASE="postgres"
DEV_APP_URL="https://localhost:$CADDY_PORT"
DEV_DB_CONNECTION="pgsql"
DEV_DB_HOST="$PGHOST"
DEV_DB_PORT="5432"
DEV_DB_DATABASE="$PGDATABASE"
DEV_DB_USERNAME="$PGUSER"
DEV_DB_PASSWORD=""
DEV_MAIL_MAILER="smtp"
DEV_MAIL_HOST="127.0.0.1"
DEV_MAIL_PORT="$MAILPIT_SMTP_PORT"
if [ ! -d "$PGDATA" ]; then
echo "[pg] initializing cluster at $PGDATA"
initdb --auth=trust --username="$PGUSER" --no-locale --encoding=UTF8 >/dev/null
{
echo "listen_addresses = ''"
echo "unix_socket_directories = '$PGDATA'"
} >> "$PGDATA/postgresql.conf"
fi
# Worktrees share host-independent localhost certificates with the main checkout.
MAIN_CERT_ROOT="$MAIN_REPO_ROOT/.cert"
if [ ! -d "$MAIN_CERT_ROOT" ]; then
echo "[cert] installing local CA + generating TLS certs in $MAIN_CERT_ROOT"
mkcert -install
mkdir -p "$MAIN_CERT_ROOT"
mkcert \
-key-file "$MAIN_CERT_ROOT/localhost-key.pem" \
-cert-file "$MAIN_CERT_ROOT/localhost.pem" \
localhost 127.0.0.1 ::1
fi
if [ "$IS_WORKTREE" = 1 ] \
&& [ ! -e "$REPO_ROOT/.cert" ] \
&& [ ! -L "$REPO_ROOT/.cert" ]; then
ln -s "$MAIN_CERT_ROOT" "$REPO_ROOT/.cert"
fi
ENV_FILE="$REPO_ROOT/backend/.env"
if [ ! -f "$ENV_FILE" ]; then
if [ "$IS_WORKTREE" = 1 ] && [ -f "$MAIN_REPO_ROOT/backend/.env" ]; then
cp "$MAIN_REPO_ROOT/backend/.env" "$ENV_FILE"
else
cp "$REPO_ROOT/backend/.env.example" "$ENV_FILE"
fi
fi
set_env_value() {
local env_key="$1"
local env_value="$2"
local escaped_value
escaped_value="$(printf '%s' "$env_value" | sed 's/[&|\\]/\\&/g')"
if grep -q "^${env_key}=" "$ENV_FILE"; then
sed -i "s|^${env_key}=.*|${env_key}=${escaped_value}|" "$ENV_FILE"
else
printf '%s=%s\n' "$env_key" "$env_value" >> "$ENV_FILE"
fi
}
set_env_value APP_URL "$DEV_APP_URL"
set_env_value DB_CONNECTION "$DEV_DB_CONNECTION"
set_env_value DB_HOST "$DEV_DB_HOST"
set_env_value DB_PORT "$DEV_DB_PORT"
set_env_value DB_DATABASE "$DEV_DB_DATABASE"
set_env_value DB_USERNAME "$DEV_DB_USERNAME"
set_env_value DB_PASSWORD "$DEV_DB_PASSWORD"
set_env_value MAIL_MAILER "$DEV_MAIL_MAILER"
set_env_value MAIL_HOST "$DEV_MAIL_HOST"
set_env_value MAIL_PORT "$DEV_MAIL_PORT"
if [ ! -d "$REPO_ROOT/backend/vendor" ]; then
echo "[composer] installing backend dependencies"
(cd "$REPO_ROOT/backend" && composer install)
fi
if grep -q '^APP_KEY=$' "$ENV_FILE"; then
echo "[laravel] generating application key"
(cd "$REPO_ROOT/backend" && php artisan key:generate)
fi
if [ ! -e "$REPO_ROOT/backend/public/storage" ]; then
echo "[laravel] linking public storage"
(cd "$REPO_ROOT/backend" && php artisan storage:link)
fi
echo "[dev] run 'process-compose up' to start postgres + mailpit + backend + caddy"