Upgrade Guide
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 guide.
Subscribe to repository updates
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.

How our releases work
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 with a detailed changelog. Publishing a release triggers a production build that pushes a new set of tags to Docker Hub and GitHub Packages.
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.
Floating tags vs. version-pinned tags
Every production build pushes two kinds of tags for each image in our matrix:
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.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.Choosing your update strategy
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.
| 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. |
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.
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 for how to do that.
Choosing an image version
If you do not select a specific patch version, you will receive automatic PHP patch updates through our floating-tag rebuilds. For example:
- 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.
If you use latest, you will always get the latest stable version of the CLI variation of PHP.
Applying your own security updates
There are two situations where you may need to apply updates yourself rather than waiting for us to publish a new image:
- 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. - You're on a floating tag, but a critical patch has landed upstream and you need it before our next weekly rebuild.
In both cases, you apply updates by extending our image in your own Dockerfile.
Update operating system packages
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.
For Debian-based images:
# 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
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
For Alpine-based images:
# 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
USER root
RUN apk update \
&& apk upgrade \
&& rm -rf /var/cache/apk/*
USER www-data
Update Composer
Composer is installed in our images by copying the binary from the official composer Docker image. 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:
# 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
# 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
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.
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.Migrating between major versions
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.
Read the major version migration guide