This repo is a docker boilerplate to use for Laravel projects. Containers included in this docker:
- Laravel 11 & 12
- FrankenPHP
- MySQL
- Redis
- Supervisor
- Octane
- Minio for S3
- MailPit
The purpose of this repo is to run Laravel 11 & Laravel 12 in a Docker container using Octane and FrankenPHP.
Use the package manager git to install Docker boilerplate.
# setup project locally
$ git clone https://github.com/jaygaha/laravel-11-frankenphp-docker.git
# Navigate to project directory:
$ cd laravel-11-frankenphp-dockerCopy the .env.example file to .env:
# Linux
$ cp .env.example .env
# OR
# Windows
$ copy .env.example .envEdit the .env file to configure your application settings. At a minimum, you should set the following variables:
APP_NAME: The name of your application.APP_ENV: The environment your application is running in (e.g., local, production).APP_KEY: The application key (will be generated in the next step).APP_DEBUG: Set totruefor debugging.APP_URL: The URL of your application.DB_CONNECTION: The database connection (e.g., mysql).DB_HOST: The database host.DB_PORT: The database port.DB_DATABASE: The database name.DB_USERNAME: The database username.DB_PASSWORD: The database password.
Edit docker related setting according to your preferences.
Run composer to install the required packages:
# install required packages
$ composer installGenerate a new application key:
# app key setup
$ php artisan key:generateBuild the Docker images:
# build docker images
$ docker compose buildRun the containers:
# Run containers
$ docker compose up -dTo stop the containers, run:
# Stop containers
$ docker compose downTo view the logs of a specific container, run:
# View logs
$ docker compose logs <container_name>If you are using podman replace docker with podman
To access the application, open your browser and navigate to the URL specified in the APP_URL variable in your .env file.
Upgrading To 12.0 From 11.x
$ composer updateThis repository includes a production-ready Docker configuration with security hardening and performance optimizations.
# 1. Create production env file
cp .env.production.example .env.production
# 2. Generate and set APP_KEY in .env.production
php artisan key:generate --show
# 3. Set DB_PASSWORD in .env.production (required)
# 4. Build and run
docker compose -f docker-compose.prod.yml build
docker compose -f docker-compose.prod.yml up -d
# 5. Check status
docker compose -f docker-compose.prod.yml ps| File | Description |
|---|---|
.docker/php/Dockerfile.prod |
Multi-stage production Dockerfile with FrankenPHP |
.docker/php/php.prod.ini |
Hardened PHP configuration with OPcache |
.docker/etc/supervisor.d/supervisord.prod.conf |
Production supervisor with Octane + 2 queue workers |
docker-compose.prod.yml |
Production compose with resource limits and health checks |
.env.production.example |
Production environment template |
.env.production |
Your production environment config (create from example) |
.dockerignore |
Excludes dev files from production image |
- Copy the production environment file:
cp .env.production.example .env.production- Configure production environment variables in
.env.production:
# Generate APP_KEY
php artisan key:generate --show
# Copy the output and set it in .env.productionRequired settings:
APP_KEY: Application encryption key (required)DB_PASSWORD: Set a strong database passwordAPP_URL: Your production domain (e.g.,https://your-domain.com)SESSION_DOMAIN: Your domain for cookies (e.g.,your-domain.com)- Configure mail and S3 credentials as needed
- Build the production image:
docker compose -f docker-compose.prod.yml build- Run production containers:
docker compose -f docker-compose.prod.yml up -d- Verify all containers are healthy:
docker compose -f docker-compose.prod.yml psThe production configuration includes platform: linux/amd64 for the web container. This is required because FrankenPHP has compatibility issues on ARM64 architecture that cause segmentation faults. The x86_64 emulation via Rosetta 2 works reliably.
If deploying to an AMD64/x86_64 server, you can optionally remove the platform line for native performance.
Container keeps restarting with exit code 139:
- This is a SIGSEGV (segmentation fault), typically caused by FrankenPHP on ARM64
- Ensure
platform: linux/amd64is set in docker-compose.prod.yml
"No application encryption key" error:
- Ensure
APP_KEYis set in.env.production - The
.env.productionfile must be mounted to the container (configured in docker-compose.prod.yml)
MySQL fails to start:
- Use the official
mysqlimage instead ofmysql/mysql-server - Ensure
DB_PASSWORDis set (empty passwords are not allowed)
Dev dependencies not found during build:
- The
composer.jsonincludes adont-discoverlist for dev-only packages - Packages like
laravel/sail,nunomaduro/collision, andspatie/laravel-ignitionare excluded from auto-discovery
- Multi-stage build: Smaller image without build dependencies
- Non-root workers: Queue workers run as
appuser(UID 1000) - No debug tools: Xdebug and dev dependencies excluded
- Hardened PHP:
display_errors=off,expose_php=off - OPcache enabled: JIT compilation for performance
- FrankenPHP + Octane: High-performance request handling with 4 workers
- Resource limits: CPU and memory constraints prevent runaway processes
- Health checks: Container-level health monitoring with
/upendpoint - Secure sessions: HTTP-only, secure cookies enabled
- Log rotation: JSON file logging with size limits
- Dev packages excluded: Auto-discovery disabled for dev-only service providers
Before deploying to production, ensure:
- Strong, unique passwords for database and Redis
-
APP_DEBUG=falseandAPP_ENV=production - HTTPS configured (use a reverse proxy like Nginx/Traefik)
- Secrets managed externally (Docker secrets, Vault, etc.)
- Database backups configured
- Monitoring and alerting set up
- Log aggregation configured (ELK, CloudWatch, etc.)
| Aspect | Local (Dockerfile.local) |
Production (Dockerfile.prod) |
|---|---|---|
| Base image | dunglas/frankenphp:1.1-builder-php8.2 |
dunglas/frankenphp:latest-php8.3 |
| Platform | Native | linux/amd64 (for ARM64 compatibility) |
| Xdebug | Installed | Not included |
| Composer | With dev deps | --no-dev |
| display_errors | On | Off |
| OPcache | Disabled | Enabled with JIT |
| User | Root | appuser (1000) for workers |
| Volumes | Source mounted | Image contains code + .env mounted |
| Resource limits | None | CPU/Memory constrained |
| MySQL image | mysql/mysql-server |
mysql (official) |
| Queue workers | 1 worker | 2 workers |
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
FREE TO USE