Laravel Octane
To run the app server in worker mode, set FRANKENPHP_MODE environment variable:
services: app: image: ghcr.io/adiachenko/frankenstack environment: PHP_ENV: development FRANKENPHP_MODE: worker ports: - 8000:80 volumes: - ./:/opt/project restart: unless-stoppedGotchas
Section titled “Gotchas”- Unhandled exceptions during the boot process (e.g. missing
APP_KEY, dependencies, etc.) can cause the container to exit when starting the worker. - Always use a restart policy for automatic recovery in worker mode (see example compose.yml above).
- You may need to run commands like
composer installvia run instead of exec because container will be killed on exception due to missing dependencies. See Running CLI Commands for more details.
Managing workers
Section titled “Managing workers”When FRANKENPHP_MODE=worker is set, Octane is managed by the container at startup. The runtime lifecycle is controlled using Docker commands instead of artisan octane commands:
- Status: use
docker compose psanddocker compose exec app frankenphp-workers-metrics - Reload: use
docker compose exec app frankenphp-workers-restart(or rely onFRANKENPHP_WORKER_WATCHin development)
Common octane:frankenphp options are exposed as environment variables:
| Octane option | Environment variable |
|---|---|
--workers | FRANKENPHP_WORKERS |
--max-requests | FRANKENPHP_MAX_REQUESTS |
--watch | FRANKENPHP_WORKER_WATCH |
--host / --port | Docker networking (ports) and SERVER_NAME |
See more details in Exposed Settings.
Why not
php artisan octane:frankenphp? Frankenstack configures FrankenPHP at the container level instead of through Laravel’s Octane CLI. This keeps classic and worker modes on one configuration path (shared Caddy template, environment variables, and entrypoint logic for timeouts, TLS, and extensions), which reduces mode-specific wiring and makes the image easier to operate and customize. It also keeps the image open to non-Laravel frameworks such as Symfony.