We needed to patch PHP on Bitnami WordPress after the PHP project disclosed two critical security flaws. Our LinuxBeast site was still running PHP 8.2.16, so we installed patched PHP alongside the existing runtime, tested it, and moved the website over. Here’s what worked, what failed along the way, and what we checked before calling the patch complete.
About downtime: the site kept running during installation and preparation. The final switch involved an Apache restart, and our checks caught connection resets during startup. We didn’t measure the full interruption or prove that no visitors were affected, so this is a controlled-cutover case study, not a zero-downtime claim.
Why this PHP patch mattered
PHP runs WordPress code on the server. The PHP project’s October 21, 2026 security advisory described CVE-2026-109618 and CVE-2026-109619, which can let an attacker run code remotely without logging in. PHP-FPM, the background service handling our PHP requests, was among the affected setups.
For our PHP 8.2 branch, the fixed release was 8.2.35. We stayed on the same branch to reduce compatibility changes during the security patch. These version numbers describe our November 8, 2026 maintenance work; check the current advisory and repository before repeating it.
| Component | Before | After |
|---|---|---|
| Web runtime | Bundled PHP-FPM 8.2.16 | Package-managed PHP-FPM 8.2.35 |
| Command-line PHP | 8.2.16 | 8.2.35 |
| Apache PHP socket | www.sock | ww2.sock |
| Session upload progress | On | Disabled |
What to check before you start
Our server used Debian 11 with the Bitnami Apache, MariaDB, and WordPress stack. Local AWS CLI and SSH commands can run from WSL2 Ubuntu on Windows, the author’s usual workstation setup. Commands that change PHP below run on the remote Debian server, not inside WSL.
- SSH access with sudo permissions and a tested recovery route.
- A completed Lightsail snapshot, plus database and configuration backups.
- Enough disk space and memory to briefly run both PHP services.
- A test instance where you can rehearse your own configuration.
- A short maintenance window for the final web-server switch.
If you need local AWS tooling, start with installing AWS CLI v2 on Ubuntu. Replace instance names, key paths, and domains in the examples with your own values.
How to patch PHP on Bitnami WordPress: our process
1. Check the PHP serving the website
The terminal and website can use different PHP installations. We checked both the command-line binary and PHP-FPM before choosing the patch path.
cat /etc/os-release
/opt/bitnami/php/bin/php -v
sudo /opt/bitnami/php/sbin/php-fpm -v
/opt/bitnami/php/bin/php -m
sudo /opt/bitnami/ctlscript.sh status
df -h /
free -m
The -v flag prints the version; -m lists PHP extensions, which add features such as database connections and image processing. Both binaries reported 8.2.16. We also inspected the running process and Apache routing to confirm that this bundled PHP handled the site.
2. Make a recovery point before changing packages
A snapshot is a recoverable copy of the instance’s disk. We created one and waited until it was available before installing PHP. These AWS commands run from your workstation:
aws lightsail create-instance-snapshot \
--region ap-southeast-1 \
--instance-name YOUR_INSTANCE_NAME \
--instance-snapshot-name YOUR_PRE_PATCH_SNAPSHOT
aws lightsail get-instance-snapshot \
--region ap-southeast-1 \
--instance-snapshot-name YOUR_PRE_PATCH_SNAPSHOT \
--query 'instanceSnapshot.state' \
--output text
The region selects the AWS location; the query prints only the snapshot state. Wait for available. A snapshot restore normally means creating a replacement instance and restoring access or moving its static IP, so it isn’t an instant undo button.
We also exported the database and backed up PHP, Apache, service-monitor settings, and startup hooks in a root-only directory. Our first database export failed because Bitnami’s WP-CLI runs as daemon, which couldn’t write into that directory. Exporting SQL to standard output and having the root shell write the file fixed the permissions issue without opening up the backup folder.
3. Install patched PHP beside the old runtime
Bitnami’s bundled PHP isn’t updated by a normal system package upgrade. We followed AWS’s in-place PHP replacement procedure: install package-managed PHP alongside Bitnami, then point Apache at the new service. AWS also recommends migrating to its maintained Lightsail blueprints as a longer-term option.
For Debian, we used the third-party PHP repository maintained by Ondřej Surý. Follow its official repository setup instructions, including the signed archive keyring. Don’t apply Debian repository commands to Ubuntu or another distribution.
sudo apt-get update
apt-cache policy php8.2-fpm
sudo apt-get install -y --no-install-recommends \
php8.2-fpm php8.2-cli php8.2-mysql php8.2-curl \
php8.2-gd php8.2-mbstring php8.2-xml php8.2-zip \
php8.2-intl php8.2-bcmath php8.2-bz2 php8.2-gmp \
php8.2-ldap php8.2-soap php8.2-sqlite3 php8.2-tidy \
php8.2-imagick php8.2-memcached
/usr/bin/php8.2 -v
Check that the candidate is 8.2.35 or a newer patched 8.2 release before installing. The module list matched our server; yours may differ. --no-install-recommends avoids recommended extras, including an additional Apache package in this setup, and -y accepts package prompts. Review the proposed changes first.
Two Debian dependencies returned 404 errors during our installation. We retrieved the exact security-patched versions from the official Debian snapshot archive and verified their SHA-256 checksums against authenticated APT metadata. We didn’t disable signature checks or substitute older packages. That was a mirror-specific repair, not a step every server should need.
4. Preserve the database connection and PHP settings
A fresh PHP installation doesn’t inherit Bitnami’s settings. We carried over the memory and upload limits, time zone, database socket, and session directory. A socket is a local connection endpoint; choosing the wrong MariaDB socket can break WordPress even when the database is healthy.
These were our site-specific overrides, stored in /etc/php/8.2/fpm/conf.d/99-linuxbeast.ini and the matching CLI directory. Confirm your own paths and limits before using them:
memory_limit = 512M
post_max_size = 80M
upload_max_filesize = 80M
max_execution_time = 30
max_input_time = 60
date.timezone = UTC
mysqli.default_socket = /opt/bitnami/mariadb/tmp/mysql.sock
pdo_mysql.default_socket = /opt/bitnami/mariadb/tmp/mysql.sock
session.save_path = /opt/bitnami/php/var/run/session
session.upload_progress.enabled = 0
Disabling session upload progress also addressed the separate CVE-2026-115560 configuration risk described in PHP’s October 23 advisory. PHP 8.2.35 fixes the original two flaws; it doesn’t by itself fix that third issue. Ordinary file uploads don’t depend on PHP’s session upload-progress tracking.
5. Give the new PHP-FPM its own socket
A PHP-FPM pool groups the worker processes that handle requests. We created a pool running as Bitnami’s daemon user, keeping it separate from the old service:
[bitnami]
user = daemon
group = daemon
listen = /opt/bitnami/php/var/run/ww2.sock
listen.owner = daemon
listen.group = daemon
listen.mode = 0660
pm = dynamic
pm.max_children = 5
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 5000
env[PATH] = /usr/local/bin:/usr/bin:/bin:/opt/bitnami/common/bin:/opt/bitnami/mariadb/bin
We saved this as /etc/php/8.2/fpm/pool.d/bitnami.conf and moved the unused default pool out of the active configuration. The five-worker limit preserved our existing setting; size yours for available memory and traffic. The PATH setting lets workers find system and Bitnami utilities.
sudo /usr/sbin/php-fpm8.2 -t
sudo systemctl enable php8.2-fpm
sudo systemctl restart php8.2-fpm
sudo ls -l /opt/bitnami/php/var/run/ww2.sock
-t validates the configuration. enable configures startup at boot; restart loads the settings. At this point, Apache still used the old socket. We tested WordPress and its database using the new PHP CLI before changing live routing. Our WP-CLI guide explains the command-line tool if you haven’t used it before.
6. Switch Apache with rollback ready
We backed up /opt/bitnami/apache/conf/bitnami/php-fpm.conf, changed its socket reference from www.sock to ww2.sock, validated Apache, and restarted it. Keep the original service available until the replacement passes web checks.
sudo /opt/bitnami/apache/bin/apachectl -t
sudo /opt/bitnami/ctlscript.sh restart apache
Our first verification request arrived before Apache finished starting and got a connection reset. The cutover script restored the previous routing automatically. After checking the Apache logs, we repeated the switch with a bounded readiness retry, and the new runtime passed. This is why a restart command returning successfully isn’t enough to declare the website ready.
7. Verify the runtime through an actual web request
A terminal version check can’t prove that Apache uses the new PHP. We created a temporary, randomly named probe that returned only the version, server interface, configuration path, and upload-progress setting. We requested it through HTTPS with the real hostname pointed at localhost, then removed it.
The actual response confirmed 8.2.35, fpm-fcgi, /etc/php/8.2/fpm/php.ini, and upload progress set to 0. Avoid leaving a public phpinfo() page behind; it exposes much more configuration than this check needs.
for path in / /wp-login.php /wp-json/ /sitemap_index.xml; do
curl --fail --silent --show-error --max-time 30 \
--resolve example.com:443:127.0.0.1 \
"https://example.com$path" \
--output /dev/null --write-out "$path %{http_code}\n" || break
done
Run this on the server with your real domain. --resolve sends requests directly to local Apache while preserving the hostname and TLS certificate checks. --fail reports HTTP errors, and --max-time limits each request. All four paths returned 200 on our site; the sitemap path applies to our Yoast setup.
We also checked the public homepage and login from the server. HTTP 200 confirms a successful response, but it doesn’t prove that login, publishing, uploads, or every plugin works. Those actions and a reboot weren’t tested in this maintenance session. For interpreting failures, see our HTTP status-code guide.
8. Update service monitoring and command-line PHP
We stopped the unused bundled PHP-FPM after the web checks passed. Then we updated Gonit, Bitnami’s service monitor, to manage the systemd service. Its PID file tells the monitor which process to check. The new package didn’t create that file by default, so we set pid = /run/php/php8.2-fpm.pid in the global PHP-FPM configuration and reloaded it.
We also redirected Bitnami’s legacy PHP start/stop hooks to systemd and linked its CLI PHP path to /usr/bin/php8.2, preserving the original files in our backup. That mattered because Bitnami’s WP-CLI wrapper explicitly called the old PHP path. Changing only our shell PATH would have missed it.
sudo /opt/bitnami/ctlscript.sh status
systemctl is-enabled php8.2-fpm
systemctl is-active php8.2-fpm
/opt/bitnami/php/bin/php -v
sudo dpkg --audit
Apache, MariaDB, and PHP-FPM reported running. The patched service was enabled and active, CLI PHP reported 8.2.35, and the package audit reported no incomplete installations. We verified the running FPM executable was /usr/sbin/php-fpm8.2.
What made the patch manageable
Most of the work happened while the existing PHP service continued handling traffic. Preparing a second runtime gave us time to check modules, database access, and configuration before the short cutover. Backups and automatic routing rollback gave us a recovery path when the first readiness check failed.
For a stronger zero-downtime design, use multiple healthy backends behind a load balancer, validate the replacement, and drain existing connections before removing the old backend. A single-server Apache restart doesn’t provide that guarantee.
Conclusion
We patched the live PHP runtime and CLI to 8.2.35, preserved the site’s configuration, and checked WordPress through Apache before stopping the old service. PHP 8.2 reaches upstream end of life on December 31, 2026, so this security fix also needs a follow-up plan for a supported branch. For ongoing recovery preparation, see automating MySQL backups to S3, adapting the connection details to your stack.