Add Nix dev shell with local MariaDB and dev orchestration script
This commit is contained in:
1 parent
6f8c8d7dfa
commit
c8b08fe258
5 files changed
+245
No files matched your search
@@ -0,0 +1,2 @@
|
||||
/.dev/
|
||||
/.direnv/
|
||||
@@ -0,0 +1,25 @@
|
||||
# think.greaterchiangmai.com
|
||||
|
||||
Two Laravel 10 apps sharing one MySQL database (`greaterc_db2024`):
|
||||
|
||||
- `think.greaterchiangmai.com/` — public site
|
||||
- `think-backend.greaterchiangmai.com/` — CMS (`/login`)
|
||||
- `upload-large-file/` — standalone S3 multipart upload helper (Node)
|
||||
|
||||
## Local development
|
||||
|
||||
Requires [Nix](https://nixos.org) with flakes (direnv optional: `.envrc` → `use flake`).
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
Other commands: `dev db start|stop|status|shell`, `dev serve frontend|backend`,
|
||||
`dev artisan <app> ...`, `dev down`. See `dev help`.
|
||||
|
||||
The local DB listens on `127.0.0.1:3307` (override with `DEV_DB_PORT`); the `dev` script
|
||||
injects `DB_*`, `APP_DEBUG=true`, `TEST_LOCAL=true` via the process environment so each
|
||||
app's `.env` is left untouched. Ports: `DEV_FRONTEND_PORT`, `DEV_BACKEND_PORT`.
|
||||
@@ -0,0 +1,158 @@
|
||||
#!/usr/bin/env bash
|
||||
# Local development orchestration. Run inside `nix develop`.
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="${DEV_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
|
||||
FRONTEND="$ROOT/think.greaterchiangmai.com"
|
||||
BACKEND="$ROOT/think-backend.greaterchiangmai.com"
|
||||
STATE="$ROOT/.dev"
|
||||
MYSQL_DATA="$STATE/mysql"
|
||||
MYSQL_SOCK="$STATE/mysql.sock"
|
||||
MYSQL_PID="$STATE/mysql.pid"
|
||||
MYSQL_LOG="$STATE/mysql.log"
|
||||
|
||||
# Must match DB_* in both apps' .env (only the port differs, to avoid clashing with a system MySQL).
|
||||
DB_PORT="${DEV_DB_PORT:-3307}"
|
||||
DB_NAME="greaterc_db2024"
|
||||
DB_USER="greaterc_dbname2024"
|
||||
DB_PASS="6vK25y6Pz8LA6Z3y78qH"
|
||||
|
||||
FRONTEND_PORT="${DEV_FRONTEND_PORT:-8000}"
|
||||
BACKEND_PORT="${DEV_BACKEND_PORT:-8001}"
|
||||
|
||||
# Process env beats .env in Laravel, so this redirects both apps to the local DB without editing .env.
|
||||
export DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT="$DB_PORT" DB_DATABASE="$DB_NAME" DB_USERNAME="$DB_USER" DB_PASSWORD="$DB_PASS"
|
||||
export APP_ENV=local APP_DEBUG=true TEST_LOCAL=true
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: dev <command>
|
||||
|
||||
setup composer install both apps + init local MariaDB
|
||||
db start|stop|status manage local MariaDB (data in .dev/mysql, port $DB_PORT)
|
||||
db shell mysql client on the local DB
|
||||
db import <dump.sql> load a production dump (schema lives only in the prod DB)
|
||||
serve frontend php artisan serve -> http://127.0.0.1:$FRONTEND_PORT
|
||||
serve backend php artisan serve -> http://127.0.0.1:$BACKEND_PORT
|
||||
up db + both apps; Ctrl-C stops everything
|
||||
down stop db and any background servers
|
||||
artisan <app> ... run artisan for frontend|backend with local env
|
||||
EOF
|
||||
}
|
||||
|
||||
app_dir() {
|
||||
case "$1" in
|
||||
frontend) echo "$FRONTEND" ;;
|
||||
backend) echo "$BACKEND" ;;
|
||||
*) echo "unknown app: $1 (frontend|backend)" >&2; exit 2 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
db_running() {
|
||||
[ -f "$MYSQL_PID" ] && kill -0 "$(cat "$MYSQL_PID")" 2>/dev/null
|
||||
}
|
||||
|
||||
db_init() {
|
||||
[ -d "$MYSQL_DATA" ] && return
|
||||
mkdir -p "$MYSQL_DATA"
|
||||
mariadb-install-db --datadir="$MYSQL_DATA" --auth-root-authentication-method=normal >"$STATE/install.log" 2>&1
|
||||
}
|
||||
|
||||
db_start() {
|
||||
mkdir -p "$STATE"
|
||||
db_init
|
||||
if db_running; then
|
||||
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 \
|
||||
>"$MYSQL_LOG" 2>&1 &
|
||||
for _ in $(seq 1 50); do
|
||||
mariadb-admin --socket="$MYSQL_SOCK" -uroot ping >/dev/null 2>&1 && break
|
||||
sleep 0.2
|
||||
done
|
||||
mariadb-admin --socket="$MYSQL_SOCK" -uroot ping >/dev/null 2>&1 || { echo "db: failed to start, see $MYSQL_LOG" >&2; exit 1; }
|
||||
mariadb --socket="$MYSQL_SOCK" -uroot <<SQL
|
||||
CREATE DATABASE IF NOT EXISTS \`$DB_NAME\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE USER IF NOT EXISTS '$DB_USER'@'127.0.0.1' IDENTIFIED BY '$DB_PASS';
|
||||
CREATE USER IF NOT EXISTS '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';
|
||||
GRANT ALL ON \`$DB_NAME\`.* TO '$DB_USER'@'127.0.0.1', '$DB_USER'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
SQL
|
||||
echo "db: listening on 127.0.0.1:$DB_PORT (pid $(cat "$MYSQL_PID"))"
|
||||
}
|
||||
|
||||
db_stop() {
|
||||
db_running || { echo "db: not running"; return; }
|
||||
mariadb-admin --socket="$MYSQL_SOCK" -uroot shutdown
|
||||
echo "db: stopped"
|
||||
}
|
||||
|
||||
db_status() {
|
||||
if db_running; then
|
||||
echo "db: running on 127.0.0.1:$DB_PORT (pid $(cat "$MYSQL_PID"))"
|
||||
mariadb --socket="$MYSQL_SOCK" -uroot "$DB_NAME" -e "SHOW TABLES"
|
||||
else
|
||||
echo "db: stopped"
|
||||
fi
|
||||
}
|
||||
|
||||
db_import() {
|
||||
local dump="${1:?usage: dev db import <dump.sql>}"
|
||||
db_running || db_start
|
||||
mariadb --socket="$MYSQL_SOCK" -uroot "$DB_NAME" <"$dump"
|
||||
echo "db: imported $dump"
|
||||
mariadb --socket="$MYSQL_SOCK" -uroot "$DB_NAME" -e "SHOW TABLES"
|
||||
}
|
||||
|
||||
composer_install() {
|
||||
for app in "$FRONTEND" "$BACKEND"; do
|
||||
[ -f "$app/.env" ] || { echo "missing $app/.env" >&2; exit 1; }
|
||||
(cd "$app" && composer install --no-interaction)
|
||||
done
|
||||
}
|
||||
|
||||
serve() {
|
||||
local dir port
|
||||
dir="$(app_dir "$1")"
|
||||
case "$1" in frontend) port="$FRONTEND_PORT" ;; backend) port="$BACKEND_PORT" ;; esac
|
||||
cd "$dir" && exec php artisan serve --host=127.0.0.1 --port="$port"
|
||||
}
|
||||
|
||||
up() {
|
||||
db_start
|
||||
local pids=()
|
||||
trap 'kill "${pids[@]}" 2>/dev/null; wait; db_stop' 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"
|
||||
echo "backend: http://127.0.0.1:$BACKEND_PORT"
|
||||
wait
|
||||
}
|
||||
|
||||
down() {
|
||||
pkill -f "artisan serve --host=127.0.0.1 --port=($FRONTEND_PORT|$BACKEND_PORT)" 2>/dev/null || true
|
||||
db_stop
|
||||
}
|
||||
|
||||
cmd="${1:-help}"; shift || true
|
||||
case "$cmd" in
|
||||
setup) composer_install; db_start ;;
|
||||
db)
|
||||
sub="${1:-status}"; shift || true
|
||||
case "$sub" in
|
||||
start) db_start ;;
|
||||
stop) db_stop ;;
|
||||
status) db_status ;;
|
||||
shell) db_running || db_start; exec mariadb --socket="$MYSQL_SOCK" -uroot "$DB_NAME" ;;
|
||||
import) db_import "$@" ;;
|
||||
*) usage; exit 2 ;;
|
||||
esac ;;
|
||||
serve) serve "${1:?usage: dev serve frontend|backend}" ;;
|
||||
up) up ;;
|
||||
down) down ;;
|
||||
artisan) dir="$(app_dir "${1:?usage: dev artisan frontend|backend ...}")"; shift; cd "$dir" && exec php artisan "$@" ;;
|
||||
help|-h|--help) usage ;;
|
||||
*) usage; exit 2 ;;
|
||||
esac
|
||||
Generated
+27
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1791734076,
|
||||
"narHash": "sha256-i5qk1kLiit98rRbh1AXmWBNT9QXC/y4l5Wk/u5EdpDQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "7fd4004d0511991fff3a0524856a9be09e28c5f0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
description = "Dev shell for think.greaterchiangmai.com (frontend + backend Laravel apps)";
|
||||
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
|
||||
outputs = { self, nixpkgs }:
|
||||
let
|
||||
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
|
||||
forAll = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});
|
||||
in
|
||||
{
|
||||
devShells = forAll (pkgs:
|
||||
let
|
||||
php = pkgs.php83;
|
||||
in
|
||||
{
|
||||
default = pkgs.mkShell {
|
||||
packages = [
|
||||
php
|
||||
php.packages.composer
|
||||
pkgs.mariadb
|
||||
pkgs.nodejs_22
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
export DEV_ROOT="$PWD"
|
||||
export PATH="$DEV_ROOT/dev:$PATH"
|
||||
echo "think-greaterchiangmai dev shell — run 'dev help'"
|
||||
'';
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user