Deploying with FrankenPHP
FrankenPHP’s worker mode boots your app once and handles many requests. Verge is optimized for this.
Dockerfile
Section titled “Dockerfile”FROM dunglas/frankenphp
COPY . /app
WORKDIR /app
RUN composer install --no-dev --optimize-autoloader
ENTRYPOINT ["frankenphp", "php-server", "--worker", "index.php"]How Worker Mode Works
Section titled “How Worker Mode Works”- Your app boots once (routes register, bindings resolve)
- FrankenPHP handles incoming requests
- Each request runs through your registered routes
- Scoped bindings reset between requests
- Singletons persist across requests
Building and Running
Section titled “Building and Running”docker build -t my-verge-app .docker run -p 8080:8080 my-verge-appDevelopment Mode
Section titled “Development Mode”For development without worker mode:
frankenphp php-server index.phpOr use PHP’s built-in server:
php -S localhost:8000 index.phpEnvironment Variables
Section titled “Environment Variables”Pass environment variables to Docker:
docker run -p 8080:8080 \ -e DATABASE_URL=postgres://... \ -e REDIS_URL=redis://... \ my-verge-appPre-Warming Caches
Section titled “Pre-Warming Caches”For maximum performance, pre-warm your route and container caches before starting:
FROM dunglas/frankenphp
COPY . /app
WORKDIR /app
RUN composer install --no-dev --optimize-autoloaderRUN php bin/verge cache:warm
ENTRYPOINT ["frankenphp", "php-server", "--worker", "index.php"]This serializes route definitions and constructor metadata so the first request is instant. See Bootstrap Caching for details.
How Worker Mode Works
Section titled “How Worker Mode Works”Verge takes advantage of worker mode automatically:
- Singletons are created once and reused
- Routes load from pre-warmed cache
- Container reflection data is pre-compiled
- Only scoped bindings reset per request
No configuration needed—just use singleton() for expensive resources and scoped() for request-specific state.
Health Checks
Section titled “Health Checks”Always include a health endpoint:
app()->get('/health', fn() => ['status' => 'ok']);This lets orchestrators verify your app is running.