fast-cmf / laradox
Plug-and-play Docker environment for Laravel with FrankenPHP, Nginx, and Octane support
Requires
- php: ^8.2
- illuminate/console: ^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.18
- orchestra/testbench: ^8.0|^9.0|^10.0|^11.0
- phpunit/phpunit: ^10.0|^11.0|^12.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-20 15:41:34 UTC
README
Plug-and-play Docker runtime for Laravel with FrankenPHP, Nginx, Octane, health gates, immutable production images, and cross-platform process execution.
中文文档 / English: README.zh-CN.md · README.md
Laradox 3.0 is built around two different runtime workflows:
- Development uses a bind-mounted working tree, a Node service for asset work, and optional local HTTPS with mkcert.
- Production builds an immutable PHP image containing the application, Composer dependencies, and front-end assets. Only Laravel runtime storage is persisted.
The 3.0 runtime also adds explicit TLS modes, Docker/Compose abstractions, readiness checks, diagnostics, release tracking, registry-backed rollback, and Windows-compatible process execution.
For an existing Laradox installation, read UPGRADE-3.0.md before upgrading.
Requirements
- PHP 8.2+
- Laravel 10.x, 11.x, 12.x, or 13.x
- Docker Engine with Docker Compose
- Composer
- Node.js/npm only when you want to build front-end assets outside the production image
- mkcert is optional and is intended for development only
Laravel 13 requires PHP 8.3+.
Install Laradox 3.0
Laradox 3.0 uses the new Composer package identity fast-cmf/laradox.
1. Install the package
composer require fast-cmf/laradox --dev
The package is published from https://github.com/fast-cmf/laradox.
2. Install Laravel Octane
composer require laravel/octane
3. Publish the Laradox runtime
php artisan laradox:install
This publishes the Docker and Compose templates, helper scripts, and supporting configuration into your Laravel application.
Use --force when you intentionally want to overwrite existing generated files:
php artisan laradox:install --force
The generated runtime layout normally includes:
docker/
├── nginx/
│ ├── conf.d/
│ │ └── app.conf
│ └── ssl/
docker-compose.development.yml
docker-compose.production.yml
composer
npm
php
Development workflow
Development is optimized for editing the Laravel working tree while containers are running.
1. Choose the domain and ports
The defaults are:
LARADOX_DOMAIN=laravel.docker.localhost LARADOX_ENV=development LARADOX_HTTP_PORT=80 LARADOX_HTTPS_PORT=443 LARADOX_FRANKENPHP_PORT=8080
2. Configure development TLS
The default TLS mode is auto.
In development, auto resolves to mkcert-backed HTTPS when local certificates are available. You can also run HTTP-only development explicitly.
For local trusted HTTPS:
php artisan laradox:setup-ssl
The command is intentionally development-only.
You can also select the mode explicitly:
php artisan laradox:up --environment=development --tls-mode=mkcert --detach php artisan laradox:up --environment=development --tls-mode=disabled --detach
For a custom domain, make sure the domain resolves to your local machine. Use --skip-hosts-check only when you manage host resolution yourself.
3. Start the stack
php artisan laradox:up --detach
Build the images before starting:
php artisan laradox:up --detach --build
The development Compose stack includes:
| Service | Purpose |
|---|---|
php |
FrankenPHP + Laravel Octane |
nginx |
Reverse proxy and optional TLS termination |
node |
Development asset tooling |
scheduler |
Laravel scheduler |
queue |
Queue worker |
4. Work with the application
The helper scripts execute commands inside the appropriate containers:
./composer install ./composer require vendor/package ./npm install ./npm run dev ./npm run build ./php artisan migrate ./php artisan queue:work ./php artisan tinker
For an interactive shell:
php artisan laradox:shell php artisan laradox:shell nginx php artisan laradox:shell --shell=bash php artisan laradox:shell --user=appuser
5. Check readiness
php artisan laradox:health php artisan laradox:health --wait --timeout=60 php artisan laradox:health --wait --json
The PHP healthcheck calls Laravel's HTTP health endpoint, which defaults to /up. Nginx exposes /healthz.
Production workflow
Laradox 3.0 treats production as an immutable image deployment.
The production PHP image contains:
- Laravel application source
- production Composer dependencies
- front-end build output
- runtime configuration
The production Compose file does not bind-mount the application source and does not run a Node service. Only /srv/storage is persisted as runtime state.
Production TLS
Set LARADOX_ENV=production and choose a TLS strategy.
| Mode | Behaviour |
|---|---|
auto |
Uses provisioned certificate files |
mkcert |
Development only; rejected in production |
files |
Nginx terminates TLS using provisioned cert/key files |
external |
TLS terminates at an external load balancer, ingress, CDN, or reverse proxy |
disabled |
Explicit HTTP-only production mode |
For Nginx TLS termination:
LARADOX_ENV=production LARADOX_TLS_MODE=files
Provision the certificate and key outside Laradox at the paths configured by config/laradox.php.
For external TLS termination:
LARADOX_ENV=production LARADOX_TLS_MODE=external
In this mode Laradox's Nginx remains HTTP-only.
For an explicitly HTTP-only environment:
LARADOX_ENV=production LARADOX_TLS_MODE=disabled
Do not use laradox:setup-ssl for production.
Build and deploy a release
The normal production entry point is:
php artisan laradox:deploy --environment=production --force
The production flow is:
- Pull the latest Git revision with
git pull --ff-onlyunless--no-pullis used. - Preserve the previously active image.
- Optionally enable Laravel maintenance mode.
- Build the immutable production image.
- Tag the build with the Git revision.
- Recreate the Compose services without relying on a source bind mount.
- Wait until the services are ready.
- Optionally push the immutable release and active image tag.
- Run database migrations.
- Warm Laravel caches and reload Octane workers.
- Mark the verified release as
current. - Leave maintenance mode.
Preview the plan without executing it:
php artisan laradox:deploy --environment=production --dry-run
Deploy non-interactively with maintenance mode:
php artisan laradox:deploy --environment=production --maintenance --force
A production deployment with --no-build cannot pull new source code. To restart the existing immutable image without pulling source, use both:
php artisan laradox:deploy --environment=production --no-build --no-pull --force
Publish releases to a registry
Set the active image reference to the registry location:
LARADOX_PHP_IMAGE=registry.example.com/my-team/my-app:current
Then deploy with:
php artisan laradox:deploy --environment=production --push --force
Laradox publishes the immutable Git-revision tag and the configured active image tag. When the registry exposes a digest, Laradox records it and verifies the digest before activating a pulled rollback release.
Release tracking and rollback
Laradox stores retained release metadata in .laradox/releases.json on the deployment host.
List retained releases:
php artisan laradox:releases
A release record contains the Git-based release ID, image tag, creation time, and registry digest when available.
Roll back to the previous retained release:
php artisan laradox:rollback --force
Roll back to a specific retained release:
php artisan laradox:rollback <release-id> --force
Rollback pulls a missing immutable image when necessary, verifies the recorded digest when present, recreates the production services, waits for readiness, and only then marks the target release as current.
Keep the deployment host's release state available when you rely on local rollback metadata. The release state is intentionally local to the deployment host.
Health, status, and diagnostics
Doctor
Use laradox:doctor before deployment to validate the host and generated configuration:
php artisan laradox:doctor php artisan laradox:doctor --environment=production
Doctor checks include:
- PHP and Laravel availability
- Docker CLI
- Docker Compose
- Compose file presence and syntax
- Compose services
- Docker daemon reachability
- generated Nginx configuration
- TLS mode
- development mkcert availability
- required certificate files
Health
Use laradox:health as a readiness gate for CI or deployment scripts:
php artisan laradox:health --environment=production --wait --timeout=120 --json
Limit the gate to one service when needed:
php artisan laradox:health php --wait --timeout=120
Status
Use laradox:status for a human-readable service report:
php artisan laradox:status php artisan laradox:status --environment=production --stats php artisan laradox:status --watch --stats --interval=10 php artisan laradox:status --json
The report includes service state, healthcheck state, readiness, uptime, published ports, and optional CPU, memory, and network usage.
A service is only considered ready when its runtime state satisfies the readiness rules. Status exits non-zero when a declared service is missing, stopped, starting, or unhealthy.
Optimizing Laravel
Laradox runs production optimization inside the container so the built image and running Octane workers use the same application state.
php artisan laradox:optimize --environment=production php artisan laradox:optimize --environment=production --clear
You can skip individual steps:
php artisan laradox:optimize --skip-autoloader --skip-reload
Development optimization is intentionally more cautious because cached configuration can freeze the current .env values.
Benchmarking
Laradox includes a simple host-side HTTP benchmark:
php artisan laradox:benchmark
php artisan laradox:benchmark --requests=1000 --concurrency=50 --warmup=25
php artisan laradox:benchmark https://laravel.docker.localhost/api/health --insecure
php artisan laradox:benchmark --json > benchmark.json
It reports throughput, success rate, status-code distribution, transfer volume, and latency percentiles.
Direct Docker Compose usage
All Laradox CLI flows are built on the generated Compose files, but direct Compose usage remains available.
Development:
docker compose -f docker-compose.development.yml up -d docker compose -f docker-compose.development.yml down docker compose -f docker-compose.development.yml logs -f
Production:
docker compose -f docker-compose.production.yml up -d --build docker compose -f docker-compose.production.yml down
For normal production releases, prefer laradox:deploy because it adds release tagging, readiness checks, migration/optimization ordering, and rollback state management.
Configuration
Publish the configuration when you need project-specific defaults:
php artisan vendor:publish --tag=laradox-config
The main settings live in config/laradox.php.
Important environment variables
# Domain LARADOX_DOMAIN=laravel.docker.localhost # Default environment LARADOX_ENV=development # TLS: auto|mkcert|files|external|disabled LARADOX_TLS_MODE=auto # Ports LARADOX_HTTP_PORT=80 LARADOX_HTTPS_PORT=443 LARADOX_FRANKENPHP_PORT=8080 # Production active image reference LARADOX_PHP_IMAGE=laradox-php:local # Production queue workers LARADOX_QUEUE_WORKERS=2 # Laravel readiness endpoint LARADOX_HEALTH_PATH=/up # Container user/group IDs LARADOX_USER_ID=1000 LARADOX_GROUP_ID=1000
Nginx configuration
Laradox maintains three generated configuration states:
app-http.conf— HTTP-onlyapp-https.conf— HTTPS with HTTP-to-HTTPS redirectapp.conf— the active generated configuration used by the running stack
Run php artisan laradox:up after changing TLS-related settings so the active configuration is regenerated.
Custom Compose files
All major commands accept a custom Compose file with --file:
php artisan laradox:up --file=/path/to/docker-compose.development.yml php artisan laradox:health --file=/path/to/docker-compose.production.yml php artisan laradox:status --file=/path/to/docker-compose.production.yml php artisan laradox:doctor --file=/path/to/docker-compose.production.yml --environment=production php artisan laradox:rollback --file=/path/to/docker-compose.production.yml --force
This is useful for staging environments or project-specific Compose variants.
Cross-platform execution
Laradox 3.0 routes normal Docker, Compose, container inspection, and host-platform operations through a cross-platform process abstraction rather than constructing shell command strings.
On Windows this avoids common PowerShell quoting and Unix-only redirection assumptions. Where a platform-specific operation genuinely needs shell features, that boundary is explicit and isolated.
The CI workflow includes a Windows cross-platform test job covering the process, Compose, platform, TLS, health, and release foundations.
Command reference
| Command | Purpose |
|---|---|
laradox:install |
Publish the Laradox Docker runtime files |
laradox:setup-ssl |
Generate development mkcert certificates |
laradox:up |
Start the selected Compose environment |
laradox:down |
Stop the selected Compose environment |
laradox:logs |
View container logs |
laradox:shell |
Open an interactive shell in a service |
laradox:health |
Gate on service readiness |
laradox:status |
Inspect state, health, readiness, ports, and usage |
laradox:doctor |
Diagnose host, Docker, Compose, TLS, and generated config |
laradox:optimize |
Warm or clear Laravel caches and reload Octane |
laradox:deploy |
Build and activate an immutable release |
laradox:rollback |
Restore a retained immutable release |
laradox:releases |
List retained release metadata |
laradox:benchmark |
Run an HTTP benchmark |
Legacy TLS compatibility
The 3.0 --force-ssl option remains available for existing scripts:
php artisan laradox:up --force-ssl=true php artisan laradox:up --force-ssl=false
These map to:
true→filesfalse→disabled
For new deployments, prefer --tls-mode or LARADOX_TLS_MODE.
Laravel 3.0 upgrade
For existing Laradox 2.x installations, follow the migration checklist:
The main changes are:
- normal process execution is now cross-platform
- TLS behavior is explicit instead of being implicitly tied to mkcert
setup-sslis development-only- production application code is baked into immutable images
- production Node is removed
- readiness and diagnostics are first-class commands
- production releases can be retained, published, and rolled back by Git revision
- Composer package identity is
fast-cmf/laradoxfor the Laradox 3.0 line
CI
The repository CI validates:
- Laravel 10/11/12/13 compatibility across the supported PHP matrix
- Laravel Pint
- Windows cross-platform unit coverage
- Docker Compose template syntax
- Docker integration
- registry integration
The workflow supports both pushes/PRs and manual execution from GitHub Actions.
License
Laradox is open-sourced software licensed under the MIT license.