# API + Health Monitor + Dashboard (for ghaymah.systems) This is your uploaded project (`server.js`, `monitor.sh`, `index.html`, `Dockerfile`) with three functional bugs fixed and a couple of production hardening tweaks. Nothing about your architecture changed. ## What was wrong and what I changed 1. **`index.html` was fetching the wrong URL.** `const API_URL = "";` then `fetch(API_URL)` calls the *current page* (`/`), not `/health` — so it was trying to `JSON.parse()` an HTML page and always fell into the `catch` block ("Offline"), even when the API was healthy. Fixed to `fetch('/health')`. 2. **`server.js` had no route serving `index.html`.** The dashboard needs to be reachable somewhere. I added `express.static('public')` and moved `index.html` into `public/`, so the dashboard is served at `/` and the plain-text welcome message moved to `/api` so the two don't collide. 3. **`monitor.sh` referenced `$response_time`, which was never set** — the response-time column was always empty. Fixed by measuring it directly with `curl -w "%{time_total}"`. Also added a fallback JSON parser for when `jq` isn't installed, and an optional CSV log file. 4. **Dockerfile ran `npm init -y && npm install` on every build**, with no lockfile/manifest — slow, non-reproducible, and re-downloads dependencies on every rebuild even if nothing changed. Added a real `package.json` and split `COPY package.json` from `COPY server.js` so Docker caches the `npm install` layer. Also switched `node:20-alpine3.16` (an older, unsupported Alpine point release) to `node:20-alpine` (current supported tag). ## Files ``` . ├── Dockerfile ├── package.json ├── server.js ├── public/ │ └── index.html ← dashboard, served at / └── monitor.sh ← external checker, run it against the deployed URL ``` ## Run locally ```bash npm install npm start # open http://localhost:3000 -> dashboard # open http://localhost:3000/health -> raw JSON ``` In another terminal, point the monitor at it: ```bash chmod +x monitor.sh ./monitor.sh http://localhost:3000 30 ``` ## Build & run with Docker ```bash docker build -t api-health-demo . docker run -d -p 3000:3000 --name api-health-demo api-health-demo ``` ## `/health` response shape ```json { "status": "Online", "uptime_seconds": 42, "request_count": 17, "response_time_ms": 3, "timestamp": "2026-07-27T20:10:00.000Z" } ``` ## Deploy to ghaymah.systems See `DEPLOY_GHAYMAH.md` for the step-by-step (build → push → create service → set port 3000 → point `monitor.sh` at the live URL).