We may earn a referral fee at no additional cost to you when you shop through the links on this page.
Ubuntu 24.04 LTS (Noble Numbat), released April 2024, is a stable long-term support release with security updates until April 2029 (extendable to 2034 with Ubuntu Pro). It ships with PHP 8.3, bringing strong performance, JIT compiler enhancements, and modern language features to your LEMP stack.
The following steps cover installing PHP-FPM and essential extensions, configuring Nginx to pass PHP requests to the FPM process manager, tuning PHP settings for production, and verifying the installation.
Prerequisites
Before you begin, ensure you have:
- A server running Ubuntu 24.04 (Noble Numbat) with a non-root user that has
sudoprivileges. See our initial server setup guide for Ubuntu 24.04 (Noble Numbat) if needed. - Nginx installed and running with a server block configured. Follow our How to Install Nginx on Ubuntu 24.04 (Noble Numbat) guide first.
Installing PHP-FPM
Unlike Apache’s embedded mod_php, Nginx does not process PHP natively. Instead, it delegates PHP requests to PHP-FPM (FastCGI Process Manager), a separate service that manages a pool of PHP worker processes. Nginx communicates with PHP-FPM through a Unix socket, passing each request and receiving the rendered output.
Install PHP-FPM and the CLI tools:
sudo apt update && sudo apt install -y php-fpm
This installs PHP 8.3 from the Ubuntu 24.04 (Noble Numbat) repositories along with the FPM process manager. The php8.3-fpm service starts automatically after installation.
Verify the PHP-FPM service is running:
sudo systemctl status php8.3-fpm
You should see active (running) in the output. PHP-FPM is now listening on a Unix socket at /run/php/php8.3-fpm.sock, ready to accept requests from Nginx.
Verifying the Installation
Check the installed PHP version:
php -v
You should see output similar to:
PHP 8.3.x (cli) (built: ...)
Copyright (c) The PHP Group
Zend Engine v4.x.x, Copyright (c) Zend Technologies
with Zend OPcache v8.3.x, Copyright (c), by Zend Technologies
Configuring Nginx for PHP
Nginx needs to be told how to handle PHP files. Open the server block you created in the Nginx installation guide:
sudo nano /etc/nginx/sites-available/example.com
Replace the contents with the following configuration, which adds PHP processing and sets index.php as the default file:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
Save and exit (press CTRL + X, press Y, then press ENTER)
Here’s what each block does:
| Directive | Purpose |
|---|---|
index index.php ... | Tells Nginx to look for index.php first when serving a directory. |
location ~ \.php$ | Matches any request ending in .php and passes it to PHP-FPM. |
include snippets/fastcgi-php.conf | Loads standard FastCGI parameters (document root, script filename, path info handling). |
fastcgi_pass unix:... | Sends the request to PHP-FPM via the Unix socket. |
location ~ /\.ht | Blocks access to .htaccess and other dotfiles for security. |
Test the configuration and reload Nginx:
sudo nginx -t && sudo systemctl reload nginx
Testing PHP Processing
Create a PHP test file to verify Nginx passes requests to PHP-FPM correctly:
echo '<?php phpinfo(); ?>' | sudo tee /var/www/example.com/info.php
Open your browser and navigate to:
http://example.com/info.php
You should see the PHP information page. Look for the Server API row, which should show FPM/FastCGI, confirming that Nginx is correctly communicating with PHP-FPM.
phpinfo() page exposes sensitive server configuration details. Remove it after testing:sudo rm /var/www/example.com/info.php - The
location ~ \.php$block is present in your server block - The socket path in
fastcgi_passmatches your PHP version:/run/php/php8.3-fpm.sock - PHP-FPM is running:
sudo systemctl status php8.3-fpm - You ran
sudo nginx -t && sudo systemctl reload nginxafter editing the config
Installing Common PHP Extensions
Most web applications require additional PHP extensions. The following command installs a robust set of extensions needed by WordPress, Laravel, Drupal, and other popular frameworks:
sudo apt install -y php-mysql php-curl php-gd php-mbstring php-xml php-zip php-intl php-bcmath
Here’s what each extension provides:
| Extension | Purpose | Required By |
|---|---|---|
php-mysql | MySQL/MariaDB database connectivity | WordPress, Laravel, Drupal, most CMS |
php-curl | HTTP requests, API integrations | WordPress plugins, payment gateways |
php-gd | Image processing and manipulation | WordPress media, image galleries |
php-mbstring | Multibyte string handling (UTF-8) | Any multilingual application |
php-xml | XML parsing (RSS, sitemaps, SOAP) | WordPress, Drupal, API integrations |
php-zip | Archive compression/extraction | Plugin/theme installers |
php-intl | Internationalization (i18n) | Symfony, Laravel, Magento |
php-bcmath | Arbitrary precision mathematics | E-commerce, financial applications |
Restart PHP-FPM to load the new extensions:
sudo systemctl restart php8.3-fpm
Verify the extensions are loaded:
php -m | grep -iE 'mysql|curl|gd|mbstring|xml|zip|intl|bcmath'
You should see each extension listed in the output.
apt search php- | grep ^php Configuring PHP
PHP-FPM has its own php.ini file, separate from the CLI version. The primary configuration file for PHP-FPM is:
/etc/php/8.3/fpm/php.ini
Common Configuration Changes
Open the PHP-FPM configuration file:
sudo nano /etc/php/8.3/fpm/php.ini
Here are recommended settings for most web applications. Find each directive (use Ctrl + W to search) and modify as needed:
; Maximum memory a script can consume (increase for large applications)
memory_limit = 256M
; Maximum file upload size (adjust for media-heavy sites)
upload_max_filesize = 64M
; Maximum size of POST data (should be >= upload_max_filesize)
post_max_size = 64M
; Maximum script execution time in seconds
max_execution_time = 300
; Maximum time for parsing input data
max_input_time = 300
; Server timezone (important for date/time functions)
date.timezone = UTC
Save and exit (press CTRL + X, press Y, then press ENTER)
128M memory; WooCommerce and page builders often require 256M or more. Restart PHP-FPM to apply configuration changes:
sudo systemctl restart php8.3-fpm
Production Error Handling
In production, disable error display to prevent exposing sensitive information while still logging errors for debugging:
; Disable error display in browser (security)
display_errors = Off
; Log errors to file instead
log_errors = On
; Error log location (check Nginx's error log or set custom path)
; error_log = /var/log/php_errors.log
Save and exit (press CTRL + X, press Y, then press ENTER)
display_errors = On temporarily to see errors in your browser. Always switch back to Off before going live. About PHP-FPM pools: PHP-FPM runs as a separate service from Nginx, managing a pool of PHP worker processes. The default pool (www) is configured in /etc/php/8.3/fpm/pool.d/www.conf. For most single-site setups, the defaults are fine. For high-traffic sites, you can tune pm.max_children, pm.start_servers, and related directives based on available memory.
Important File Locations
Key paths for managing PHP-FPM on Ubuntu 24.04 (Noble Numbat):
- PHP Configuration (FPM):
/etc/php/8.3/fpm/php.ini— Primary settings file for web requests. - PHP Configuration (CLI):
/etc/php/8.3/cli/php.ini— Settings for command-line scripts (separate from FPM). - FPM Pool Configuration:
/etc/php/8.3/fpm/pool.d/www.conf— Worker process settings (pm.max_children, etc.). - Additional Configuration:
/etc/php/8.3/fpm/conf.d/— Drop-in config files for extensions. - FPM Socket:
/run/php/php8.3-fpm.sock— Unix socket for Nginx-to-FPM communication. - PHP-FPM Error Log:
/var/log/php8.3-fpm.log— FPM process manager log.
Creating a Complete Test
Create a simple PHP script to verify your setup works end-to-end. This replaces the Nginx test page you created earlier:
sudo nano /var/www/example.com/index.php
Add the following content:
<?php
$hostname = gethostname();
$php_version = phpversion();
$server_software = $_SERVER['SERVER_SOFTWARE'];
$document_root = $_SERVER['DOCUMENT_ROOT'];
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PHP Test - <?php echo $hostname; ?></title>
<style>
body { font-family: system-ui, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
h1 { color: #4F5D95; }
.info { background: #f4f4f4; padding: 15px; border-radius: 5px; margin: 10px 0; }
.success { color: #28a745; }
code { background: #e9ecef; padding: 2px 6px; border-radius: 3px; }
</style>
</head>
<body>
<h1>✓ PHP is Working!</h1>
<div class="info">
<p><strong>PHP Version:</strong> <code><?php echo $php_version; ?></code></p>
<p><strong>Server:</strong> <code><?php echo $server_software; ?></code></p>
<p><strong>Hostname:</strong> <code><?php echo $hostname; ?></code></p>
<p><strong>Document Root:</strong> <code><?php echo $document_root; ?></code></p>
</div>
<p class="success">Your LEMP stack's PHP component is configured correctly.</p>
<p><small>Return to <a href="https://devanswers.net/series/lemp-stack/">LEMP Stack Documentation</a></small></p>
</body>
</html>
Save and exit (press CTRL + X, press Y, then press ENTER)
Visit http://example.com in your browser to see the test page. If you see the PHP version and server details, your LEMP stack’s PHP layer is working correctly.
Conclusion
You now have PHP 8.3 running as PHP-FPM with Nginx on Ubuntu 24.04, complete with essential extensions for modern web applications.
With PHP 8.3’s performance improvements and security support until 2029 (or 2034 with Ubuntu Pro), this is an excellent foundation for WordPress, Laravel, and other PHP applications. Your next step is installing MariaDB to complete your LEMP stack.
Comments