Docker Health Monitoring
Runtime optimizations and health monitoring for production/staging deployments using Docker ENTRYPOINT pattern and Spatie Health package.
Overview
Section titled “Overview”Docker ENTRYPOINT pattern provides:
- Runtime Laravel optimization at container startup
- Health monitoring via Spatie Health package
- Portable Docker images across environments
- Consistent initialization across container restarts
Docker ENTRYPOINT Pattern
Section titled “Docker ENTRYPOINT Pattern”What It Does
Section titled “What It Does”Executes at container startup (runtime) instead of Docker build time:
- Configures PHP limits from environment variables (
PHP_MEMORY_LIMIT,PHP_POST_MAX_SIZE,PHP_UPLOAD_MAX_FILESIZE,PHP_MAX_EXECUTION_TIME,PHP_MAX_INPUT_TIME) - Tunes the PHP-FPM pool from environment variables (
PHP_FPM_PM_MAX_CHILDREN,PHP_FPM_PM_START_SERVERS,PHP_FPM_PM_MIN_SPARE_SERVERS,PHP_FPM_PM_MAX_SPARE_SERVERS,PHP_FPM_REQUEST_SLOWLOG_TIMEOUT,PHP_FPM_REQUEST_TERMINATE_TIMEOUT,PHP_FPM_SLOWLOG,PHP_FPM_ACCESS_FORMAT) php artisan filament:optimize- Optimizes FilamentPHP assetsphp artisan optimize- Caches Laravel routes, views, config
Benefits
Section titled “Benefits”- Config cache uses actual runtime environment variables
- Portable Docker images work across dev/staging/production
- OptimizedAppCheck passes with proper caching state
- Consistent initialization across container restarts
Implementation
Section titled “Implementation”Shared entrypoint script: backend/docker/common/docker-entrypoint.sh
Used by:
php-fpmcontainerqueue-workercontainerschedulercontainer
Health Monitoring
Section titled “Health Monitoring”Configured Checks
Section titled “Configured Checks”| Check | Purpose | Configuration |
|---|---|---|
| DatabaseCheck | Verify database connectivity | Default |
| CacheCheck | Verify cache connectivity | Default |
| UsedDiskSpaceCheck | Monitor disk usage | Warn: 70%, Fail: 90% |
| OptimizedAppCheck | Verify Laravel optimization (prod/staging) | Checks config/route cache |
| DebugModeCheck | Ensure debug mode off (prod/staging) | Fails if APP_DEBUG=true |
| EnvironmentCheck | Verify correct environment (prod/staging) | Checks APP_ENV value |
External Monitoring
Section titled “External Monitoring”Application errors and performance are monitored via:
- Sentry (
sentry/sentry-laravel) — Error tracking and performance tracing - Nightwatch — APM, ingested through a dedicated agent container (
laravelphp/nightwatch-agent) defined incompose.yaml - Container health checks (
HEALTHCHECKin each image)
Production Containers
Section titled “Production Containers”Container Names
Section titled “Container Names”php-fpm: # Web application (PHP-FPM)backend: # Nginx front (serves php-fpm) — the "backend" ECR imagequeue-worker: # Processes background jobsscheduler: # Runs scheduled tasks (schedule:work)nightwatch: # Nightwatch APM agentEach of php-fpm, queue-worker, backend (nginx), and frontend is built as
its own ECR image (see Deployment). The scheduler
runs as a container but is not a separate ECR image — it reuses the
queue-worker / php image with a different command.
Scheduler Container
Section titled “Scheduler Container”Dedicated container running Laravel scheduler in production/staging:
php artisan schedule:workPurpose: Executes the scheduled commands defined in backend/routes/console.php:
telescope:prune- Daily cleanup (keeps 14 days, preserves exceptions)model:prune- Daily health history cleanup (1-day retention)currency:sync-rates- Daily exchange rate sync from the configured provideroffers:auto-generate- Every 15 minutes, from flight cache entriesoffers:draft-released- Daily, withdraws offers that entered the supplier release-days windowflights:mark-stale-searching-as-failed- Every 5 minutes, flips silently-dead flight cache rows to FAILEDProcessScheduledBalancePaymentsJob(Job) - Hourly scheduled balance paymentsdb-backup.sh- Daily at 05:00 UTC, uploads a fresh DB dump to S3 (see Database Backup)
Deployment: Configured in infrastructure templates:
infra-volare/.../staging-1/.../api-staging-1.user-data.tmplinfra-volare/.../production-1/.../api-production-1.user-data.tmpl
Health Endpoints
Section titled “Health Endpoints”JSON Health Endpoint
Section titled “JSON Health Endpoint”GET /healthReturns JSON with all check results:
{ "finishedAt": "2025-11-14 17:30:00", "checkResults": [ { "name": "Database", "status": "ok" }, { "name": "Cache", "status": "ok" } ]}Response Codes:
200- All checks passed503- One or more checks failed
Health Dashboard
Section titled “Health Dashboard”GET /health-dashboardAuthenticated UI showing cached health check results (requires login).
Manual Health Check
Section titled “Manual Health Check”php artisan health:checkConfiguration
Section titled “Configuration”Environment Variables
Section titled “Environment Variables”HEALTH_NOTIFICATION_EMAIL=ops@example.comHEALTH_DB_CONNECTION=pgsqlQueue Worker Memory
Section titled “Queue Worker Memory”The queue worker has a separate Laravel memory threshold, configured in megabytes:
QUEUE_WORKER_MEMORY=384The image defaults to 384. An empty override also uses the default. Any other value must be a positive integer, or the container exits during startup with a configuration error. Keep this threshold below the container memory limit so the worker can shut down cleanly before Docker terminates it.
Config File
Section titled “Config File”File: config/health.php
- Result storage: Database (1-day history)
- Notifications: Email (throttled to 1/hour)
Load Balancer Integration
Section titled “Load Balancer Integration”Configure a load balancer (e.g., AWS ALB) to poll the /health endpoint:
Health Check Settings:
- Path:
/health - Interval: 30 seconds
- Timeout: 5 seconds
- Healthy threshold: 2
- Unhealthy threshold: 2
Troubleshooting
Section titled “Troubleshooting”OptimizedAppCheck Failing
Section titled “OptimizedAppCheck Failing”- Ensure ENTRYPOINT executes before service starts
- Check container logs for optimization errors
- Verify runtime environment variables set correctly
# Check if optimization randocker logs php-fpm | grep "artisan optimize"Disk Space Warning
Section titled “Disk Space Warning”- Check disk usage:
df -h- Clean old logs:
php artisan telescope:prune- Prune health history: Daily scheduled task handles this
Database Connection Issues
Section titled “Database Connection Issues”- Check database connectivity:
php artisan tinker>>> DB::connection()->getPdo();- Verify environment variables:
php artisan config:show databaseCache Connection Issues
Section titled “Cache Connection Issues”- Check Redis connectivity:
php artisan tinker>>> Cache::get('test');- Verify Redis configuration:
php artisan config:show cacheSpatie Health Package
Section titled “Spatie Health Package”Adding Custom Checks
Section titled “Adding Custom Checks”use Spatie\Health\Facades\Health;use Spatie\Health\Checks\Checks\DatabaseCheck;
Health::checks([ DatabaseCheck::new(), CacheCheck::new(), UsedDiskSpaceCheck::new() ->warnWhenUsedSpaceIsAbovePercentage(70) ->failWhenUsedSpaceIsAbovePercentage(90), // Add custom checks here]);Custom Check Example
Section titled “Custom Check Example”use Spatie\Health\Checks\Check;use Spatie\Health\Checks\Result;
class QueueSizeCheck extends Check{ public function run(): Result { $queueSize = Queue::size('default');
if ($queueSize > 1000) { return Result::make() ->failed("Queue size is {$queueSize}"); }
if ($queueSize > 500) { return Result::make() ->warning("Queue size is {$queueSize}"); }
return Result::make() ->ok("Queue size is {$queueSize}"); }}Related Documentation
Section titled “Related Documentation”- Queue System - Queue infrastructure
- Health Monitoring - Application health checks