From 4d774649881cb7af471df16d29c81a7108e9104c Mon Sep 17 00:00:00 2001 From: kurogeek Date: Thu, 15 Oct 2026 07:36:56 +0000 Subject: [PATCH] Make 'nix run' spin up the whole stack in one command --- README.md | 20 +++++++++++++++----- dev/dev | 17 ++++++++++++++--- flake.nix | 45 +++++++++++++++++++++++++++------------------ 3 files changed, 56 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index c70f468..6bbf220 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,25 @@ Two Laravel 10 apps sharing one MySQL database (`greaterc_db2024`): ## Local development -Requires [Nix](https://nixos.org) with flakes (direnv optional: `.envrc` → `use flake`). +Requires [Nix](https://nixos.org) with flakes. ```sh -nix develop # php 8.3 + composer + mariadb + node on PATH -dev setup # composer install both apps, init MariaDB under .dev/ -dev db import dump.sql # load a production dump — the article/category schema only exists in prod -dev up # http://127.0.0.1:8000 (site), http://127.0.0.1:8001 (CMS); Ctrl-C stops all +nix run # installs vendors on first run, starts MariaDB, serves both apps; Ctrl-C stops all ``` +- site: http://127.0.0.1:8000 +- CMS: http://127.0.0.1:8001 + +The site's article pages need the production schema, which only exists in the prod DB: + +```sh +mysqldump greaterc_db2024 > dump.sql # on the server +nix run . -- db import dump.sql +``` + +`nix run . -- ` forwards to the `dev` script; `nix develop` drops you into a shell with +`dev`, `php`, `composer`, `mariadb`, `node` on PATH (direnv: `.envrc` → `use flake`). + Other commands: `dev db start|stop|status|shell`, `dev serve frontend|backend`, `dev artisan ...`, `dev down`. See `dev help`. diff --git a/dev/dev b/dev/dev index a4ae161..54a2cac 100755 --- a/dev/dev +++ b/dev/dev @@ -65,8 +65,9 @@ db_start() { echo "db: already running (pid $(cat "$MYSQL_PID"))" return fi - mariadbd --datadir="$MYSQL_DATA" --socket="$MYSQL_SOCK" --pid-file="$MYSQL_PID" \ - --port="$DB_PORT" --bind-address=127.0.0.1 --skip-name-resolve \ + # Ignore terminal Ctrl-C in the DB so `up` can shut it down cleanly after the app servers. + (trap '' INT; exec mariadbd --datadir="$MYSQL_DATA" --socket="$MYSQL_SOCK" --pid-file="$MYSQL_PID" \ + --port="$DB_PORT" --bind-address=127.0.0.1 --skip-name-resolve) \ >"$MYSQL_LOG" 2>&1 & for _ in $(seq 1 50); do mariadb-admin --socket="$MYSQL_SOCK" -uroot ping >/dev/null 2>&1 && break @@ -121,9 +122,19 @@ serve() { } up() { + for app in "$FRONTEND" "$BACKEND"; do + [ -f "$app/vendor/autoload.php" ] || composer_install + done db_start local pids=() - trap 'kill "${pids[@]}" 2>/dev/null; wait; db_stop' EXIT INT TERM + cleanup() { + trap - EXIT INT TERM + set +e + kill "${pids[@]}" 2>/dev/null + wait "${pids[@]}" 2>/dev/null + db_stop + } + trap cleanup EXIT INT TERM (cd "$FRONTEND" && php artisan serve --host=127.0.0.1 --port="$FRONTEND_PORT") & pids+=($!) (cd "$BACKEND" && php artisan serve --host=127.0.0.1 --port="$BACKEND_PORT") & pids+=($!) echo "frontend: http://127.0.0.1:$FRONTEND_PORT" diff --git a/flake.nix b/flake.nix index bd04a18..49cede7 100644 --- a/flake.nix +++ b/flake.nix @@ -7,27 +7,36 @@ let systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; forAll = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system}); + toolchain = pkgs: + let php = pkgs.php83; in + [ php php.packages.composer pkgs.mariadb pkgs.nodejs_22 ]; in { - devShells = forAll (pkgs: - let - php = pkgs.php83; - in - { - default = pkgs.mkShell { - packages = [ - php - php.packages.composer - pkgs.mariadb - pkgs.nodejs_22 - ]; + devShells = forAll (pkgs: { + default = pkgs.mkShell { + packages = toolchain pkgs; + shellHook = '' + export DEV_ROOT="$PWD" + export PATH="$DEV_ROOT/dev:$PATH" + echo "think-greaterchiangmai dev shell — run 'dev help'" + ''; + }; + }); - shellHook = '' - export DEV_ROOT="$PWD" - export PATH="$DEV_ROOT/dev:$PATH" - echo "think-greaterchiangmai dev shell — run 'dev help'" + # `nix run` = `dev up` with the toolchain on PATH, no `nix develop` needed. + # Runs the checked-out dev/dev (not a store copy) so state lands in the working tree. + apps = forAll (pkgs: { + default = { + type = "app"; + program = toString (pkgs.writeShellApplication { + name = "dev"; + runtimeInputs = toolchain pkgs; + text = '' + [ -x "$PWD/dev/dev" ] || { echo "run from the repo root (dev/dev not found in $PWD)" >&2; exit 1; } + DEV_ROOT="$PWD" exec "$PWD/dev/dev" "''${@:-up}" ''; - }; - }); + }) + "/bin/dev"; + }; + }); }; }