Nginx with PHP-FPM is the standard way to serve PHP sites such as WordPress on Linux Mint 22. Nginx takes the connections and passes every .php request to a pool of PHP workers over a Unix socket. Both come straight from the Ubuntu 24.04 (noble) archive that Mint 22 is built on, so you don’t need any extra repository, and the PHP 8.3 build there already carries the October 2026 PHP2Shell fix.
The steps below install Nginx, add PHP-FPM with the common extensions, check the PHP build for PHP2Shell, and wire the two together with a server block that suits WordPress. We ran the install, the server block and the PHP2Shell check on Linux Mint 22.3 and on a fresh Ubuntu 24.04 system, the noble base Mint 22 shares, in October 2026.
What is Nginx?
Nginx is an open-source program that serves quite a number of purposes, which include being a web server, cache, proxy and reverse proxy, load balancer, and media streaming server. The goal behind the development of nginx was to produce a high speed web server which has now facilitated the creation of highly scalable websites. Being a fast webserver nginx became suitable for situations that called for many and fast connections such as reverse proxying and load balancing since it can handle large volumes of simultaneous connections. Nginx also acts as an SSL/TLS terminator between a client and a web server, handling tasks such as SSL negotiation that might otherwise slow the web server down.
What is PHP-FPM?
PHP-FPM (PHP FastCGI Process Manager) serves requests between PHP and the web server, just like the mod_php module does when using the Apache web server. Nginx has no PHP module of its own, so it hands PHP requests to PHP-FPM, which keeps a pool of worker processes ready and is fast because of it.
Update Linux Mint
Before any installation, ensure that your system is running the latest version and that your packages are up to date.
sudo apt update && sudo apt upgrade -y
After the updates, it is highly recommended to reboot your machine to ensure that the new changes take effect.
sudo reboot
Log back in once the machine is up, and continue with Nginx.
Install Nginx on Linux Mint
Having updated your packages, it is time to install Nginx on your Linux Mint. Run the command as shown to install Nginx.
sudo apt install nginx -y
To verify installation, check whether Nginx is running by using the command below:
sudo systemctl status nginx
The service should read active (running) and enabled, as in this sample output:

