{ pkgs ? import {} }: pkgs.mkShell { buildInputs = with pkgs; [ # PHP and tools php84 php84Packages.composer symfony-cli # Node.js and npm (React/Vite SPA) nodejs_22 # Container tools podman podman-compose # Database client (for direct DB access) postgresql # Utilities git curl gnumake ]; shellHook = '' export USER_ID=$(id -u) export GROUP_ID=$(id -g) export PODMAN_USERNS=keep-id # Compose files (symfony-docker convention: root compose.yaml + compose.override.yaml). # Both must be passed explicitly so the dev override is merged. # NOTE: $COMPOSE is invoked unquoted (word-split into args) — assumes the repo path # contains no spaces. Fine here; would break if checked out under a path with spaces. COMPOSE="podman-compose -f $PWD/compose.yaml -f $PWD/compose.override.yaml" # =================== # ALIASES # =================== alias pc="$COMPOSE" # =================== # DEV COMMANDS # =================== dev-up() { echo "Starting services..." PODMAN_USERNS=keep-id $COMPOSE up -d "$@" echo "" $COMPOSE ps echo "" echo "App available at: http://localhost:8100" } dev-down() { if [[ "$1" == "-v" ]]; then echo "Stopping services and removing volumes..." $COMPOSE down -v else echo "Stopping services..." $COMPOSE down fi } dev-restart() { echo "Restarting services..." $COMPOSE restart "$@" } dev-rebuild() { echo "Rebuilding services (down -v + up)..." $COMPOSE down -v PODMAN_USERNS=keep-id $COMPOSE up -d "$@" echo "" $COMPOSE ps echo "" echo "App available at: http://localhost:8100" } dev-logs() { $COMPOSE logs -f php "$@" } dev-logs-db() { $COMPOSE logs -f database "$@" } dev-shell() { $COMPOSE exec php sh } dev-console() { $COMPOSE exec php php bin/console "$@" } dev-composer() { $COMPOSE exec php composer "$@" } # =================== # QA COMMANDS (run in the php container) # =================== dev-test() { $COMPOSE exec php php bin/phpunit "$@" } # =================== # BUILD COMMANDS # =================== base-build() { local image="forge.lvl0.xyz/lvl0/buckets:latest" # Check if logged in, prompt if not if ! podman login --get-login forge.lvl0.xyz &>/dev/null; then echo "Not logged in to forge.lvl0.xyz" podman login forge.lvl0.xyz || return 1 fi echo "Building image: $image" if ! podman build -t "$image" -f Dockerfile .; then echo "Build failed!" return 1 fi echo "" echo "Pushing to registry..." if ! podman push "$image"; then echo "Push failed!" return 1 fi echo "" echo "Done! Image pushed: $image" } # =================== # WELCOME MESSAGE # =================== echo "" echo "=================================================" echo " Buckets Dev Environment " echo "=================================================" echo "" echo " PHP: $(php --version | head -1 | cut -d' ' -f2)" echo " Symfony: $(symfony version 2>/dev/null | head -1 || echo 'symfony-cli')" echo " Podman: $(podman --version | cut -d' ' -f3)" echo "" echo "Commands:" echo " dev-up [services] Start all or specific services" echo " dev-down [-v] Stop services (-v removes volumes)" echo " dev-rebuild Fresh start (down -v + up)" echo " dev-restart Restart services" echo " dev-logs Tail app logs" echo " dev-logs-db Tail database logs" echo " dev-shell Shell into app container" echo " dev-console Run Symfony console command" echo " dev-composer Run composer in the container" echo " dev-test [args] Run PHPUnit (bin/phpunit)" echo " base-build Build and push image" echo "" echo "Services:" echo " php Symfony/FrankenPHP http://localhost:8100" echo " database Postgres 16 localhost:5433" echo "" ''; }