DEPLOYMENT.md 7.0 KB

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/.

/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:

/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.

8. Connect the sensor clients

Each ESP32 or other sensor client should send readings to:

POST https://your-domain.example/api/v1/readings.php
Authorization: Bearer <your-token>
Content-Type: application/json

The request and response format is documented in 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:

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