From 08f66d7c68e4e34ed0e16c494065cfe1ee2f7140 Mon Sep 17 00:00:00 2001 From: Jay Rogers Date: Thu, 14 May 2026 14:44:21 -0500 Subject: [PATCH 1/2] Update nginx version for Alpine and Debian configurations in php-versions-base-config.yml - Changed nginx version from 1.28.3 to 1.30.1 for Alpine 3.21, 3.22, and 3.23. - Updated nginx version from 1.28.3-1 to 1.30.1-1 for Debian Bullseye, Bookworm, and Trixie. - These updates ensure compatibility with the latest nginx features and security improvements. --- scripts/conf/php-versions-base-config.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/conf/php-versions-base-config.yml b/scripts/conf/php-versions-base-config.yml index 4eb235d6..2e1adf39 100644 --- a/scripts/conf/php-versions-base-config.yml +++ b/scripts/conf/php-versions-base-config.yml @@ -99,27 +99,27 @@ operating_systems: - name: "Alpine 3.21" version: alpine3.21 number: 3.21 - nginx_version: 1.28.3-r1 + nginx_version: 1.30.1-r1 - name: "Alpine 3.22" version: alpine3.22 number: 3.22 - nginx_version: 1.28.3-r1 + nginx_version: 1.30.1-r1 - name: "Alpine 3.23" version: alpine3.23 number: 3.23 - nginx_version: 1.28.3-r1 + nginx_version: 1.30.1-r1 - family: debian default: true versions: - name: "Debian Bullseye" version: bullseye number: 11 - nginx_version: 1.28.3-1~bullseye + nginx_version: 1.30.1-1~bullseye - name: "Debian Bookworm" version: bookworm number: 12 - nginx_version: 1.28.3-1~bookworm + nginx_version: 1.30.1-1~bookworm - name: "Debian Trixie" version: trixie number: 13 - nginx_version: 1.28.3-1~trixie + nginx_version: 1.30.1-1~trixie From b6efc67e8938599c3fa58d3aabf055cc7c6ce033 Mon Sep 17 00:00:00 2001 From: Jay Rogers Date: Thu, 14 May 2026 16:03:44 -0500 Subject: [PATCH 2/2] Enhance security policy and documentation updates - Expanded the SECURITY.md file to clarify the reporting process for vulnerabilities, including what is in and out of scope for reporting. - Added detailed guidelines on how to handle end-of-life (EOL) software and the implications of using EOL operating systems. - Updated the documentation on choosing an image to include notes on floating vs. version-pinned tags, emphasizing the importance of selecting supported OS releases. - Revised the Upgrade Guide to explain the release process and update strategies, ensuring users understand the implications of their choices regarding image tags. --- SECURITY.md | 65 ++-- .../1.getting-started/5.choosing-an-image.md | 15 + .../docs/1.getting-started/7.upgrade-guide.md | 300 +++++------------- .../5.guide/5.major-version-migrations.md | 226 +++++++++++++ 4 files changed, 365 insertions(+), 241 deletions(-) create mode 100644 docs/content/docs/5.guide/5.major-version-migrations.md diff --git a/SECURITY.md b/SECURITY.md index dc4def99..73628be1 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,29 +1,58 @@ # Security Policy -## PHP upstream support (php.net) +`serversideup/php` is a **downstream distributor**. We package PHP, NGINX, Apache, Composer, the base operating system, and related tooling into production-ready Docker images. We do not maintain those upstream projects ourselves — this policy explains what belongs here and what belongs upstream. -The table below is the **official PHP project** support phase for each branch—not a guarantee that every branch appears in our image matrix. Use it to decide when to upgrade. +## Reporting a vulnerability + +For anything in scope below, please use **[GitHub's private vulnerability reporting](https://github.com/serversideup/docker-php/security/advisories/new)** to open a confidential report. Please include: + +- The affected image tag and digest (e.g. `serversideup/php:8.4-fpm-nginx@sha256:…`) +- Steps to reproduce and the impact +- Any suggested mitigation, if you have one + +Do not disclose details publicly (issues, discussions, social media) before a fix is released. + +## What is in scope + +Vulnerabilities in what *we* author and ship: + +- Entrypoint scripts, healthchecks, helper scripts, and S6 service definitions in `src/` +- Default configs we ship for PHP-FPM, NGINX, Apache, and FrankenPHP +- Insecure defaults: ports, file permissions, the `www-data` user model, SSL defaults +- Build pipeline integrity (GitHub Actions workflows, tag assembly, image publishing) +- Documentation that materially misleads users about a security-relevant setting -| Branch | Phase on php.net | +## What is out of scope — report to the upstream project + +Vulnerabilities in software we package but do not maintain belong with the upstream project, not here: + +| Component | Where to report | | --- | --- | -| 8.5 | Active support (bug + security fixes) | -| 8.4 | Active support (bug + security fixes) | -| 8.3 | Security fixes only | -| 8.2 | Security fixes only | -| 8.1 | End of life — upgrade as soon as practical | -| 8.0 | End of life — upgrade as soon as practical | -| 7.4 | End of life — upgrade as soon as practical | -| ≤ 7.3 | End of life — not built in this project’s current matrix | +| PHP itself | [The PHP project](https://www.php.net/) (security mailing list: `security@php.net`) | +| NGINX | [NGINX security advisories](https://nginx.org/en/security_advisories.html) | +| Apache HTTP Server | [Apache HTTPD security](https://httpd.apache.org/security_report.html) | +| Composer | [composer/composer on GitHub](https://github.com/composer/composer/security) | +| Debian / Alpine base packages | The respective distribution security teams | + +If an upstream CVE is already publicly disclosed, you don't need to file with us — we pick up upstream patches on our **weekly rebuilds (Tuesday 08:00 UTC)** for floating tags. See [How our releases work](https://serversideup.net/open-source/docker-php/docs/getting-started/upgrade-guide#how-our-releases-work) for the full cadence and which tags receive rebuilds. -**References** +## Component lifecycle references -- [Supported Versions](https://www.php.net/supported-versions.php) — active and security support dates for current branches -- [End-of-life branches](https://www.php.net/eol.php) — historical EOL dates +Our images bundle third-party software, each with its own support window. Before reporting an issue (or pinning to a particular version), confirm the component is still receiving security fixes from its maintainers: -We may still ship images for **EOL** PHP versions to help migrate legacy apps; prefer a [currently supported branch](https://www.php.net/supported-versions.php) for production. +| Component | Lifecycle reference | +| --- | --- | +| PHP | [endoflife.date/php](https://endoflife.date/php) | +| Debian | [endoflife.date/debian](https://endoflife.date/debian) | +| Alpine Linux | [endoflife.date/alpine-linux](https://endoflife.date/alpine-linux) | +| NGINX | [endoflife.date/nginx](https://endoflife.date/nginx) | +| Apache HTTP Server | [endoflife.date/apache](https://endoflife.date/apache) | +| Composer | [endoflife.date/composer](https://endoflife.date/composer) | ---- +We continue to publish images for end-of-life PHP versions and operating system bases so legacy applications have a path into containers — but those bases will not receive new upstream security fixes. Use them as a stepping stone, not a destination. See [Choosing an image — Operating Systems](https://serversideup.net/open-source/docker-php/docs/getting-started/choosing-an-image#operating-systems) for the trade-off. -## Reporting a vulnerability +## How updates flow + +For the full release model, how floating vs. version-pinned tags behave, and how to apply your own patches to a pinned image, see the [Upgrade Guide](https://serversideup.net/open-source/docker-php/docs/getting-started/upgrade-guide). -Follow [our responsible disclosure policy](https://www.notion.so/Responsible-Disclosure-Policy-421a6a3be1714d388ebbadba7eebbdc8). +For the EOL trade-off when picking an operating system base, see [Choosing an image — Operating Systems](https://serversideup.net/open-source/docker-php/docs/getting-started/choosing-an-image#operating-systems). diff --git a/docs/content/docs/1.getting-started/5.choosing-an-image.md b/docs/content/docs/1.getting-started/5.choosing-an-image.md index 509634d6..3cbb7028 100644 --- a/docs/content/docs/1.getting-started/5.choosing-an-image.md +++ b/docs/content/docs/1.getting-started/5.choosing-an-image.md @@ -61,6 +61,10 @@ Here's what each part means: | `{{operating-system}}`
The operating system to use. | `debian` | `alpine`
`bullseye`
`bookworm`
`trixie` | | `{{github-release-version}}`
The version of the GitHub release to use. | (latest stable release) | See our [GitHub Releases](https://github.com/serversideup/docker-php/releases){target="_blank"} for specific versions. | +::note{title="Floating vs. version-pinned tags"} +Including `{{github-release-version}}` (e.g. `8.4-fpm-nginx-v4.3.5`) creates a **version-pinned tag** that is written once and never updated. Omitting it (e.g. `8.4-fpm-nginx`) gives you a **floating tag** that we rebuild weekly with the latest security patches. The right choice depends on how you balance reproducibility against staying current — see [How our releases work](/docs/getting-started/upgrade-guide#how-our-releases-work) and [Choosing your update strategy](/docs/getting-started/upgrade-guide#choosing-your-update-strategy) in the upgrade guide. +:: + ## PHP version There are many factors to consider when choosing the right PHP version. Best practices include: @@ -127,6 +131,17 @@ Choosing an operating system comes down to a few preferences, but ultimately you | `debian` (default) | Debian is a popular Linux distribution that is known for its stability and reliability. It is the default operating system for our images. | | `alpine` | Alpine is a lightweight Linux distribution that is known for its small size and low resource usage. | +::warning{title="Choose an OS release that's still supported"} +We continue to publish images on end-of-life operating system releases (like Debian Bullseye and Alpine 3.16) so legacy applications can be containerized as a first step. Be aware that EOL bases also ship EOL versions of other software like NGINX and OpenSSL — and no amount of `apt upgrade` will get you newer ones, because the distribution itself has stopped releasing fixes. + +Before picking a base, confirm it's currently supported: + +- [Debian release lifecycle](https://endoflife.date/debian){target="_blank"} +- [Alpine Linux release lifecycle](https://endoflife.date/alpine-linux){target="_blank"} + +If you must start on an EOL base, treat it as a stepping stone. See [EOL versions and the legacy-modernization path](https://github.com/serversideup/docker-php/blob/main/SECURITY.md#eol-versions-and-the-legacy-modernization-path) for the recommended migration approach. +:: + ### Specific versions ::note Not all operating systems are available for all image variations and PHP versions. Double check [Docker Hub](https://hub.docker.com/r/serversideup/php/tags){target="_blank"} and [GitHub Packages](https://github.com/serversideup/docker-php/pkgs/container/php){target="_blank"} for the most accurate list of available tags. diff --git a/docs/content/docs/1.getting-started/7.upgrade-guide.md b/docs/content/docs/1.getting-started/7.upgrade-guide.md index 757848aa..1a50e7d5 100644 --- a/docs/content/docs/1.getting-started/7.upgrade-guide.md +++ b/docs/content/docs/1.getting-started/7.upgrade-guide.md @@ -5,272 +5,126 @@ layout: docs title: Upgrade Guide --- +::lead-p +This guide explains how `serversideup/php` releases work, how to choose an update strategy that fits your environment, and how to apply your own security patches when you need them. Use it to decide whether to ride our floating tags for automatic weekly updates, or pin to a version-pinned release and take responsibility for your own patching — both are valid choices, and the right one depends on how you balance reproducibility against staying current. For crossing a major version boundary (V3 → V4, V2 → V3), see the [Major Version Migrations](/docs/guide/major-version-migrations) guide. +:: + ## Subscribe to repository updates -Regardless if you are choosing to use automatic updates or manual updates, it is highly advised to subscribe to our releases. You can do this through the "Watch" button on our [GitHub](https://github.com/serversideup/docker-php). +Regardless if you are choosing to use floating tags or pinned releases, it is highly advised to subscribe to our releases. You can do this through the "Watch" button on our [GitHub](https://github.com/serversideup/docker-php). ![Watch Repository](images/docs/watch-repo.png){.max-w-md.w-full.h-auto.mx-auto} :u-button{to="https://github.com/serversideup/docker-php" target="_blank" label="Subscribe to our Repo" aria-label="Subscribe to our Repo" size="md" color="primary" variant="outline" trailing-icon="i-lucide-arrow-right" class="font-bold ring ring-inset ring-blue-600 text-blue-600 hover:ring-blue-500 hover:text-blue-500"} -## Choosing an image version +## How our releases work -If you do not select a specific patch version, then you will receive automatic PHP updates. +All source code merges into the `main` branch. A pre-release is created for beta testing. After internal and community testing, we [publish a release on GitHub](https://github.com/serversideup/docker-php/releases) with a detailed changelog. Publishing a release triggers a production build that pushes a new set of tags to Docker Hub and GitHub Packages. -For example, you can select your version based on the different version numbers: -- Major Version (example: `8` will give you the latest 8.x version) -- Minor Version (example: `8.4` will give you the latest 8.4.x version) -- Patch Version (example: `8.4.1` will always stay at the 8.4.1 version) +Production images are also rebuilt **automatically every Tuesday at 08:00 UTC** so floating tags pick up the latest upstream PHP and operating system security patches even when we haven't cut a release that week. -If you use `latest`, you will always get the latest stable version of the CLI variation of PHP. For the best stability in production environments, you may want to pin to a specific patch version (example: `8.4.1`). +### Floating tags vs. version-pinned tags -If you need help choosing an image, see our guide below. +Every production build pushes two kinds of tags for each image in our matrix: -:u-button{to="/docs/getting-started/choosing-an-image" label="Learn more about choosing an image" aria-label="Learn more about choosing an image" size="md" color="primary" variant="outline" trailing-icon="i-lucide-arrow-right" class="font-bold ring ring-inset ring-blue-600 text-blue-600 hover:ring-blue-500 hover:text-blue-500"} +::note{title="Floating tags get updates automatically"} +Tags like `8.4-fpm-nginx`, `8.4-fpm-nginx-bookworm`, and `latest` are **overwritten on every release and every weekly rebuild**. If you use a floating tag, you receive the latest security updates simply by running `docker pull`. +:: -## Release process -All source code is merged into the `main` branch, which automatically build our "beta" images. +::caution{title="Version-pinned tags are immutable"} +Tags that include a release suffix like `8.4-fpm-nginx-v4.3.5` are written **once** and never rebuilt. They stay exactly as they were the day they were published. If you pin to a version-pinned tag, you will **not** receive any future security updates from us — you are responsible for applying your own patches in your downstream image. +:: -After testing the images internally and from other community members, we will [publish a release on GitHub](https://github.com/serversideup/docker-php/releases) with a detailed changelog. +## Choosing your update strategy -## Updating the Docker images on your own -If you You and simply run `apt-get update && apt-get upgrade` within your own image, but still want the image to receive other operating system updates, you will need to run the following commands on your build. +There are two valid ways to consume our images, and the right choice depends on how you balance reproducibility against staying current on security patches. -Any updates that you apply have a risk of breaking other things inside the container. Be sure to have a good testing process in place before applying updates to your production environment. +| Strategy | Example tag | Update behavior | What you are responsible for | +|----------|-------------|-----------------|------------------------------| +| Floating tag *(recommended for simple projects)* | `serversideup/php:8.4-fpm-nginx` | Auto-rebuilt weekly and on every release. `docker pull` brings in the latest patch. | Pulling regularly and testing before promoting to production. | +| Version-pinned release *(recommended for high-volume production environments)* | `serversideup/php:8.4-fpm-nginx-v4.3.5` | Never rebuilt. Stays exactly as published. | All security updates — OS packages, Composer, and any other software inside the image. | -#### Example Dockerfile with manual updates for Debian -```dockerfile [Dockerfile] -FROM serversideup/php:8.4.1-fpm-nginx +For simple deployments, we recommend pinning to a **minor PHP version on a floating tag** like `8.4-fpm-nginx`. This keeps your PHP version stable for compatibility while still receiving weekly security updates from our rebuilds. -RUN apt-get update \ - && apt-get upgrade -y \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/* -``` - -If you're running an Alpine-based image, you can use the following commands: - -#### Example Dockerfile with manual updates for Alpine -```dockerfile [Dockerfile] -FROM serversideup/php:8.4.1-fpm-nginx-alpine +Choose a **version-pinned release** when you need fully reproducible builds — for example, for supply-chain compliance or air-gapped environments — and have a process in place to apply your own updates. See [Applying your own security updates](#applying-your-own-security-updates) for how to do that. -RUN apk update \ - && apk upgrade \ - && rm -rf /var/cache/apk/* -``` - -## Version 3 → Version 4 Migration -Version 3 to Version 4 is a much easier migration compared to previous versions. There are **no breaking changes**, so you can simply update your image tag to the latest version and take advantage of the new features. - -### New Features in Version 4 -This release focused on expanding image variations, improving Laravel automations, and enhancing the developer experience. Here are the key features: - -- **FrankenPHP variation** - A new production-ready FrankenPHP variation with intelligent defaults, flexible environment configuration, native health checks, and support for Debian and Alpine operating systems. -- **Revamped documentation site** - Completely rewritten documentation with improved navigation, better examples, and a modern user experience. -- **Enhanced Laravel automations** - Refactored to use `php artisan optimize` by default (following Laravel best practices), with support for migration modes (`fresh`, `refresh`), database connection selection, seeding options, and easier debugging with `AUTORUN_DEBUG`. -- **Expanded environment variables** - 25+ new environment variables for fine-tuning PHP, NGINX, Apache, and FrankenPHP configurations. [See the full list of environment variables →](/docs/reference/environment-variable-specification) -- **Improved health checks** - Better container startup detection using `start-period` and `start-interval` for more accurate health readings. -- **IPv6 support for NGINX** - Control IP listening protocols with `NGINX_LISTEN_IP_PROTOCOL` (supports `ipv4`, `ipv6`, or `all`). -- **Enhanced file permissions script** - `docker-php-serversideup-set-file-permissions` now includes automated service detection and support for multiple directories with the `--dir` flag. -- **Quieter logs** - Health check requests no longer appear in access logs for `fpm-nginx` and `fpm-apache` variations. - -### Quality of Life Improvements -- **Startup scripts** - Improved handling of `entrypoint.d` scripts with better error handling and a redesigned container startup info display. -- **FPM process control** - Default changed to `ondemand` for even lower resource usage in `fpm-nginx` and `fpm-apache` variations. -- **Better Apache logs** - Access logs now include "Referer" and "User Agent" for better debugging. -- **NGINX improvements** - Added `absolute_redirect off;` for better proxy compatibility, fixed `svgz` handling with Symfony's asset mapper, and allowed `robots.txt` to be dynamically generated by PHP. - -### V4 Migration Checklist -Since there are no breaking changes, the migration is straightforward: - -#### Update Your Images -Simply update your image tags to the latest version. For example: - -```yml [compose.yml] -services: - php: - image: serversideup/php:8.5-fpm-nginx -``` - -No other changes are required unless you want to take advantage of new features. +## Choosing an image version -#### Optional: Leverage New Features +If you do not select a specific patch version, you will receive automatic PHP patch updates through our floating-tag rebuilds. For example: -**Consider enabling Laravel optimizations (if using Laravel):** -```yml [compose.yml] -services: - php: - image: serversideup/php:8.5-fpm-nginx - environment: - AUTORUN_ENABLED: "true" - AUTORUN_LARAVEL_OPTIMIZE: "true" -``` +- Major version (`8`) gives you the latest 8.x release. +- Minor version (`8.4`) gives you the latest 8.4.x release. +- Patch version (`8.4.1`) stays at exactly 8.4.1 — but on a floating tag, you still receive OS package updates on the weekly rebuild. +- Version-pinned (`8.4.1-fpm-nginx-v4.3.5`) is fully frozen. -**Try the new FrankenPHP variation:** -```yml [compose.yml] -services: - php: - image: serversideup/php:8.5-frankenphp - ports: - - 80:8080 - - 443:8443 -``` +If you use `latest`, you will always get the latest stable version of the CLI variation of PHP. -That's it! Version 4 is designed to be a smooth, non-breaking upgrade that gives you more flexibility and features when you need them. +:u-button{to="/docs/getting-started/choosing-an-image" label="Learn more about choosing an image" aria-label="Learn more about choosing an image" size="md" color="primary" variant="outline" trailing-icon="i-lucide-arrow-right" class="font-bold ring ring-inset ring-blue-600 text-blue-600 hover:ring-blue-500 hover:text-blue-500"} -## Version 2 → Version 3 Migration -If you're an existing user of our v2 images, be sure that your current configurations are NOT set to use the latest images. To do this, you can lock your images into the `v2.2.1` tag. This will ensure that you're not automatically upgraded to the v3 images. +## Applying your own security updates -For example, if you are using `8.2-fpm-nginx`, you would change your `compose.yml` file to use the [`v2.2.1`](https://hub.docker.com/r/serversideup/php/tags?page=1&name=2.2.1){target="_blank"} tag: +There are two situations where you may need to apply updates yourself rather than waiting for us to publish a new image: -```yml [compose.yml] {3} -services: - php: - image: serversideup/php:8.2-fpm-nginx - ports: - - 80:80 - volumes: - - .:/var/www/html -``` +1. **You're pinned to a version-pinned tag** (e.g. `-v4.3.5`) for reproducibility, and a CVE has been disclosed since that release was cut. +2. **You're on a floating tag**, but a critical patch has landed upstream and you need it before our next weekly rebuild. -```yml [compose.yml] {3} -services: - php: - image: serversideup/php:8.2-fpm-nginx-v2.2.1 - ports: - - 80:80 - volumes: - - .:/var/www/html -``` +In both cases, you apply updates by extending our image in your own Dockerfile. -All you need to do is add `-v2.2.1` to the end of the image tag. This will ensure that you're not automatically upgraded to the v3 images. - -### New Features in Version 3 -We've been busy overhauling our PHP Docker Images to make them more production-ready and easier to use. Here are some of the new features we've added: -- **Based on official PHP Images** - We're now building an improved developer experience on top of the official PHP Docker images. -- **Unprivileged by default** - We're now running our images as an unprivileged user by default. This is a huge step forward in security and compatibility. -- **PHP 8.4 support** - We're now shipping the latest and greatest. -- **Pin to the exact minor version** - Pin your app to the exact minor version of PHP that you want to use. This means you can pin to `8.2.12` instead of `8.2`. -- **Easier start up script customization** - We now have a folder called `/etc/entrypoint.d` that allows you to easily customize your container with scripts. Just put them in numerical order and we'll execute any shell script you want. No S6 Overlay knowledge required. -- **Expanded Laravel Automations** - We added automations to run `config:cache`, `route:cache`, `view:cache`, `event:cache`, `migrate --force --isolated`, and `storage:link` -- **NGINX Unit Support** - We're offering NGINX Unit as a variation as an alternative to PHP-FPM. This allows you to run PHP applications without the need for a webserver like NGINX or Apache to run with PHP-FPM. -- **Available on GitHub Packages** - We're now publishing our images to GitHub Packages. This means you can use our images without needing to authenticate with Docker Hub. - -### Breaking changes in Version 3 -::caution -The following changes are considered to be "breaking changes" and will require you to make changes to your application. +::warning +Any update you apply carries a risk of breaking the application inside the container. Always test before promoting changes to production. :: -#### Ubuntu is no longer used as a base image -We now use Debian or Alpine as our base OS (because we're using the official PHP images as a base). This is a huge change, but we're confident this will be the best direction moving forward. - -#### `ppa:ondrej/php` is no longer used -Since we're using PHP.net as the "official source of truth" for getting our PHP versions, this means we're also dropping support for the `ppa:ondrej/php` repository. If you're using things like `apt-get install php-redis` you will need to change your method of installing PHP extensions. +### Update operating system packages -[Learn how to install your own PHP extension →](/docs/customizing-the-image/installing-additional-php-extensions) +Our images run as the unprivileged `www-data` user by default, so you need to switch to `root` before running package managers, then switch back. -#### `webuser` is no longer being used -We used to add a user called `webuser` with the UID of `9999` with shell permissions. To increase security, we're now using the `www-data` user and group that is built into the official PHP images. If you have mounted volumes, you will need to `chown` the files to match the ID of the `www-data` user and groups. For Debian, this is `33:33` and for Alpine, this is `82:82`. +For Debian-based images: -#### NGINX and Apache listen on 8080 (HTTP) and 8443 (HTTPS) by default -Our images are now unprivileged by default. This is a major step forward in security and compatibility. Since we are unprivileged by default, we lose the ability to mount on ports less than 1024. If you're using NGINX or Apache, you will need to update your port mappings to use `8080` and `8443` instead of `80` and `443`. - -[Learn more about this change →](/docs/getting-started/default-configurations#unprivileged-by-default) - -#### S6 Overlay is only used in `*-fpm-apache` and `*-fpm-nginx` images -Due to compatibility issues, we only use S6 Overlay in our `*-fpm-apache` and `*-fpm-nginx` images. If you were using S6 Overlay for our other variations (cli, fpm, etc), you will need to migrate your scripts to use the new `/etc/entrypoint.d` folder. - -#### `SSL_MODE` is now set to `off` by default (HTTP only) -Running end-to-end SSL by default created more problems than good. By default, we're now shipping HTTP-only by default with the option for people to turn this on. - -#### `AUTORUN_ENABLED` is now set to `false` by default. -Having this set to "true" by default also created more problems than good. If you want to use any of the Laravel Automation Scripts, be sure to set this to `true`. - -#### MSMTP is no longer included in the images -For security and image size reasons, we removed MSMTP from the images. If you need to send emails, use an external SMTP service like Postmark/Sendgrid/Mailgun. You can also extend the image yourself to include MSMTP specifically for your use case. - -#### Variable deprecations -- `WEB_APP_DIRECTORY` has now been renamed to `APP_BASE_DIR` -- `DEBUG_OUTPUT` has been removed for in favor of `LOG_OUTPUT_LEVEL=debug` -- `PUID` & `PGID` are no longer used because it requires root privileges. See the [new way to set the UID and GID →](/docs/guide/understanding-file-permissions) -- `MSMTP_RELAY_SERVER_HOSTNAME` & `MSMTP_RELAY_SERVER_PORT` are no longer used because MSMTP is no longer included in the images. -- `PHP_POOL_NAME` has been renamed to `PHP_FPM_POOL_NAME` - -### V3 Migration Checklist -Here is a good list to perform the V3 migration. +```dockerfile [Dockerfile] +# 8.4.1 is the PHP version, and 4.3.5 is our GitHub release version +FROM serversideup/php:8.4.1-fpm-nginx-v4.3.5 -#### Repository -- Ensure you're committing to a test environment +USER root +RUN apt-get update \ + && apt-get upgrade -y \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/* +USER www-data +``` -#### Docker Compose -- Update the image name (if applicable) -- Check each environment variable exists and is set to a proper value [See the full list of environment variables →](/docs/reference/environment-variable-specification) -- Ensure you updated the ports to `8080` and `8443` for NGINX, Apache, and Unit -- Consider adding `PHP_OPCACHE_ENABLE=1` to your production environment for increased performance +For Alpine-based images: -#### Dockerfile -- Update the base image name (if applicable) -- Remove any `ppa:ondrej/php` references -- Remove any Ubuntu specific commands -- Ensure all extensions are installed with the `install-php-extensions` command [Learn how to install your own PHP extension →](/docs/customizing-the-image/installing-additional-php-extensions) -- Ensure your `COPY` commands are copying with the correct permissions (i.e. `--chown=www-data:www-data`) +```dockerfile [Dockerfile] +# 8.4.1 is the PHP version, and 4.3.5 is our GitHub release version +FROM serversideup/php:8.4.1-fpm-nginx-alpine-v4.3.5 -#### CI/CD -If you're running `fpm-nginx` (or similar) on a runner that's running as your builds as `root`, you may need to add `user = www-data` and `group = www-data` to your `php-fpm.conf` file so you can bring FPM up correctly. +USER root +RUN apk update \ + && apk upgrade \ + && rm -rf /var/cache/apk/* +USER www-data +``` -If you have to run things as root in CI, you can do this with a multi stage build and set the targets: +### Update Composer +Composer is installed in our images by copying the binary from the [official `composer` Docker image](https://hub.docker.com/_/composer). You can use the same pattern in your own Dockerfile to pull in a newer Composer release without waiting for us to publish a new image: ```dockerfile [Dockerfile] -############################################ -# Base Image -############################################ - -# Learn more about the Server Side Up PHP Docker Images at: -# https://serversideup.net/open-source/docker-php/ -FROM serversideup/php:8.4-fpm-nginx AS base - -## Uncomment if you need to install additional PHP extensions -# USER root -# RUN install-php-extensions bcmath gd - -############################################ -# Development Image -############################################ -FROM base AS development - -# We can pass USER_ID and GROUP_ID as build arguments -# to ensure the www-data user has the same UID and GID -# as the user running Docker. -ARG USER_ID -ARG GROUP_ID - -# Switch to root so we can set the user ID and group ID -USER root -RUN docker-php-serversideup-set-id www-data $USER_ID:$GROUP_ID && \ - docker-php-serversideup-set-file-permissions --owner $USER_ID:$GROUP_ID -USER www-data +# 8.4.1 is the PHP version, and 4.3.5 is our GitHub release version +FROM serversideup/php:8.4.1-cli-v4.3.5 -############################################ -# CI image -############################################ -FROM base AS ci +# Pin Composer to a specific patch for reproducibility, +# or use composer:2 for the latest 2.x release. +COPY --from=composer:2.9.8 /usr/bin/composer /usr/bin/composer +``` -# Sometimes CI images need to run as root -USER root +This works for any of our variations (`cli`, `fpm`, `fpm-apache`, `fpm-nginx`, `frankenphp`). It's the same mechanism we use inside our images, so you're not fighting the base image — you're just upgrading the same file we put there. -############################################ -# Production Image -############################################ -FROM base AS deploy -COPY --chown=www-data:www-data . /var/www/html -USER www-data -``` +::warning{title="NGINX, Apache, and other distro-provided software"} +Web servers like NGINX and Apache are installed from your image's operating system package repositories. Running `apt-get upgrade` or `apk upgrade` only gets you the version your distribution currently ships. If you need a meaningfully newer NGINX — for example, to pick up a CVE fix that's only in a later distribution release — switch the base OS of our image (e.g. from `bullseye` to `bookworm`) or upgrade to a newer `serversideup/php` release. Avoid swapping in upstream `nginx.org` packages, as that can break our integration with PHP-FPM and S6 Overlay. +:: -#### Production/Staging Servers -- Update all host volume file permissions to match the `www-data` UID/GID (`33:33` for Debian, `82:82` for Alpine) [Learn how to manage file permissions](/docs/guide/understanding-file-permissions) -- If you're running Docker Swarm with host volume mounts, we created a script that could potentially help ([change-volume-permissions.sh](https://github.com/serversideup/docker-volume-change-permission-script)) +## Migrating between major versions -#### Deployment -- CI/CD with valid tests is always encouraged -- After completing all steps above, you're now ready to deploy the new images +Crossing a major version boundary — like V3 → V4 or V2 → V3 — is a separate concern from day-to-day upgrades. We track breaking changes, new features, and step-by-step checklists for each major release in a dedicated guide. +:u-button{to="/docs/guide/major-version-migrations" label="Read the major version migration guide" aria-label="Read the major version migration guide" size="md" color="primary" variant="outline" trailing-icon="i-lucide-arrow-right" class="font-bold ring ring-inset ring-blue-600 text-blue-600 hover:ring-blue-500 hover:text-blue-500"} diff --git a/docs/content/docs/5.guide/5.major-version-migrations.md b/docs/content/docs/5.guide/5.major-version-migrations.md new file mode 100644 index 00000000..06ef3fec --- /dev/null +++ b/docs/content/docs/5.guide/5.major-version-migrations.md @@ -0,0 +1,226 @@ +--- +head.title: 'Major version migrations - Docker PHP - Server Side Up' +description: 'Step-by-step guides for migrating between major versions of the serversideup/php Docker images.' +layout: docs +title: Major version migrations +--- + +::lead-p +When we ship a new major version of `serversideup/php`, we collect the breaking changes, new features, and migration checklists in this guide. Use it whenever you're crossing a major version boundary — for example, V3 → V4 or V2 → V3. For day-to-day patches and security updates, see the [Upgrade Guide](/docs/getting-started/upgrade-guide) instead. +:: + +## Version 3 → Version 4 Migration +Version 3 to Version 4 is a much easier migration compared to previous versions. There are **no breaking changes**, so you can simply update your image tag to the latest version and take advantage of the new features. + +### New Features in Version 4 +This release focused on expanding image variations, improving Laravel automations, and enhancing the developer experience. Here are the key features: + +- **FrankenPHP variation** - A new production-ready FrankenPHP variation with intelligent defaults, flexible environment configuration, native health checks, and support for Debian and Alpine operating systems. +- **Revamped documentation site** - Completely rewritten documentation with improved navigation, better examples, and a modern user experience. +- **Enhanced Laravel automations** - Refactored to use `php artisan optimize` by default (following Laravel best practices), with support for migration modes (`fresh`, `refresh`), database connection selection, seeding options, and easier debugging with `AUTORUN_DEBUG`. +- **Expanded environment variables** - 25+ new environment variables for fine-tuning PHP, NGINX, Apache, and FrankenPHP configurations. [See the full list of environment variables →](/docs/reference/environment-variable-specification) +- **Improved health checks** - Better container startup detection using `start-period` and `start-interval` for more accurate health readings. +- **IPv6 support for NGINX** - Control IP listening protocols with `NGINX_LISTEN_IP_PROTOCOL` (supports `ipv4`, `ipv6`, or `all`). +- **Enhanced file permissions script** - `docker-php-serversideup-set-file-permissions` now includes automated service detection and support for multiple directories with the `--dir` flag. +- **Quieter logs** - Health check requests no longer appear in access logs for `fpm-nginx` and `fpm-apache` variations. + +### Quality of Life Improvements +- **Startup scripts** - Improved handling of `entrypoint.d` scripts with better error handling and a redesigned container startup info display. +- **FPM process control** - Default changed to `ondemand` for even lower resource usage in `fpm-nginx` and `fpm-apache` variations. +- **Better Apache logs** - Access logs now include "Referer" and "User Agent" for better debugging. +- **NGINX improvements** - Added `absolute_redirect off;` for better proxy compatibility, fixed `svgz` handling with Symfony's asset mapper, and allowed `robots.txt` to be dynamically generated by PHP. + +### V4 Migration Checklist +Since there are no breaking changes, the migration is straightforward: + +#### Update Your Images +Simply update your image tags to the latest version. For example: + +```yml [compose.yml] +services: + php: + image: serversideup/php:8.5-fpm-nginx +``` + +No other changes are required unless you want to take advantage of new features. + +#### Optional: Leverage New Features + +**Consider enabling Laravel optimizations (if using Laravel):** +```yml [compose.yml] +services: + php: + image: serversideup/php:8.5-fpm-nginx + environment: + AUTORUN_ENABLED: "true" + AUTORUN_LARAVEL_OPTIMIZE: "true" +``` + +**Try the new FrankenPHP variation:** +```yml [compose.yml] +services: + php: + image: serversideup/php:8.5-frankenphp + ports: + - 80:8080 + - 443:8443 +``` + +That's it! Version 4 is designed to be a smooth, non-breaking upgrade that gives you more flexibility and features when you need them. + +## Version 2 → Version 3 Migration +If you're an existing user of our v2 images, be sure that your current configurations are NOT set to use the latest images. To do this, you can lock your images into the `v2.2.1` tag. This will ensure that you're not automatically upgraded to the v3 images. + +For example, if you are using `8.2-fpm-nginx`, you would change your `compose.yml` file to use the [`v2.2.1`](https://hub.docker.com/r/serversideup/php/tags?page=1&name=2.2.1){target="_blank"} tag: + +```yml [compose.yml] {3} +services: + php: + image: serversideup/php:8.2-fpm-nginx + ports: + - 80:80 + volumes: + - .:/var/www/html +``` + +```yml [compose.yml] {3} +services: + php: + image: serversideup/php:8.2-fpm-nginx-v2.2.1 + ports: + - 80:80 + volumes: + - .:/var/www/html +``` + +All you need to do is add `-v2.2.1` to the end of the image tag. This will ensure that you're not automatically upgraded to the v3 images. + +### New Features in Version 3 +We've been busy overhauling our PHP Docker Images to make them more production-ready and easier to use. Here are some of the new features we've added: +- **Based on official PHP Images** - We're now building an improved developer experience on top of the official PHP Docker images. +- **Unprivileged by default** - We're now running our images as an unprivileged user by default. This is a huge step forward in security and compatibility. +- **PHP 8.4 support** - We're now shipping the latest and greatest. +- **Pin to the exact minor version** - Pin your app to the exact minor version of PHP that you want to use. This means you can pin to `8.2.12` instead of `8.2`. +- **Easier start up script customization** - We now have a folder called `/etc/entrypoint.d` that allows you to easily customize your container with scripts. Just put them in numerical order and we'll execute any shell script you want. No S6 Overlay knowledge required. +- **Expanded Laravel Automations** - We added automations to run `config:cache`, `route:cache`, `view:cache`, `event:cache`, `migrate --force --isolated`, and `storage:link` +- **NGINX Unit Support** - We're offering NGINX Unit as a variation as an alternative to PHP-FPM. This allows you to run PHP applications without the need for a webserver like NGINX or Apache to run with PHP-FPM. +- **Available on GitHub Packages** - We're now publishing our images to GitHub Packages. This means you can use our images without needing to authenticate with Docker Hub. + +### Breaking changes in Version 3 +::caution +The following changes are considered to be "breaking changes" and will require you to make changes to your application. +:: + +#### Ubuntu is no longer used as a base image +We now use Debian or Alpine as our base OS (because we're using the official PHP images as a base). This is a huge change, but we're confident this will be the best direction moving forward. + +#### `ppa:ondrej/php` is no longer used +Since we're using PHP.net as the "official source of truth" for getting our PHP versions, this means we're also dropping support for the `ppa:ondrej/php` repository. If you're using things like `apt-get install php-redis` you will need to change your method of installing PHP extensions. + +[Learn how to install your own PHP extension →](/docs/customizing-the-image/installing-additional-php-extensions) + +#### `webuser` is no longer being used +We used to add a user called `webuser` with the UID of `9999` with shell permissions. To increase security, we're now using the `www-data` user and group that is built into the official PHP images. If you have mounted volumes, you will need to `chown` the files to match the ID of the `www-data` user and groups. For Debian, this is `33:33` and for Alpine, this is `82:82`. + +#### NGINX and Apache listen on 8080 (HTTP) and 8443 (HTTPS) by default +Our images are now unprivileged by default. This is a major step forward in security and compatibility. Since we are unprivileged by default, we lose the ability to mount on ports less than 1024. If you're using NGINX or Apache, you will need to update your port mappings to use `8080` and `8443` instead of `80` and `443`. + +[Learn more about this change →](/docs/getting-started/default-configurations#unprivileged-by-default) + +#### S6 Overlay is only used in `*-fpm-apache` and `*-fpm-nginx` images +Due to compatibility issues, we only use S6 Overlay in our `*-fpm-apache` and `*-fpm-nginx` images. If you were using S6 Overlay for our other variations (cli, fpm, etc), you will need to migrate your scripts to use the new `/etc/entrypoint.d` folder. + +#### `SSL_MODE` is now set to `off` by default (HTTP only) +Running end-to-end SSL by default created more problems than good. By default, we're now shipping HTTP-only by default with the option for people to turn this on. + +#### `AUTORUN_ENABLED` is now set to `false` by default. +Having this set to "true" by default also created more problems than good. If you want to use any of the Laravel Automation Scripts, be sure to set this to `true`. + +#### MSMTP is no longer included in the images +For security and image size reasons, we removed MSMTP from the images. If you need to send emails, use an external SMTP service like Postmark/Sendgrid/Mailgun. You can also extend the image yourself to include MSMTP specifically for your use case. + +#### Variable deprecations +- `WEB_APP_DIRECTORY` has now been renamed to `APP_BASE_DIR` +- `DEBUG_OUTPUT` has been removed for in favor of `LOG_OUTPUT_LEVEL=debug` +- `PUID` & `PGID` are no longer used because it requires root privileges. See the [new way to set the UID and GID →](/docs/guide/understanding-file-permissions) +- `MSMTP_RELAY_SERVER_HOSTNAME` & `MSMTP_RELAY_SERVER_PORT` are no longer used because MSMTP is no longer included in the images. +- `PHP_POOL_NAME` has been renamed to `PHP_FPM_POOL_NAME` + +### V3 Migration Checklist +Here is a good list to perform the V3 migration. + +#### Repository +- Ensure you're committing to a test environment + +#### Docker Compose +- Update the image name (if applicable) +- Check each environment variable exists and is set to a proper value [See the full list of environment variables →](/docs/reference/environment-variable-specification) +- Ensure you updated the ports to `8080` and `8443` for NGINX, Apache, and Unit +- Consider adding `PHP_OPCACHE_ENABLE=1` to your production environment for increased performance + +#### Dockerfile +- Update the base image name (if applicable) +- Remove any `ppa:ondrej/php` references +- Remove any Ubuntu specific commands +- Ensure all extensions are installed with the `install-php-extensions` command [Learn how to install your own PHP extension →](/docs/customizing-the-image/installing-additional-php-extensions) +- Ensure your `COPY` commands are copying with the correct permissions (i.e. `--chown=www-data:www-data`) + +#### CI/CD +If you're running `fpm-nginx` (or similar) on a runner that's running as your builds as `root`, you may need to add `user = www-data` and `group = www-data` to your `php-fpm.conf` file so you can bring FPM up correctly. + +If you have to run things as root in CI, you can do this with a multi stage build and set the targets: + + +```dockerfile [Dockerfile] +############################################ +# Base Image +############################################ + +# Learn more about the Server Side Up PHP Docker Images at: +# https://serversideup.net/open-source/docker-php/ +FROM serversideup/php:8.4-fpm-nginx AS base + +## Uncomment if you need to install additional PHP extensions +# USER root +# RUN install-php-extensions bcmath gd + +############################################ +# Development Image +############################################ +FROM base AS development + +# We can pass USER_ID and GROUP_ID as build arguments +# to ensure the www-data user has the same UID and GID +# as the user running Docker. +ARG USER_ID +ARG GROUP_ID + +# Switch to root so we can set the user ID and group ID +USER root +RUN docker-php-serversideup-set-id www-data $USER_ID:$GROUP_ID && \ + docker-php-serversideup-set-file-permissions --owner $USER_ID:$GROUP_ID +USER www-data + +############################################ +# CI image +############################################ +FROM base AS ci + +# Sometimes CI images need to run as root +USER root + +############################################ +# Production Image +############################################ +FROM base AS deploy +COPY --chown=www-data:www-data . /var/www/html +USER www-data +``` + +#### Production/Staging Servers +- Update all host volume file permissions to match the `www-data` UID/GID (`33:33` for Debian, `82:82` for Alpine) [Learn how to manage file permissions](/docs/guide/understanding-file-permissions) +- If you're running Docker Swarm with host volume mounts, we created a script that could potentially help ([change-volume-permissions.sh](https://github.com/serversideup/docker-volume-change-permission-script)) + +#### Deployment +- CI/CD with valid tests is always encouraged +- After completing all steps above, you're now ready to deploy the new images