Php

Install PHP 8.5 on Linux Mint 22

Linux Mint 22 ships PHP 8.3 in its default repositories. That is fine for plenty of work, but if you want PHP 8.5, the current stable release with the pipe operator, a built-in URI parser, and faster execution, you add one repository. The only Linux Mint specific detail worth knowing is the release codename, and this guide handles it so the install does not stall halfway.

Original content from computingforgeeks.com - post 7394

Installing PHP 8.5 on Linux Mint comes down to the OndΕ™ej SurΓ½ PPA, the same archive Ubuntu admins rely on. Mint 22 is built on Ubuntu 24.04, so the packages are byte-for-byte identical. The thing to get right is that the PPA publishes against Ubuntu codenames, and Mint uses its own. Modern Mint tooling resolves that for you, but it is the first thing to check when something breaks.

Screens and the codename check come from a fresh Linux Mint 22.3 (Zena) install in June 2026, and in October 2026 we re-ran the install and the PHP2Shell check against the noble PPA packages Mint 22 uses (PHP 8.5.12 on Ubuntu 24.04). The same steps apply to Linux Mint 22, 22.1, and 22.2, and the package names match the PHP 8.5 setup on Ubuntu 24.04 since both share the noble base.

What follows is the PPA setup with the codename check, the PHP 8.5 install with the extensions real applications need, PHP-FPM for Nginx and mod_php for Apache, a production php.ini, and running PHP 8.5 next to an older version on the same machine.

What PHP version Linux Mint ships

Before adding anything, check what the base system offers. The Mint repositories inherit Ubuntu 24.04’s package set, which tops out at PHP 8.3:

apt-cache policy php

The candidate version comes straight from the Ubuntu archive that Mint is built on:

php:
  Installed: (none)
  Candidate: 2:8.3+93ubuntu2
  Version table:
     2:8.3+93ubuntu2 500

PHP 8.3 is in security support until the end of 2027, so it is a reasonable choice for a stable box. But 8.5 is where active development sits, and new framework releases increasingly require it. Pulling 8.5 means stepping outside the Mint repos, and the cleanest way to do that is the OndΕ™ej SurΓ½ PPA.

Update Linux Mint

Refresh the package index and apply pending updates so the new repository resolves against a current system:

sudo apt update
sudo apt full-upgrade -y

If the kernel or core libraries change here, reboot before continuing. A half-upgraded system is the most common cause of dependency errors later in the install.

Add the OndΕ™ej SurΓ½ PHP PPA

Install the tooling that manages PPAs, then add the repository:

sudo apt install -y software-properties-common
sudo add-apt-repository -y ppa:ondrej/php

You’ll see a notice that the PPA is being merged into packages.sury.org. That move covers Ubuntu 26.04 first, and the PPA still serves noble builds, so Mint 22 keeps using it as shown here.

Here is the Mint detail. The PPA only publishes for Ubuntu codenames, and Mint 22.3 calls itself zena while its Ubuntu base is noble. On our Mint 22.3 test in June 2026, add-apt-repository wrote the noble suite on its own, but it is the first thing to confirm:

cat /etc/apt/sources.list.d/ondrej-php-noble.list

On that June Mint box the file held one line, and the part that matters is noble, not your Mint codename:

deb [signed-by=/etc/apt/keyrings/ondrej-php-noble.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main

On a plain Ubuntu 24.04 box, add-apt-repository writes a deb822 file named ondrej-ubuntu-php-noble.sources instead, so if the .list file is missing, run grep -r ondrej /etc/apt/sources.list.d/ and check that its Suites: line reads noble. If instead you see your Mint codename in that file, or you added the repository by hand on an older release, the suite will be wrong and the next step fails with a 404. The fix is one sed; the Troubleshooting section at the end covers it. With the suite correct, refresh the index:

sudo apt update

Look for the PPA’s noble pocket in the output. The line number varies from box to box; this one is from the October rerun on Ubuntu 24.04:

Hit:4 https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble InRelease

PHP 8.5 is now a candidate alongside the Mint packages. The same archive carries Debian builds too, so the approach mirrors the PHP 8.5 install on Debian; only RHEL rebuilds diverge, where you would follow the Rocky and AlmaLinux route through Remi instead.

Install PHP 8.5 on Linux Mint

Install the core interpreter and the command-line binary:

sudo apt install -y php8.5 php8.5-cli php8.5-common

The php8.5 metapackage also pulls in Apache and libapache2-mod-php8.5, and on a fresh system Apache is running on port 80 as soon as the install finishes. If you only want the CLI, or plan to run PHP-FPM behind Nginx, install php8.5-cli php8.5-common php8.5-fpm instead of php8.5, and Apache isn’t pulled in. Confirm the binary:

php -v

Note that OPcache is compiled in and already loaded, no separate package required:

PHP 8.5.12 (cli) (built: Oct 21 2026 14:37:30) (NTS)
Copyright (c) The PHP Group
Built by Ubuntu
Zend Engine v4.5.12, Copyright (c) Zend Technologies
    with Zend OPcache v8.5.12, Copyright (c), by Zend Technologies

That is the interpreter and CLI working. Applications need database drivers and string handling on top, which the PPA ships as separate packages.

Install the PHP 8.5 extensions you need

A bare interpreter runs code but not much else. Database drivers, string handling, and image support all live in separate packages. This set covers what most web applications, WordPress, Laravel, Symfony and the like, actually depend on:

sudo apt install -y \
  php8.5-mysql php8.5-pgsql php8.5-curl php8.5-gd \
  php8.5-mbstring php8.5-xml php8.5-zip php8.5-intl \
  php8.5-bcmath php8.5-soap php8.5-readline

One trap here. There is no php8.5-opcache package; OPcache ships inside php8.5-common. Asking apt for it aborts the whole transaction with “Unable to locate package”, which makes it look like none of the extensions installed. Leave it out. A few genuine extras are worth adding depending on the workload:

sudo apt install -y php8.5-apcu php8.5-redis php8.5-imagick

php8.5-apcu gives a fast in-memory user cache, php8.5-redis covers session storage and queues, and php8.5-imagick handles image processing beyond what GD offers. Every package in the PPA is named php8.5-*, so when an application’s docs list an extension you do not have, the package name is predictable. List the full set with apt-cache search php8.5- | sort.

Verify PHP 8.5 on Linux Mint

Two commands confirm the install. The version string proves which interpreter the CLI resolves to, and php -m lists every compiled and loaded module:

php -v
php -m

The module list should include curl, gd, intl, mbstring, mysqli, redis, and Zend OPcache. A missing entry means its package didn’t install, so rerun the extension line and read apt’s error.

That is a working PHP 8.5 command line. Before it serves any web traffic, confirm the build carries the October 2026 security fixes.

Check the build for PHP2Shell (CVE-2026-109618, CVE-2026-109619)

PHP2Shell is the name for two critical bugs in PHP itself, CVE-2026-109618 and CVE-2026-109619, both rated CVSS 9.2 and both exploitable for remote code execution over an ordinary HTTP request. PHP fixed them on 21 October 2026 in 8.5.12, 8.4.27, 8.3.36 and 8.2.35, per the PHP security advisory, and the noble PPA builds that Mint 22 installs already carry the fix. A fresh install from this guide is patched. A box you set up before 21 October isn’t, until you upgrade it.

On 22 October 2026 the PPA’s noble builds of the supported branches and of its legacy branches all named both CVE IDs in their changelog:

  • php8.5 8.5.12, php8.4 8.4.27, php8.3 8.3.36 and php8.2 8.2.35
  • php8.1 8.1.34-9, php8.0 1:8.0.30-25 and php7.4 1:7.4.33-31
  • php7.3 7.3.33-35, php7.0 7.0.33-92 and php5.6 5.6.40-105

The one exception is the php8.6 release candidate (8.6.0~rc3), which predates the fix, so keep it off anything that faces the internet. The legacy branches keep their old upstream version and only bump the package release, so php -v doesn’t prove anything on them. The changelog does, on every branch. Check the installed package and grep its changelog for the two CVE IDs:

dpkg-query -W php8.5-common
zgrep -E 'CVE-2026-10961[89]' /usr/share/doc/php8.5-common/changelog.Debian.gz

A patched system shows the 8.5.12 package and a changelog line naming both CVEs. If zgrep prints nothing, your build predates the patch:

php8.5-common	8.5.12-1+ubuntu24.04.1+deb.sury.org+1
   + (CVE-2026-109618, CVE-2026-109619): Avoid state corruption via

On a fresh install that output is the end of the job, so carry on with the web server sections below. The rest of this section is for an existing server that was installed before 21 October. Upgrade it in place. The Apache module is named libapache2-mod-php8.5, which the php8.5* glob misses, so it goes on the line explicitly. Repeat with 'php8.4*' and libapache2-mod-php8.4 for any other branch you keep:

sudo apt update
sudo apt install --only-upgrade 'php8.5*' libapache2-mod-php8.5

Don’t count on the package scripts to restart what’s running. Restart only the services that exist on that server: php8.5-fpm if you run PHP-FPM, apache2 if Apache serves PHP through mod_php, or both. Then check that each came up after the upgrade:

sudo systemctl restart php8.5-fpm
systemctl show -p ActiveEnterTimestamp php8.5-fpm
grep ' upgrade php8.5-common' /var/log/dpkg.log | tail -1

The last line prints when apt replaced the package, and the timestamp above it must be later. Our lab build was already patched, so its upgrade was a no-op and only the restart time is real:

ActiveEnterTimestamp=Thu 2026-10-22 15:34:54 UTC

For mod_php, run the same two commands against apache2 instead. Then ask the web server which build answers, because php -v only proves the CLI binary while your site runs inside the FPM pool or an Apache child:

echo '<?php echo PHP_VERSION, " ", PHP_SAPI, PHP_EOL;' | sudo tee /var/www/html/version.php >/dev/null
curl -s http://localhost/version.php
sudo rm /var/www/html/version.php

Through Nginx or Apache with PHP-FPM, the page reports the patched build and the FPM SAPI:

8.5.12 fpm-fcgi

Through Apache with mod_php, the same probe printed the Apache handler instead:

8.5.12 apache2handler

On the 8.1 and older branches the version in that output doesn’t change after the upgrade, which is why the restart timestamp matters there. Older Mint releases differ. Mint 21 pulls the jammy PPA builds, which carry the same fixes, but Mint 20 sits on focal and the PPA no longer publishes any packages for it, while the focal archive’s own PHP 7.4 gets the fix only through Ubuntu Pro, so there is no free patched PHP there; move that machine up to Mint 22, where the upgrade from Mint 21 is the last hop. With a patched build confirmed, hand requests to it from a web server, and Apache is the quickest way to prove that works.

Run PHP 8.5 with Apache

Linux Mint does not install a web server by default. For a quick local setup, Apache with the PHP module is the least fuss, since the php8.5 metapackage already pulled in libapache2-mod-php8.5. Install Apache and make sure the module is the active handler:

sudo apt install -y apache2 libapache2-mod-php8.5
sudo a2enmod php8.5
sudo systemctl restart apache2

Drop a small probe file into the web root to confirm Apache hands .php requests to the interpreter rather than serving them as plain text:

echo "<?php phpinfo();" | sudo tee /var/www/html/info.php

Open http://localhost/info.php in the Mint browser. The PHP 8.5 information page renders, with the Server API line reading Apache 2 Handler and the System line showing your Mint kernel. This capture is from the June 2026 Mint test, so it shows the pre-patch 8.5.6 build; a current install reports 8.5.12 or later:

June 2026 phpinfo capture in Firefox showing PHP 8.5.6, a pre-PHP2Shell build, served by Apache on Linux Mint 22.3

Delete the probe once it works. A public phpinfo() page leaks your exact configuration to anyone who finds it:

sudo rm /var/www/html/info.php

The Apache module is convenient, but it ties PHP to the web server process and does not scale as well as a separate pool. For anything beyond a local dev box, run PHP-FPM instead.

Set up PHP-FPM

PHP-FPM runs the interpreter as its own service and talks to the web server over a socket. It is the standard for production and the only sensible choice with Nginx. Install it and start the service:

sudo apt install -y php8.5-fpm
sudo systemctl enable --now php8.5-fpm
systemctl status php8.5-fpm --no-pager

The service should report active and ready to handle connections:

● php8.5-fpm.service - The PHP 8.5 FastCGI Process Manager
     Loaded: loaded (/usr/lib/systemd/system/php8.5-fpm.service; enabled; preset: enabled)
     Active: active (running) since Thu 2026-10-22 15:19:36 UTC; 2s ago
       Docs: man:php-fpm8.5(8)
   Main PID: 16429 (php-fpm8.5)
     Status: "Ready to handle connections"

The socket path is the one value you reference everywhere else. Confirm it exists before wiring up a web server:

ls -l /run/php/php8.5-fpm.sock

It is owned by www-data and lives at /run/php/php8.5-fpm.sock.

If Apache is still running with mod_php, switch it to the FPM pool so the two don’t both handle PHP. Disabling the module alone isn’t enough: Apache then serves your .php files as plain text, source included, because the FPM package doesn’t enable its Apache config. All four steps go together:

sudo a2dismod php8.5 && sudo a2enmod proxy_fcgi setenvif && sudo a2enconf php8.5-fpm && sudo systemctl restart apache2

After the restart, the version probe from the PHP2Shell section reports fpm-fcgi through Apache. Skip this if you are moving to Nginx in the next step, since that disables Apache anyway.

Wire PHP-FPM into Nginx

If you prefer Nginx, point a server block at the FPM socket. If you installed the php8.5 metapackage, Apache is already running on port 80 at this point because the metapackage pulled it in, and Nginx can’t bind a port Apache holds: its package installs fine but the service lands in a failed state and the reload below errors with “nginx.service is not active, cannot reload”. Stop and disable Apache first, then install Nginx and edit the default site. If you took the php8.5-cli php8.5-common php8.5-fpm path, Apache was never installed, so skip the first line:

sudo systemctl disable --now apache2
sudo apt install -y nginx
sudo nano /etc/nginx/sites-available/default

Inside the server block, list index.php first so PHP front controllers load ahead of static index files, then add a location that forwards PHP to the socket:

index index.php index.html index.htm;

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.5-fpm.sock;
}

Test the configuration and reload. A clean syntax check is the difference between a reload and an outage:

sudo nginx -t
sudo systemctl reload nginx

Requests for .php files now reach the 8.5 pool through Nginx. For a full virtual host with logging, gzip, and a real document root, the dedicated Nginx with PHP-FPM walkthrough picks up where this leaves off, and it is the same socket a WordPress install on Mint talks to.

Tune php.ini for production

The defaults are conservative. PHP-FPM, the CLI, and Apache each read a separate php.ini, and editing the wrong one is a classic time sink. Ask PHP which file the CLI loads, then look at the directory layout:

php --ini | grep "Loaded Configuration"
ls /etc/php/8.5/

The CLI loads /etc/php/8.5/cli/php.ini, and the directory holds separate cli, fpm, and apache2 trees:

Loaded Configuration File:         "/etc/php/8.5/cli/php.ini"
apache2  cli  fpm  mods-available

For a web application, edit the FPM copy at /etc/php/8.5/fpm/php.ini. The settings worth changing on most servers:

memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 120
cgi.fix_pathinfo = 0
date.timezone = Africa/Nairobi

opcache.enable = 1
opcache.memory_consumption = 192
opcache.max_accelerated_files = 20000
opcache.validate_timestamps = 1

Match memory_limit and the upload sizes to the application; WordPress media or a Laravel queue worker wants more headroom than a static site. Setting cgi.fix_pathinfo to 0 stops PHP from guessing a script out of PATH_INFO, which is how an uploaded image could get run as PHP. Leave opcache.validate_timestamps on while developing so code changes take effect, and turn it off on a release-only server for a measurable speed gain. Apply the changes by reloading FPM:

sudo systemctl reload php8.5-fpm

FPM re-reads its configuration on reload, so the new limits apply without dropping active connections. When something does misbehave, the errors below cover what usually goes wrong on Mint.

Troubleshooting

404 Not Found on a zena or wilma Release file

The PPA was added with Mint’s codename instead of the Ubuntu base. Launchpad publishes for noble, not zena or wilma. Rewrite the suite and update again:

grep -rl ondrej /etc/apt/sources.list.d/
sudo sed -i 's/zena/noble/g' $(grep -rl ondrej /etc/apt/sources.list.d/)
sudo apt update

Substitute your own codename if it is not zena; check it with lsb_release -cs, and confirm the Ubuntu base with grep UBUNTU_CODENAME /etc/os-release.

E: Unable to locate package php8.5

apt cannot see the PPA. Either the repository was not added, or the apt update after adding it failed. Re-run the update and read the output for errors, then confirm the package is visible with apt-cache policy php8.5.

E: Unable to locate package php8.5-opcache

There is no such package. OPcache is built into php8.5-common and is already active, as the php -v output shows. Drop it from the install line. Because apt aborts the whole command on one missing package, this single mistake can make it look like every extension failed to install.

PHP code shows as plain text in the browser

The web server is serving .php files instead of executing them. On Apache with PHP-FPM, usually after a2dismod php8.5 on its own, the FPM handler was never enabled; turn it on with the command below. Only re-enable mod_php (sudo a2enmod php8.5 and a restart) if you meant to run mod_php.

sudo a2enmod proxy_fcgi setenvif && sudo a2enconf php8.5-fpm && sudo systemctl restart apache2

Reload the page afterwards and it should render instead of showing source. On Nginx, the location ~ \.php$ block is missing or the fastcgi_pass socket path is wrong.

502 Bad Gateway from Nginx

Nginx cannot reach the FPM socket. The path in fastcgi_pass must match the running service exactly. Check it with ls /run/php/; a PHP 8.5 pool listens on php8.5-fpm.sock, not the unversioned php-fpm.sock that some older guides reference.

Run multiple PHP versions side by side

The real payoff of the PPA is keeping more than one PHP version installed at once. Install an older line next to 8.5:

sudo apt install -y php8.4 php8.4-cli php8.4-fpm

Both FPM pools run at the same time, each on its own socket, so different sites on the same box can target different versions in their Nginx blocks:

ls /run/php/*.sock

Both pools are listening, each on its own versioned socket:

/run/php/php8.4-fpm.sock
/run/php/php8.5-fpm.sock

For the command line, update-alternatives picks which php binary is the global default:

sudo update-alternatives --config php

The higher-numbered version wins automatically, so 8.5 is already the default; the menu lets you pin an older one if a project needs it:

There are 2 choices for the alternative php (providing /usr/bin/php).

  Selection    Path             Priority   Status
------------------------------------------------------------
* 0            /usr/bin/php8.5   85        auto mode
  1            /usr/bin/php8.4   84        manual mode
  2            /usr/bin/php8.5   85        manual mode

Press <enter> to keep the current choice[*], or type selection number:

To run a one-off script against a specific version regardless of the default, call the binary directly with php8.4 script.php or php8.5 script.php. Start new projects on 8.5, keep 8.4 only for the applications that have not certified against it yet, and once everything you run supports 8.5, purge the older packages with sudo apt purge 'php8.4*' to get back to a single clean version.

Keep reading

PHP2Shell (CVE-2026-109618, CVE-2026-109619): Check and Patch PHP Php PHP2Shell (CVE-2026-109618, CVE-2026-109619): Check and Patch PHP PHP2Shell on End-of-Life PHP 8.1, 8.0 and 7.4 (WHMCS, ionCube) Php PHP2Shell on End-of-Life PHP 8.1, 8.0 and 7.4 (WHMCS, ionCube) Backup and Restore Linux Systems with Timeshift Debian Backup and Restore Linux Systems with Timeshift How To Install Wine on Linux Mint 22.3 / 22.2 / 22.1 Linux Mint How To Install Wine on Linux Mint 22.3 / 22.2 / 22.1 Web Load Server Balancing with Apache,Nginx and HAProxy Apache Web Load Server Balancing with Apache,Nginx and HAProxy How To Install Anydesk on Linux Mint 22 Desktop How To Install Anydesk on Linux Mint 22

Leave a Comment

Press ESC to close