Monitoring and logs
Needs review
Needs review: Check how /api/health and /api/healthcheck behave on tenant hosts: spatie/laravel-health stores results in the file cache per storage directory, and only the platform runs health:check from the image HEALTHCHECK.
Container health checks
Section titled “Container health checks”| Container | Built-in check | What it tests |
|---|---|---|
api |
php artisan health:check every 30 s |
Platform database connection and Redis (app/Providers/HealthCheckProvider.php) |
h5p |
GET http://127.0.0.1:8080/h5p/health |
Liveness and Redis (loopback host, no tenant) |
pdf |
GET http://127.0.0.1:3000/health |
Process up, fonts loaded |
web |
GET http://127.0.0.1:4321/healthz |
Process up (answers ok) |
admin, front |
none | Apache serving static files |
docker compose ps shows the state; restart policies in the example restart crashed containers
but not unhealthy ones. An external monitor should probe the HTTP endpoints below.
HTTP endpoints to probe
Section titled “HTTP endpoints to probe”| URL | Answer |
|---|---|
https://api.<domain>/api/health |
200 or 503 from the last stored health:check result (spatie/laravel-health) |
https://api.<domain>/api/healthcheck |
JSON with each check’s status |
https://<slug>.api.<domain>/h5p/health |
{ok, tenant, db, redis, s3} for that tenant; 503 if a dependency is down, 404 for an unknown tenant |
https://<slug>.app.<domain>/healthz |
ok from the learner front |
https://<slug>.api.<domain>/api/settings |
The tenant’s public settings: a cheap end-to-end check of routing, the tenant env file and its database |
Probe at least the platform API, one tenant’s /h5p/health (it covers the tenant database, Redis
and the bucket) and the front.
Workers and the scheduler
Section titled “Workers and the scheduler”- Horizon runs the platform queues (default and the long-job queue for video). Its dashboard
at
/horizonis open only whenAPP_ENVislocalorstage, or for users allowed by theviewHorizongate, which lists nobody by default. KeepAPP_ENV=production. - Tenant queues are processed by
queue.sh, which loops over all tenant hosts and runsqueue:work --stop-when-empty --domain=<host>for each. Watch for growing Redis lists under the tenant prefixes (ulams_<slug>_queues:default) if jobs seem stuck. - Scheduler:
scheduler.shrunsschedule:runfor the platform and every tenant once a minute. Failed scheduled jobs show up in theapilog.
- Container stdout/stderr: supervisord forwards php-fpm, Horizon, the queue loops and the scheduler
to the
apicontainer log; the Node services log JSON (pino) to stdout; Caddy logs requests with the H5P_tokenparameter and auth headers redacted. The example caps Docker’sjson-filelogs at 5 x 20 MB per container. - Laravel application logs go to the
dailyfile channel by default:storage/logs/laravel-<date>.logfor the platform andstorage/<host with dots as underscores>/logs/for each tenant, on theapi_storagevolume. Rotate or ship them; setLOG_CHANNEL=stderrto send them to the container log instead (not the project’s default).
Error tracking
Section titled “Error tracking”| Component | Variables |
|---|---|
| API | SENTRY_LARAVEL_DSN (or SENTRY_DSN), SENTRY_ENVIRONMENT, SENTRY_RELEASE, SENTRY_TRACES_SAMPLE_RATE, SENTRY_PROFILES_SAMPLE_RATE, SENTRY_SEND_DEFAULT_PII (default off) |
| Admin | REACT_APP_SENTRYDSN on the container; the release is taken from the image version |
| Older React front | VITE_APP_SENTRYDSN on the container |