# Deployment Guide This application can run on basic shared webhosting because it uses: - plain PHP - no database - no Composer dependencies - JSON files for persistence The deployment target assumed by this guide is a classic shared hosting account with a document root such as `public_html/`. ## Requirements Required: - PHP 8.1 or newer recommended - PHP sessions enabled - permission for PHP to read `src/` and read/write `data/` - domain or subdomain pointing to the app Optional but useful: - working `mail()` configuration for email alerts - `allow_url_fopen` enabled for webhook alerts - outbound HTTPS requests for webhook alerts - browser access to `cdn.jsdelivr.net` if `/docs/` should load Swagger UI Not required: - database - Composer - Node.js - cron job ## Important Deployment Limitation The current app is written for deployment at the web root of a domain or subdomain, for example: - `https://monitor.example.com/` - `https://example.com/` It is currently **not prepared for deployment in a subfolder** such as `https://example.com/monitor/`, because the frontend uses root-relative URLs like: - `/styles.css` - `/app.js` - `/admin/` - `/api/v1/status.php` If subfolder deployment is needed later, the code should be adjusted first. ## Where Everything Should Be ### Preferred layout if the host allows a custom document root Keep the repository structure as-is and point the domain document root to `public/`. ```text /home/account/getraenke-monitor/ ├── data/ │ ├── alert_log.json │ ├── config.json │ └── state.json ├── public/ <- document root │ ├── admin/ │ ├── api/ │ ├── docs/ │ ├── app.js │ ├── index.php │ ├── openapi.yaml │ └── styles.css └── src/ ``` ### Recommended layout for basic shared hosting with `public_html/` If the host does not let you choose `public/` as document root, upload the files like this: ```text /home/account/ ├── data/ │ ├── alert_log.json │ ├── config.json │ └── state.json ├── public_html/ <- public contents go here │ ├── admin/ │ ├── api/ │ ├── docs/ │ ├── app.js │ ├── index.php │ ├── openapi.yaml │ └── styles.css └── src/ ``` Important: - upload the **contents of `public/`** into `public_html/` - upload `src/` next to `public_html/`, not inside it - upload `data/` next to `public_html/`, not inside it This exact layout matches how the PHP files resolve `../src/bootstrap.php` and `../data/...`. ## What Must Be Public And What Must Stay Private Public in the web root: - `index.php` - `styles.css` - `app.js` - `openapi.yaml` - `admin/` - `api/` - `docs/` Private, outside the public web root: - `src/` - `data/config.json` - `data/state.json` - `data/alert_log.json` Do not place `data/` inside the public web root if you can avoid it. Those files contain credentials, live state, and alert history. ## Deployment Steps ### 1. Prepare the files From this repository, you need these folders: - `public/` - `src/` - `data/` You do not need `docs/` on the server for runtime operation. The `docs/` folder in the repository is only Markdown documentation for developers. ### 2. Upload the application Using FTP, SFTP, or your hosting file manager: - upload `src/` outside the public web root - upload `data/` outside the public web root - upload the contents of `public/` into the public web root For a typical shared host that means: - repo `src/` -> server `~/src/` - repo `data/` -> server `~/data/` - repo `public/*` -> server `~/public_html/` ### 3. Set permissions PHP must be able to write to `data/` and the JSON files in it. Typical safe defaults: - directories: `755` or `775` - files: `644` or `664` If the host runs PHP under your own account, `755/644` is often enough. If writes fail, adjust group write permissions first before considering anything more permissive. The app needs write access for: - `data/config.json` - `data/state.json` - `data/alert_log.json` ### 4. Set the PHP version In the hosting control panel, select PHP `8.1` or newer for the domain/subdomain. ### 5. Open the app After upload, these URLs should work: - `/` - `/admin/` - `/api/v1/status.php` - `/docs/` - `/openapi.yaml` Examples: - `https://monitor.example.com/` - `https://monitor.example.com/admin/` - `https://monitor.example.com/api/v1/status.php` ### 6. Replace the default credentials The example files ship with placeholder credentials. After the first login, immediately change: - admin username - admin password - API bearer token You can do that in `/admin/`. ### 7. Configure the application In the admin panel, configure: - app name - timezone - dashboard refresh interval - email sender - webhook targets - email recipients - machines - slots - sensor calibration values - alert thresholds The JSON structure is documented in [CONFIG.md](./CONFIG.md). ### 8. Connect the sensor clients Each ESP32 or other sensor client should send readings to: ```text POST https://your-domain.example/api/v1/readings.php Authorization: Bearer Content-Type: application/json ``` The request and response format is documented in [API.md](./API.md). ### 9. Run a deployment check Verify all of the following: - dashboard loads without PHP errors - admin login works - saving config works - `data/state.json` updates after a test reading - webhook delivery works if configured - email delivery works if configured - `/api/v1/status.php` returns JSON - `/docs/` loads Swagger UI ## First Live Test Use one manual API call after deployment: ```bash curl -X POST https://your-domain.example/api/v1/readings.php \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "machine_id": "automat-lobby", "sensor_id": "fach-a1", "distance_mm": 184 }' ``` If that works, the dashboard should shortly show the new state. ## Troubleshooting ### Dashboard loads, but saving config fails Cause: - `data/` is not writable by PHP Check: - directory permissions - file ownership - hosting PHP user ### PHP errors about missing `src/bootstrap.php` Cause: - `src/` was uploaded into the wrong place Fix: - place `src/` next to `public_html/`, not inside it ### API works locally but not on shared hosting Check: - PHP version - whether `Authorization` headers are forwarded by the host - whether HTTPS is used The app already checks both `HTTP_AUTHORIZATION` and `REDIRECT_HTTP_AUTHORIZATION`, which helps on many Apache-based hosts. ### `/docs/` does not render Cause: - the Swagger UI page loads its assets from `cdn.jsdelivr.net` Fix: - allow outbound access to the CDN - or replace the hosted Swagger assets with local files later ## Recommended Go-Live Checklist - deploy at the domain root, not in a subfolder - keep `src/` and `data/` outside the public web root - ensure `data/` is writable - replace all demo credentials - test one real API reading - verify alerts before production use