This application can run on basic shared webhosting because it uses:
The deployment target assumed by this guide is a classic shared hosting account with a document root such as public_html/.
Required:
src/ and read/write data/Optional but useful:
mail() configuration for email alertsallow_url_fopen enabled for webhook alertscdn.jsdelivr.net if the Swagger UI should load at /docs/ or <base-path>/docs/Not required:
The application now supports an optional configured base path for deployments below the domain root.
Examples:
https://monitor.example.com/https://example.com/https://example.com/monitor/The relevant config value is app.base_path in data/config.json:
/"/monitor"monitor, /monitor, and /monitor/ all become "/monitor"This setting is used for generated links, asset URLs, admin redirects, and dashboard API polling.
Important:
app.base_path changes URLs, not the required PHP file layoutsrc/ and data/ must still stay outside the public web root../src/... and ../data/... paths resolve correctlyKeep the repository structure as-is and point the domain document root to public/.
/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/
public_html/If the host does not let you choose public/ as document root, upload the files like this:
/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:
public/ into public_html/src/ next to public_html/, not inside itdata/ next to public_html/, not inside itThis exact layout matches how the PHP files resolve ../src/bootstrap.php and ../data/....
Public in the web root:
index.phpstyles.cssapp.jsopenapi.yamladmin/api/docs/Private, outside the public web root:
src/data/config.jsondata/state.jsondata/alert_log.jsonDo not place data/ inside the public web root if you can avoid it. Those files contain credentials, live state, and alert history.
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.
Using FTP, SFTP, or your hosting file manager:
src/ outside the public web rootdata/ outside the public web rootpublic/ into the public web rootFor a typical shared host that means:
src/ -> server ~/src/data/ -> server ~/data/public/* -> server ~/public_html/PHP must be able to write to data/ and the JSON files in it.
Typical safe defaults:
755 or 775644 or 664If 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.jsondata/state.jsondata/alert_log.jsonIn the hosting control panel, select PHP 8.1 or newer for the domain/subdomain.
After upload, these URLs should work.
If app.base_path is empty:
//admin//api/v1/status.php/docs//openapi.yamlExamples:
https://monitor.example.com/https://monitor.example.com/admin/https://monitor.example.com/api/v1/status.phpIf app.base_path is set to /monitor:
/monitor//monitor/admin//monitor/api/v1/status.php/monitor/docs//monitor/openapi.yamlExamples:
https://example.com/monitor/https://example.com/monitor/admin/https://example.com/monitor/api/v1/status.phpThe example files ship with placeholder credentials. After the first login, immediately change:
You can do that in /admin/ or <base-path>/admin/, depending on the deployment.
In the admin panel, configure:
For the base path:
/monitorThe JSON structure is documented in CONFIG.md.
Each ESP32 or other sensor client should send readings to:
POST https://your-domain.example<base-path>/api/v1/readings.php
Authorization: Bearer <your-token>
Content-Type: application/json
Examples:
https://your-domain.example/api/v1/readings.phpapp.base_path = "/monitor": https://your-domain.example/monitor/api/v1/readings.phpThe request and response format is documented in API.md.
Verify all of the following:
data/state.json updates after a test reading/api/v1/status.php returns JSON/docs/ loads Swagger UIUse one manual API call after deployment:
curl -X POST https://your-domain.example<base-path>/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.
Cause:
data/ is not writable by PHPCheck:
src/bootstrap.phpCause:
src/ was uploaded into the wrong placeFix:
src/ next to public_html/, not inside itCheck:
Authorization headers are forwarded by the hostThe app already checks both HTTP_AUTHORIZATION and REDIRECT_HTTP_AUTHORIZATION, which helps on many Apache-based hosts.
Cause:
app.base_path does not match the actual public URL prefixFix:
app.base_path empty for deployment at //monitor/admin/ or update data/config.json directly if the admin URL is currently wrong/docs/ does not renderCause:
cdn.jsdelivr.netFix:
app.base_path correctly for the final public URLsrc/ and data/ outside the public web rootdata/ is writable