Static site + status portal.
This repo contains:
- The web root content served by Nginx.
- A
/statusportal with system metrics and service health. - Ops assets (systemd units, metrics script, Docker option).
Home
Status
- Clone the repo on the server.
- Run the ops installer:
sudo ./ops/install.sh- Ensure Nginx serves
/var/www/htmland has a stub_status endpoint:
location = /status/nginx {
stub_status;
access_log off;
}
- Validate Nginx:
sudo nginx -t- Visit
/status.
This runs the static site in a container while metrics stay on the host.
- Run the host install first (metrics + web root):
sudo ./ops/install.sh- Start the container:
make status-up- Configure host Nginx to proxy
/to the container:
sudo ./ops/docker/proxy-install.sh- Validate Nginx:
sudo nginx -t- Visit
/status.
Run:
./scripts/deploy.shThis syncs the repo contents to /var/www/html.
The deploy excludes status/metrics.json so host metrics aren't wiped.
Run CI checks and deploy in one step:
./scripts/pipeline.shTo bypass git safety checks during deploy:
./scripts/deploy.sh --forceOn pushes:
beta: deploys to the beta host only.main: deploys to production, then attempts a clean merge intobeta; if clean, deploys beta.
The workflow:
- Runs linting, link checks, and Playwright smoke tests.
- Syncs runtime files to the server via rsync (non-runtime files excluded).
- Runs a lightweight uptime check on
/and/status/. - Runs a server-side health check to validate
/var/www/html/status/metrics.json.
Required secrets:
DEPLOY_HOST,DEPLOY_USER,DEPLOY_KEY_B64(beta)PROD_DEPLOY_KEY_B64(prod)
On pull requests, a dry-run rsync preview is executed.
Use GitHub branch protection on main with required status checks for:
- Lint (HTML/CSS)
- Link check
- Playwright smoke tests
This prevents untested changes from reaching deploy.
Run the site locally with mock metrics (no production dependencies required):
docker compose -f docker-compose.dev.yml upAccess at http://localhost:8080
For live-updating mock metrics (simulates real server behavior):
docker compose -f docker-compose.dev.yml --profile live upServe files directly without Docker:
python3 -m http.server 8080Note: Status page metrics won't update without the metrics generator.
Install dev tooling:
npm installRun checks:
npm run lint:html
npm run lint:css
npm run lint:vibe
npm run test:links
npm run test:e2e- Metrics generator:
/usr/local/bin/status-metrics.sh - Timer:
status-metrics.timer(10-second interval) - Metrics JSON:
/var/www/html/status/metrics.json - Status UI:
/status - Nginx stub_status:
/status/nginx
Hybrid container setup lives in ops/docker. See ops/docker/README.md.