A Docker-based Laravel development environment with FrankenPHP.
This project provides a complete Docker environment for running Laravel applications with FrankenPHP, which combines the Caddy web server and PHP runtime in a single process. It includes:
- Laravel application container (FrankenPHP)
- Properly configured Docker setup for local development
- Performance testing capabilities with autocannon
- Automated testing script for verification
- Redis caching layer for improved performance
FrankenPHP is a modern PHP application server that replaces traditional PHP-FPM setups with better performance and simpler configuration. This test bench demonstrates the benefits of using FrankenPHP for Laravel applications.
- Docker
- Docker Compose
-
Clone the repository:
git clone <repository-url> cd laravel-franken-nginx-test-bench
-
(Optional) Run the environment diagnostic script to check your system:
- Windows: Run
docker-diag.bat
- Windows: Run
-
Build and start the containers:
docker-compose up -d --build
-
The application will be available at
http://localhost:8000
-
(Optional) HTTPS is available at
https://localhost:8443
(you'll need to accept the self-signed certificate)
Note: The first build may take a few minutes as it installs all the required PHP extensions.
If you encounter issues during setup, try using the troubleshooting scripts:
- Windows: Run
docker-troubleshoot.bat
- PowerShell: Run
docker-troubleshoot.ps1
Dockerfile
: Configuration for the Laravel application container with FrankenPHPdocker-compose.yml
: Docker Compose configurationCaddyfile
: Caddy server configuration for FrankenPHPdocker-entrypoint.sh
: Entry point script for the application container
GET /api/hello
- Returns a simple JSON response with a "Hello World" messageGET /api/cache-test
- Tests Redis caching functionalityGET /api/redis-status
- Checks Redis connection status
Run basic performance test:
autocannon http://localhost:8000/api/hello
Run intensive test with 50 connections for 30 seconds:
autocannon -c 50 -d 30 http://localhost:8000/api/hello
Run high-load test with 100 connections for 20 seconds:
autocannon -c 100 -d 20 http://localhost:8000/api/hello
Run the automated test script to verify the setup:
bash test-frankenphp.sh
The test script will:
- Check if the Docker container is running
- Verify the API endpoint is responding correctly
- Display the response from the API
See REDIS-TESTING.md for detailed instructions on testing the Redis implementation.
The Caddyfile
in this project is configured specifically for Laravel applications:
- Uses
php_server
directive to handle PHP files directly within FrankenPHP - Includes proper routing for Laravel's front controller pattern
- Adds security headers for better application security
- Enables compression for improved performance
- Configures logging for easier debugging
- Start containers:
docker-compose up -d
- Stop containers:
docker-compose down
- View logs:
docker-compose logs
- Check container status:
docker-compose ps
Note: Two containers will be running:
laravel_frankenphp
- The main Laravel application containerlaravel_redis
- The Redis caching service
FrankenPHP offers several advantages over traditional PHP-FPM setups:
-
Better Performance: FrankenPHP embeds PHP directly into the Caddy web server, eliminating the need for FastCGI protocol overhead.
-
Simpler Configuration: A single container replaces both Nginx and PHP-FPM containers, reducing complexity.
-
Built-in Features: FrankenPHP includes HTTPS, HTTP/2, HTTP/3, automatic certificates, and more out of the box.
-
Worker Mode: FrankenPHP supports a worker mode that preloads the PHP application, significantly reducing response times for Laravel applications. This is configured through the
FRANKENPHP_CONFIG
environment variable. -
Modern Architecture: FrankenPHP is built with modern Go and PHP technologies for improved reliability and performance.
The application uses a standard Laravel .env
file for configuration. Redis is configured with:
CACHE_DRIVER=redis
REDIS_HOST=redis
REDIS_PORT=6379
- Port mapping: 8000 (host) -> 80 (FrankenPHP container)
- Volume mapping: Current directory is mapped to
/app
in the container - Worker Mode: Configured to preload Laravel application for better performance
The FrankenPHP container is configured to run in worker mode by setting the FRANKENPHP_CONFIG
environment variable to worker ./public/index.php
. This preloads the Laravel application, reducing the response time for subsequent requests.
The Redis container is configured as a separate service in the Docker Compose file.
The Caddy server is configured through the Caddyfile
which includes:
- PHP server configuration for handling Laravel requests
- Security headers for improved security
- Compression for better performance
- Proper routing for Laravel's front controller pattern
This setup includes Redis as a caching layer with the following features:
- Redis service running in a separate container
- PHP Redis extension installed and configured
- Laravel configured to use Redis for caching
- Custom API endpoints to test caching functionality
- Laravel command for testing Redis connectivity
See REDIS-TESTING.md for detailed testing instructions.
-
500 Internal Server Error:
- Check if all required Laravel configuration files exist in the
config
directory - Ensure proper permissions on storage directories
- Check if all required Laravel configuration files exist in the
-
Connection Refused:
- Verify that containers are running with
docker-compose ps
- Check container logs with
docker-compose logs
- Verify that containers are running with
-
Redis Connection Issues:
- Verify that the Redis container is running
- Check Redis container logs with
docker-compose logs redis
- Ensure the Redis configuration in
.env
is correct
-
Docker Desktop Issues:
- Error:
open //./pipe/dockerDesktopLinuxEngine: The system cannot find the file specified
- This error typically occurs when Docker Desktop's Linux container engine isn't running properly
- Solutions:
- Close Docker Desktop completely
- Restart Docker Desktop as an administrator
- Ensure it's set to use Linux containers (not Windows containers)
- If the issue persists, try resetting Docker to factory defaults
- Run the provided troubleshooting scripts (
docker-troubleshoot.bat
ordocker-troubleshoot.ps1
)
- Error:
-
Port Conflicts:
- If port 8000 is already in use, either:
- Stop the process using the port:
netstat -ano | findstr :8000
thentaskkill /PID <pid> /F
- Or change the port mapping in
docker-compose.yml
- Stop the process using the port:
- If port 8000 is already in use, either:
docker-compose logs --tail=20
The application has been tested with autocannon and performs well under various loads:
- Requests: 477
- Latency: Average 213.96ms
- Throughput: 46.7 requests/second
- Data: 137 kB read
Note: Performance may vary based on system resources and current load.
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a new Pull Request
This project is open source and available under the MIT License.