Now if you are running a firewall you need to allow Nginx ports through the firewall:
sudo ufw allow 443/tcp
sudo ufw allow 80/tcp
UFW was inactive on our Mint 22.3 machine, and in that state these rules are stored but only take effect once you enable the firewall.
Install PHP-FPM on Linux Mint
Follow the steps below to install PHP-FPM on Linux Mint 22 to work with Nginx. First update your system package index.
sudo apt update
Then install the PHP command line, php-fpm and the common extensions. Leave the bare php package off this line, because on noble it depends on php8.3, which pulled in Apache and mod_php in our test. Apache then failed to start, since Nginx already holds port 80, but it stayed enabled for the next boot:
sudo apt install -y php-cli php-fpm php-json php-pdo php-mysql php-zip php-gd php-mbstring php-curl php-xml php-pear php-bcmath
If you installed PHP with an older version of this guide, check whether Apache came along:
systemctl is-enabled apache2
The answer not-found means it never got installed and you can move on. If it prints enabled, Apache races Nginx for port 80 at every boot, and whichever starts first wins. Stop Apache, keep it off, and restart Nginx in case Apache held the port last time:
sudo systemctl disable --now apache2
sudo systemctl restart nginx
systemctl is-active nginx
The last command must print active. We tested the case where Apache had taken port 80 and Nginx was down, and after these three commands Nginx answered PHP requests again with Apache disabled. Nothing in this guide needs Apache.
After installation completes, check php version with the below command:
php -v
Ubuntu patches PHP 8.3 in place, so every noble build reports 8.3.6, and the PHP2Shell section below shows how to tell a patched one from an old one:
PHP 8.3.6 (cli) (built: Oct 19 2026 15:16:58) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.6, Copyright (c) Zend Technologies
with Zend OPcache v8.3.6, Copyright (c), by Zend Technologies
To check modules run:
php -m
The list should include curl, gd, mbstring, mysqli, pdo_mysql, zip and Zend OPcache. A missing entry means its package didn’t install, so rerun the install line and read apt’s error.
Confirm the PHP2Shell fix (CVE-2026-109618, CVE-2026-109619)
PHP2Shell is two critical bugs in PHP itself, CVE-2026-109618 and CVE-2026-109619, that let a crafted HTTP request run code on the server. PHP’s 20 October pre-announcement rated both 9.2 on CVSS v4.0, and the fixes shipped on 21 October 2026 in 8.5.12, 8.4.27, 8.3.36 and 8.2.35, per the PHP security advisory. Linux Mint 22 doesn’t move to 8.3.36. Ubuntu backported the fix into its own 8.3.6 build in noble-security, and Mint 22 pulls that pocket by default, so a fresh install from this guide is patched while a server set up before 21 October isn’t until you upgrade it.
Because php -v prints 8.3.6 before and after the patch, it proves nothing. The package version and its changelog do:
dpkg-query -W php8.3-common
zgrep -E 'CVE-2026-10961[89]' /usr/share/doc/php8.3-common/changelog.Debian.gz
A patched system shows package 0ubuntu0.24.04.13 or later and changelog lines naming both CVEs. If zgrep prints nothing, the build is older than the fix:
php8.3-common 8.3.6-0ubuntu0.24.04.13
- debian/patches/CVE-2026-109618_109619.patch: Avoid state corruption via
- CVE-2026-109618
- CVE-2026-109619
Minimal installs that strip /usr/share/doc have no changelog to read. This comparison works on any system and prints patched or VULNERABLE:
dpkg --compare-versions "$(dpkg-query -W -f='${Version}' php8.3-common)" ge 8.3.6-0ubuntu0.24.04.13 && echo patched || echo VULNERABLE
On a fresh install that check is the end of the job, so skip ahead to the Nginx server block. On an existing server installed before 21 October, upgrade in place. The glob matches every php8.3 package you have, and the Apache module goes on the line by name because the glob misses it; apt skips whatever isn’t installed:
sudo apt update
sudo apt install --only-upgrade 'php8.3*' libapache2-mod-php8.3
Don’t count on the package scripts to restart the running workers. Restart PHP-FPM yourself, then compare when it started with when apt last replaced the package:
sudo systemctl restart php8.3-fpm
systemctl show -p ActiveEnterTimestamp php8.3-fpm
zgrep -hE ' (install|upgrade) php8.3-(common|fpm):' /var/log/dpkg.log* | sort | tail -1
The start time must be later than the dpkg line. Our lab box was installed with the patched build, so its dpkg line is the original install and the upgrade was a no-op:
ActiveEnterTimestamp=Thu 2026-10-22 19:43:16 UTC
2026-10-22 19:39:41 install php8.3-fpm:amd64 <none> 8.3.6-0ubuntu0.24.04.13
Long-running PHP CLI workers, such as queue workers under supervisor or a systemd unit, keep the old code in memory until they restart, so restart those too.
Older Mint releases differ. Mint 21 sits on jammy, whose php8.1 package in jammy-security carries the same fix from version 8.1.2-1ubuntu2.28 on, so the same comparison works there with the php8.1 package name:
dpkg --compare-versions "$(dpkg-query -W -f='${Version}' php8.1-common)" ge 8.1.2-1ubuntu2.28 && echo patched || echo VULNERABLE
Mint 20 is a different story. It reached end of life in April 2025 and sits on focal, where the free archive’s PHP 7.4 has no fix, and Ubuntu Pro, the only source of a patched focal build, is not a supported route on Mint, so treat a Mint 20 web server as unpatched. The way out is two release upgrades with mintupgrade, 20 to 21 and then 21 to 22, or a clean Mint 22 install.
If you added the OndΕej SurΓ½ PPA for a newer branch, your PHP comes from the PPA instead, and the PHP 8.5 guide for Mint shows how to check those builds. Either way, the version probe at the end of the next section confirms which PHP actually answers web requests.
Configure Nginx to use PHP-FPM
With both installed we can consider an example on usage. The sample configuration is for WordPress using Nginx and FPM, and the full application setup is in the WordPress install guide for Mint. Create the server block:
sudo vim /etc/nginx/sites-available/mywebsite.conf
Paste the following, replacing app.example.com with your own domain:
server {
listen 80;
listen [::]:80;
server_name app.example.com www.app.example.com;
root /var/www/html/wp_website;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php-fpm.sock;
}
}
The leading slash in /index.php?$args matters. Without it, WordPress permalinks such as /hello-world/ returned 404 in our test, while the same URL went to index.php once the slash was in place. The socket /run/php/php-fpm.sock is a symlink that Ubuntu’s packages point at php8.3-fpm.sock, so the file keeps working if the PHP branch changes. snippets/fastcgi-php.conf already sets SCRIPT_FILENAME, so the block needs no fastcgi_param line of its own. Enable the site and create its web root:
sudo ln -s /etc/nginx/sites-available/mywebsite.conf /etc/nginx/sites-enabled/
sudo mkdir -p /var/www/html/wp_website
sudo nginx -t
The syntax check must pass before you reload:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Load the new server block:
sudo systemctl reload nginx
Then ask the site itself which PHP answers. The Host header lets you test before DNS points at the machine, and the probe file is removed straight after:
echo '<?php echo PHP_VERSION, " ", PHP_SAPI, PHP_EOL;' | sudo tee /var/www/html/wp_website/version.php >/dev/null
curl -s -H 'Host: app.example.com' http://localhost/version.php
sudo rm /var/www/html/wp_website/version.php
Nginx handed the request to the PHP-FPM pool, which reports the FPM SAPI:
8.3.6 fpm-fcgi
If you get the PHP source back instead, the request did not reach the location ~ \.php$ block: either another server block answered it (check that server_name matches the Host you sent and that the symlink is in sites-enabled), or the request landed in the moment right after the reload, which only a retry straight after reloading fixes. A 502 means Nginx can’t reach the socket, which usually means php8.3-fpm isn’t running. The version in that output stays 8.3.6 whether the server is patched or not, so the changelog check in the PHP2Shell section remains the proof, and this probe shows that the pool serving your site is the one you restarted. Nginx and PHP-FPM are ready for WordPress or any other PHP application from here.
Recommended Web Development books to read:
Click links below for more interesting guides: