Document verified XAMPP Lite 8.5 deployment + add launcher

- 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 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-01 15:34:09 -05:00
co-authored by Claude Opus 4.8
parent 238cdf5689
commit f9f1dd2d13
3 changed files with 269 additions and 29 deletions
+162
View File
@@ -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 07 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.
+49 -29
View File
@@ -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.
+58
View File
@@ -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