From f9f1dd2d13c42d1fb19cc13998774cfb16077b27 Mon Sep 17 00:00:00 2001 From: Cyd Date: Wed, 1 Jul 2026 15:34:09 -0500 Subject: [PATCH] Document verified XAMPP Lite 8.5 deployment + add launcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - install/DEPLOYMENT-WALKTHROUGH.md: full verified runbook (operator + headless methods) from an actual deploy — PHP 8.5.5 + MariaDB 11.4.10 + Apache, app at www/pqs, DB provisioned via installer, registration/commit verified, zero PHP 8.5 warnings from app code. - install/start-pqs.bat: one-command launcher (starts MariaDB + Apache, sets the XAMPP_LITE_ROOT/SRVROOT placeholders, provisions the DB on first run). - install/README.md: aligned to this stack's layout (apps/, www/, control panel); corrected the installer 'safe to re-run' note (seed inserts are not idempotent). Co-Authored-By: Claude Opus 4.8 --- install/DEPLOYMENT-WALKTHROUGH.md | 162 ++++++++++++++++++++++++++++++ install/README.md | 78 ++++++++------ install/start-pqs.bat | 58 +++++++++++ 3 files changed, 269 insertions(+), 29 deletions(-) create mode 100644 install/DEPLOYMENT-WALKTHROUGH.md create mode 100644 install/start-pqs.bat diff --git a/install/DEPLOYMENT-WALKTHROUGH.md b/install/DEPLOYMENT-WALKTHROUGH.md new file mode 100644 index 0000000..9f86eac --- /dev/null +++ b/install/DEPLOYMENT-WALKTHROUGH.md @@ -0,0 +1,162 @@ +# PQS on XAMPP Lite 8.5 — verified deployment walkthrough + +This is a full record of an **actual deployment** performed on 2026-07-01, with +the exact commands and the results observed. Stack verified: + +- **Apache** serving **PHP 8.5.5** (Thread-Safe, `php8apache2_4.dll` module) +- **MariaDB 11.4.10** +- App served from `www\pqs`, reachable at `http://localhost/pqs/...` +- **Result:** registration, all console/wall pages, and the Commit-Mission + transaction all worked; **zero PHP 8.5 warnings/deprecations** from app code. + +There are two ways to run it: the **operator method** (GUI control panel — what +you'd do at a venue) and the **headless method** (exact commands, for scripting / +on-demand automation). Both end at the same place. + +--- + +## 0. Stack layout + +``` +xampp_lite_8_5\ + XL-Control-Panel.x64.exe + apps\apache\bin\httpd.exe Apache + apps\apache\conf\httpd.conf Listen 127.0.0.1:80 ; DocumentRoot ${XAMPP_LITE_ROOT}/www + apps\mysql\bin\mysqld.exe MariaDB server + apps\mysql\bin\mysql.exe MariaDB client + apps\mysql\bin\my.ini port 3306 + apps\mysql\data\ datadir (already initialized) + apps\php\php.exe PHP 8.5.5 + www\ document root +``` + +Apache's config resolves two environment placeholders that the control panel +normally sets. For the headless method you set them yourself: + +- `XAMPP_LITE_ROOT` = the stack root, forward slashes, e.g. `C:/VWE/PQS/xampp_lite_8_5` +- `SRVROOT` = `${XAMPP_LITE_ROOT}/apps/apache` + +Default ports: Apache `127.0.0.1:80`, MariaDB `3306`. Confirm they're free first +(`Get-NetTCPConnection -State Listen -LocalPort 80,3306`). + +--- + +## 1. Deploy the application into the web root + +Copy the PQS app into `www\pqs`, excluding the XAMPP stack itself, the `.7z` +archive and `.git`: + +```powershell +robocopy C:\VWE\PQS C:\VWE\PQS\xampp_lite_8_5\www\pqs /E ` + /XD C:\VWE\PQS\xampp_lite_8_5 C:\VWE\PQS\.git /XF *.7z +``` +(robocopy exit codes 0–7 mean success.) + +--- + +## 2. Start MariaDB + +**Operator:** click **Start** next to MySQL in `XL-Control-Panel.x64.exe`. + +**Headless:** +```powershell +$x = "C:\VWE\PQS\xampp_lite_8_5" +Start-Process -FilePath "$x\apps\mysql\bin\mysqld.exe" ` + -ArgumentList "--defaults-file=`"$x\apps\mysql\bin\my.ini`"","--datadir=`"$x\apps\mysql\data`"" ` + -WindowStyle Hidden +``` +Verify it's up (root has no password): +```powershell +& "$x\apps\mysql\bin\mysql.exe" -u root -h 127.0.0.1 -e "SELECT VERSION();" +# -> 11.4.10-MariaDB-log +``` + +--- + +## 3. Provision the database (one time) + +```powershell +$mysql = "$x\apps\mysql\bin\mysql.exe" +cmd /c "`"$mysql`" -u root -h 127.0.0.1 < `"C:\VWE\PQS\install\pqs_install.sql`"" +``` +Verify: +```powershell +& $mysql -u pqs -ppqs -h 127.0.0.1 pqs -e ` + "SELECT (SELECT COUNT(*) FROM pqs_mechinfo) mechs, + (SELECT COUNT(*) FROM pqs_mapinfo) maps, + (SELECT numpods FROM pqs_gameconfig) numpods;" +# -> mechs=63 maps=26 numpods=6 (10 tables, all InnoDB) +``` +> The installer is **not** safe to re-run (seed inserts duplicate / hit the +> `gameconfig` unique key). To redo it: `DROP DATABASE pqs;` then reload. + +--- + +## 4. Start Apache + +**Operator:** click **Start** next to Apache in the control panel. + +**Headless** (must set the two env vars in the *same* shell that launches httpd): +```powershell +$x = "C:\VWE\PQS\xampp_lite_8_5" +$env:XAMPP_LITE_ROOT = ($x -replace '\\','/') +$env:SRVROOT = "$($x -replace '\\','/')/apps/apache" + +# optional sanity check: +& "$x\apps\apache\bin\httpd.exe" -t -f "$x\apps\apache\conf\httpd.conf" # -> Syntax OK + +Start-Process -FilePath "$x\apps\apache\bin\httpd.exe" ` + -ArgumentList "-f","`"$x\apps\apache\conf\httpd.conf`"" -WindowStyle Hidden +``` + +--- + +## 5. Verify end-to-end + +```powershell +# register a player through the kiosk +Invoke-WebRequest -UseBasicParsing ` + "http://localhost/pqs/callsign.php?submit=yes&callsign=XamppTest&mech=41&wclass=Assault" +# -> 200, page contains "entered into the queue" + +& $mysql -u pqs -ppqs -h 127.0.0.1 pqs -e "SELECT CallSign,Mech,MissionID FROM pqs_queue;" +# -> XamppTest Atlas 1 +``` +Observed in this deployment: +- `callsign.php`, `registration.php`, `console.php`, `combinedqueue.php`, + `includes/getqueue.php` → all HTTP **200**, no `Fatal error`. +- Commit Mission (`console.php?submit=Commit+Mission&nummercs=1`) moved the + player to `pqs_currentmission` + `pqs_pastmissions`, emptied the queue, and set + `pqs_mission.Completed=1` — the transaction path works on MariaDB 11.4. +- Apache error log (`tmp\apache_logs\apache_error.log`): **no PHP + warnings/deprecations from app code.** (An `xdebug` load notice can appear from + the CLI `php.exe` only; it does not occur under Apache and is harmless.) + +Screens: +- Kiosk http://localhost/pqs/callsign.php +- Reg console http://localhost/pqs/registration.php +- Ops console http://localhost/pqs/console.php +- Queue wall http://localhost/pqs/combinedqueue.php +- phpMyAdmin http://localhost/phpmyadmin (bundled) + +--- + +## 6. Stop / teardown + +**Operator:** Stop both in the control panel. + +**Headless:** +```powershell +Get-Process httpd, mysqld -ErrorAction SilentlyContinue | Stop-Process +``` +The database persists in `apps\mysql\data`. To wipe the app's data for a fresh +event, `DROP DATABASE pqs;` and re-run the installer (§3), or use the +`docs/Clear Code.txt` truncates to clear just the live queue/mission tables. + +--- + +## 7. One-command launcher + +`install\start-pqs.bat` bundles §2 + §4 and provisions the DB on first run +(§3) if it doesn't exist yet. Copy it to the XAMPP Lite root (next to +`XL-Control-Panel.x64.exe`) and double-click, or run it from a prompt. diff --git a/install/README.md b/install/README.md index b3c3b29..6bdc248 100644 --- a/install/README.md +++ b/install/README.md @@ -1,31 +1,41 @@ # Deploying PQS on XAMPP Lite 8.5 (on-demand) -PQS is designed to run from a **portable XAMPP Lite 8.5** stack (PHP 8.5 + -MariaDB + Apache) so the whole system can be stood up on demand at a venue with -no internet. This folder holds the one-shot database installer. +PQS runs from a **portable XAMPP Lite 8.5** stack (PHP 8.5 + MariaDB 11.4 + +Apache) so the whole system can be stood up on demand at a venue with no +internet. This folder holds the one-shot database installer. -## Steps +> For the full, verified step-by-step (including the headless/scripted method +> and validation results), see **[DEPLOYMENT-WALKTHROUGH.md](DEPLOYMENT-WALKTHROUGH.md)**. +> This page is the short version. -1. **Drop the app into htdocs.** Copy the PQS folder to: +## Stack layout (this XAMPP Lite build) + +``` +xampp_lite_8_5\ + XL-Control-Panel.x64.exe <- start/stop Apache + MySQL here + apps\apache\ <- Apache (serves PHP 8.5 as a module) + apps\mysql\ <- MariaDB 11.4 (root, no password) + apps\php\ <- PHP 8.5 + www\ <- document root (http://localhost/ -> www\) +``` + +## Quick start + +1. **Drop the app into the web root**, named `pqs`: ``` - xampp\htdocs\pqs + xampp_lite_8_5\www\pqs\ ``` - (The app uses `/pqs/...` URLs, so the folder must be named `pqs`.) + (The app uses `/pqs/...` URLs, so the folder must be `pqs`.) -2. **Start Apache and MySQL** from the XAMPP control panel. +2. **Start Apache + MySQL** from `XL-Control-Panel.x64.exe`. -3. **Create the database.** From `xampp\mysql\bin` (XAMPP's MariaDB root has no - password by default): +3. **Create the database** (one time). From `apps\mysql\bin`: ``` - mysql -u root < ..\..\htdocs\pqs\install\pqs_install.sql + mysql.exe -u root < ..\..\..\www\pqs\install\pqs_install.sql ``` - Or in phpMyAdmin (http://localhost/phpmyadmin) → Import → choose - `install\pqs_install.sql`. - - This creates the `pqs` database, the `pqs`/`pqs` application user, every - table (all InnoDB), and the static seed data (mechs, maps, game types, - default game config, pod layout). Queue/mission/history start empty. It is - safe to re-run; to wipe clean, `DROP DATABASE pqs` first. + Or import `install\pqs_install.sql` via phpMyAdmin (http://localhost/phpmyadmin). + This creates the `pqs` database, the `pqs`/`pqs` user, every table (all + InnoDB) and the static seed (mechs, maps, game types, default config, pods). 4. **Open the app:** | Screen | URL | @@ -35,25 +45,35 @@ no internet. This folder holds the one-shot database installer. | Game/ops console | http://localhost/pqs/console.php | | Queue wall | http://localhost/pqs/combinedqueue.php | -That's it — no build step, no internet. +No build step, no internet. ## Notes - **Credentials.** The app connects as `pqs`/`pqs` on `localhost` (see - `includes/db.php`). These are a formality on an air-gapped LAN. + `includes/db.php`) — a formality on an air-gapped LAN. - **Timezone.** Set once in `includes/db.php` (`PQS_TIMEZONE`, default - `America/Chicago`). Change it there. -- **PHP target.** Code targets PHP 7.4+; XAMPP Lite 8.5 ships PHP 8.5. Tested on - PHP 8.3 / MariaDB (see `dev/`). -- **`time.php` (optional clock sync).** Sets the machine clock from the browser - for the air-gapped box. On Windows it uses PowerShell `Set-Date`, which only - works if Apache is **running as administrator**. If the host clock is already - correct you don't need this. + `America/Chicago`). +- **PHP target.** Code targets PHP 7.4+; verified on XAMPP Lite's **PHP 8.5.5** + with zero warnings/deprecations from app code. +- **`time.php` (optional clock sync).** Uses PowerShell `Set-Date` on Windows, + which only works if Apache runs **as administrator**. Skip it if the host + clock is already correct. + +## Re-running / resetting + +The installer is **not** idempotent for the seed data — re-running it duplicates +rows and fails on the `gameconfig` unique key. To reset to a clean database: + +```sql +DROP DATABASE pqs; +``` +then load `pqs_install.sql` again. (The `CREATE DATABASE/USER ... IF NOT EXISTS` +lines are harmless on their own; it's the seed `INSERT`s that must not run twice.) ## Fresh install vs. upgrading an existing DB -- **Fresh XAMPP deploy →** use `install/pqs_install.sql` (this folder). It - already creates every table as InnoDB, so no migrations are needed. +- **Fresh XAMPP deploy →** use `install/pqs_install.sql` (this folder). Every + table is created as InnoDB, so no migrations are needed. - **Upgrading a pre-existing (older MyISAM) database →** run the incremental `dev/migrations/001-*.sql` and `002-*.sql` instead, which convert the affected tables to InnoDB in place. diff --git a/install/start-pqs.bat b/install/start-pqs.bat new file mode 100644 index 0000000..4b5f364 --- /dev/null +++ b/install/start-pqs.bat @@ -0,0 +1,58 @@ +@echo off +setlocal enabledelayedexpansion +REM ===================================================================== +REM PQS on-demand launcher for XAMPP Lite 8.5 +REM Copy this file to the XAMPP Lite root (next to XL-Control-Panel.x64.exe) +REM and run it. It starts MariaDB + Apache and provisions the pqs database +REM on first run. The app must already be deployed to www\pqs . +REM ===================================================================== + +set "ROOT=%~dp0" +if "%ROOT:~-1%"=="\" set "ROOT=%ROOT:~0,-1%" +set "MYSQLBIN=%ROOT%\apps\mysql\bin" +set "APACHEBIN=%ROOT%\apps\apache\bin" +set "APP=%ROOT%\www\pqs" + +if not exist "%MYSQLBIN%\mysqld.exe" ( + echo [PQS] ERROR: run this from the XAMPP Lite root ^(apps\ not found next to it^). + goto :end +) + +REM Apache reads these two placeholders from the environment (forward slashes). +set "XAMPP_LITE_ROOT=%ROOT:\=/%" +set "SRVROOT=%XAMPP_LITE_ROOT%/apps/apache" + +echo [PQS] Starting MariaDB... +start "" /B "%MYSQLBIN%\mysqld.exe" --defaults-file="%MYSQLBIN%\my.ini" --datadir="%ROOT%\apps\mysql\data" + +echo [PQS] Waiting for MariaDB... +set /a TRIES=0 +:waitdb +"%MYSQLBIN%\mysql.exe" -u root -h 127.0.0.1 -e "SELECT 1" >nul 2>&1 +if not errorlevel 1 goto dbready +set /a TRIES+=1 +if !TRIES! GEQ 30 ( echo [PQS] ERROR: MariaDB did not come up. & goto :end ) +ping -n 2 127.0.0.1 >nul +goto waitdb +:dbready +echo [PQS] MariaDB is up. + +"%MYSQLBIN%\mysql.exe" -u root -h 127.0.0.1 -e "USE pqs" >nul 2>&1 +if errorlevel 1 ( + echo [PQS] Provisioning pqs database from installer... + "%MYSQLBIN%\mysql.exe" -u root -h 127.0.0.1 < "%APP%\install\pqs_install.sql" +) else ( + echo [PQS] pqs database already present; skipping provisioning. +) + +echo [PQS] Starting Apache... +start "" /B "%APACHEBIN%\httpd.exe" -f "%ROOT%\apps\apache\conf\httpd.conf" + +echo. +echo [PQS] Ready. +echo Kiosk : http://localhost/pqs/callsign.php +echo Ops : http://localhost/pqs/console.php +echo Wall : http://localhost/pqs/combinedqueue.php +echo Stop : taskkill /IM httpd.exe /F ^&^& taskkill /IM mysqld.exe /F +:end +endlocal