v4.0.0-beta1
Pre-releaseβ‘οΈ What's new
π§ββοΈ FrankenPHP variations now added
The highly anticipated release of FrankenPHP is now available. These images come with many enhancements compared to the official FrankenPHP images.
Images are unprivileged by default
For best security practices, we're running things as www-data. This dramatically reduces your security footprint when running PHP in production. Because of this, we're listening on 8080 (HTTP) and 8443 (HTTPS). This follows the same design pattern as our other images.
Native health checks
Health checks are critical for ensureing zero-downtime deployments. Our images come "batteries included" with intelligent health check endpoints that can easily be customized with $HEALTHCHECK_PATH. By default, our images ensure /healthcheck is alive with Caddy, but you can change this variable to HEALTHCHECK_PATH=/up and it will use the built-in Laravel health check endpoint to ensure Laravel is actually ready to accept requests.
Extremely flexible and production-grade Caddyfile by default
The default FrankenPHP Caddyfile gives you enough to get started, but we spent a ton of time making sure that we're shipping production-grade and secure configurations by default. This includes:
- Native CloudFlare support with trusted IP addresses
- Performance and caching rules made available by default
- Security headers included by default
- Flexible and powerful logging defaults
- Simple and intelligent self-signed certificate generation (but still allowing you to use Let's Encrypt if you wanted)
Designed for mass-scale production deployments
It's almost unbelievable and amazing how well FrankenPHP works with Caddy as a proxy. This tight integration allows you to do magical things like deploy trusted SSLs with Let's Encrypt. The only problem is, you probably have something else serving SSL termination and you most likely would not use that feature in a single container.
Our approach is "orchestrator first", meaning the image is designed for mass-scale in mind.
This means we're shipping the image assuming that you're doing TLS termination elsewhere. This makes it easier for you to scale and perform zero-downtime deployments:
flowchart TD
A["Reverse Proxy
(Not FrankenPHP)"] -->C{Container Service}
C -->|STOP| D[MyApp:v1]
C -->|START| E[MyApp:v2]Flexible environment configuration
Just like the experience with our other PHP variations, we also have things like SSL_MODE, LOG_OUTPUT_LEVEL, changing PHP INI settings with environment variables, all our helper scripts for changing permissions, etc. that make it a breeze for you to customize how the PHP image behaves.
More operating system variations
We are able to compile FrankenPHP by source, which allows us to open up support for many operating systems.
How tagging works
There's more to it, but in general the primary principle is:
{php-minor-version}-{variation}-{os-version}This means we're offering FrankenPHP with the following operating systems:
trixie: Debian Trixie (13)bookworm: Debian Bookworm (12)alpine3.22: Alpine 3.22alpine3.21: Alpine 3.21
π New Environment Variables
The following environment variables are now available:
| Environment Variable | Default | Authored By |
|---|---|---|
| AUTORUN_DEBUG | false | @jaydrogers |
| AUTORUN_LARAVEL_OPTIMIZE | true | @aSeriousDeveloper |
| AUTORUN_LARAVEL_MIGRATION_FORCE | true | @jaydrogers |
| AUTORUN_LARAVEL_MIGRATION_MODE | default |
@jaydrogers |
| AUTORUN_LARAVEL_MIGRATION_SEED | false | @jaydrogers |
| AUTORUN_LARAVEL_MIGRATION_SKIP_DB_CHECK | false | @jaydrogers |
| NGINX_ACCESS_LOG | /dev/stdout |
@robsontenorio |
| NGINX_CLIENT_MAX_BODY_SIZE | 100M |
@dlundgren |
| NGINX_ERROR_LOG | /dev/stderr |
@robsontenorio |
| NGINX_LISTEN_IP_PROTOCOL | all |
@yuuzukatsu, @jaydrogers |
| PHP_FPM_PM_MAX_REQUESTS | 0 | @ifaridjalilov, @thueske |
| PHP_FPM_PM_STATUS_PATH | /status |
@jaydrogers |
| PHP_MAX_INPUT_VARS | 1000 | @RadeJR |
| PHP_OPCACHE_ENABLE_FILE_OVERRIDE | 0 |
@jaydrogers |
| PHP_OPCACHE_FORCE_RESTART_TIMEOUT | 180 | @aSeriousDeveloper, @jaydrogers |
| PHP_OPCACHE_JIT | off | @aSeriousDeveloper, @jaydrogers |
| PHP_OPCACHE_JIT_BUFFER_SIZE | 0 | @aSeriousDeveloper, @jaydrogers |
| PHP_OPCACHE_SAVE_COMMENTS | 1 | @aSeriousDeveloper, @jaydrogers |
| PHP_OPCACHE_VALIDATE_TIMESTAMPS | 1 | @aSeriousDeveloper, @jaydrogers |
| PHP_REALPATH_CACHE_TTL | 120 |
@jaydrogers |
| PHP_ZEND_DETECT_UNICODE | null |
@jaydrogers |
| PHP_ZEND_MULTIBYTE | Off |
@jaydrogers |
π€© New Features
Laravel Automations Script Improvements
The Laravel Automations script has been completely refactored to make it easier to support advanced Laravel features. Tons of new features are now available:
"php artisan optmize" now run by default
Instead of setting AUTORUN_LARAVEL_ROUTE_CACHE, AUTORUN_LARAVEL_VIEW_CACHE etc, we use AUTORUN_LARAVEL_OPTIMIZE by default, which calls php artisan optimize. Readjusting our logic to this new structure not only simplifies our approach to follow Laravel's best practices, it allows you to hook into the optimize command if you need to use it for your own application.
If you don't want to use php artisan optimize or if you're running an older version of Laravel, no sweat! Our refactored approach is backwards compatible and you can enable/disable certain functions by just setting your desired values to AUTORUN_LARAVEL_ROUTE_CACHE, AUTORUN_LARAVEL_VIEW_CACHE etc.
Added support for "migration modes"
We now support different migration modes of refresh or fresh by Laravel. This is super helpful if you need to seed a preview environment.
| Migration Mode | Description |
|---|---|
default (our default behavior) |
Runs php artisan migrate - standard forward migrations |
fresh |
Runs php artisan migrate:fresh - drops all tables and re-runs migrations |
refresh |
Runs php artisan migrate:refresh - rolls back and re-runs migrations |
Specify which database connections to run migrations with
If you run multiple databases with a multi-tenant Laravel application, you may need to specify your exact database connection that you'd like to use. We created AUTORUN_LARAVEL_MIGRATION_DATABASE so you can set the configuration name of the database connection you'd like to run migrations on (ie. mysql). Supports running against multiple databases too (ie. mysql,pgsql).
Added "--seed" option to migrations
Laravel has a helpful flag of --seed that you can run with php artisan migrate that will indicate if the seed task should be re-run. If you need this, just set AUTORUN_LARAVEL_MIGRATION_SEED to true.
Easier debugging
If you're running into issues with automations, set AUTORUN_DEBUG to true and you'll get helpful output to help you figure out why you're running into issues.
Control NGINX IP listening protocols with NGINX_LISTEN_IP_PROTOCOL
Are you running an IPv6 only cluster with fpm-nginx? Now you can set NGINX_LISTEN_IP_PROTOCOL: ipv6 and NGINX will listen on IPv6 stacks only. Same thing works if you set it to ipv4, then IPv6 will be disabled.
Great for Kubernetes clusters! π€
Default behavior is to keep a non-breaking change of all which will listen on IPv4 and IPv6.
π§ββοΈ Quality Of Life Improvements
Improved health checks
A brilliant PR by @aSeriousDeveloper was merged which dramatically improves our "definition of healthy", especially on container start up. This approach utilizes start-period and start-interval which will give us more accurate readings and flexibility for container start up.
| Option | Description | Old Value | New Value |
|---|---|---|---|
| start-period | start period provides initialization time for containers that need time to bootstrap. Probe failure during that period will not be counted towards the maximum number of retries. However, if a health check succeeds during the start period, the container is considered started and all consecutive failures will be counted towards the maximum number of retries. | - | 60s |
| start-interval | start interval is the time between health checks during the start period. | - | 3s |
| timeout | If a single run of the check takes longer than timeout seconds then the check is considered to have failed. | 3s | 3s |
| retries | It takes retries consecutive failures of the health check for the container to be considered unhealthy. |
3 | 3 |
| interval | The health check will first run interval seconds after the container is started, and then again interval seconds after each previous check completes. | 5s | 10s |
Startup and Entrypoint Scripts
- Changed approach to executing
entrypoint.dscripts so we can gracefully handleexit 0in a entrypoint script - Re-designed container start up info script
Changing file permissions (docker-php-serversideup-set-file-permissions)
- Added automated service detection (
--serviceis now optional) - Added
--dirparameter for specifying extra directories (you can specify multiple--dirflags for multiple directories)
Quiet health check access logs
- Improved
fpm-nginxandfpm-apachelogs to never show access log output for any request$HEALTHCHECK_PATH. Things are much quieter now π
π Bug Fixes
All images
- Fixed deprecation notices for
session.sid_bits_per_characterandsession.sid_length(using PHP defaults now) (#560)
S6-based images (fpm-nginx and fpm-apache)
- Re-added
docker-serversideup-php-s6-initback for advanced S6 dependency use cases (#479)
fpm-nginx
- Added
absolute_redirect off;to have redirects return relative redirects (helpful for proxies like Traefik) (#567) - Fixed a bug with
svgzwith Symphony's asset mapper with FPM-NGINX (#530) - Fixed notice of
/package/admin/s6-overlay/libexec/preinit: info: /run belongs to uid X instead of Ywhen using thedocker-php-serversideup-set-file-permisisonsscript on FPM-NGINX Alpine instances
fpm-apache
- Added "Referer" and "User Agent" in Apache access logs (#540)
β« Dependency updates
- Updates
install-php-extensionsscript to v2.9.11
What's Changed
- Add PHP_FPM_PM_MAX_REQUESTS as ENV by @twiesing in #513
- Add environment variable: PHP_MAX_INPUT_VARS by @RadeJR in #500
- Add additional OPCache environment variables by @aSeriousDeveloper in #510
- Refactor Laravel Autorun Script, adjust entrypoint behavior, contianer info improvements by @aSeriousDeveloper in #511
- Adding Cache-Control header to assets and media files by @guillaumebriday in #487
- Add opt-int database seeding support by @DarkGhostHunter in #404
- Add default Caddyfile for FrankenPHP that mimics the FPM-NGINX experience by @hookenz in #527
- Add
NGINX_ACCESS_LOGandNGINX_ERROR_LOGby @robsontenorio in #534 - FEAT: add
NGINX_IP_LISTENING_PROTOCOLby @yuuzukatsu in #539 - feat: allow nginx
client_max_body_sizeto be configurable by @dlundgren in #558 - Move SVG handling to media assets block for Symfony's Asset Mapper compatibility by @ricardomm85 in #530
- introduce start-period and start-interval parameters to HEALTHCHECK by @aSeriousDeveloper in #547
New Contributors
- @twiesing made their first contribution in #513
- @aSeriousDeveloper made their first contribution in #510
- @guillaumebriday made their first contribution in #487
- @DarkGhostHunter made their first contribution in #404
- @hookenz made their first contribution in #527
- @robsontenorio made their first contribution in #534
- @yuuzukatsu made their first contribution in #539
- @dlundgren made their first contribution in #558
- @ricardomm85 made their first contribution in #530
Full Changelog: v3.6.1...v4.0.0-beta1