Skip to main content
Blog|
How-to guides

How to Install PHP on Ubuntu

|
Mar 19, 2026|9 min read
HOW-TO GUIDESHow to Install PHP on UbuntuHOSTNEYhostney.comMarch 19, 2026

Ubuntu’s default repositories include PHP, but they often ship an older version. Ubuntu 22.04 LTS ships PHP 8.1. Ubuntu 24.04 LTS ships PHP 8.3. If you need a different version, or you want to run multiple versions side by side, you need the Ondrej PPA.

This guide covers installing PHP on Ubuntu via apt, adding the Ondrej PPA for specific versions, installing the extensions WordPress and other applications need, switching between PHP versions, and verifying that everything is working.

Installing PHP from the default repositories#

The simplest installation uses Ubuntu’s built-in packages:

sudo apt update
sudo apt install php

This installs the default PHP version for your Ubuntu release along with the Apache mod_php module. If you are running Nginx instead of Apache, install PHP-FPM instead:

sudo apt update
sudo apt install php-fpm

PHP-FPM (FastCGI Process Manager) runs PHP as a separate service that Nginx communicates with through a Unix socket. This is the standard setup for Nginx and is more efficient than embedding PHP in the web server process. See Nginx vs Apache: which one is better for WordPress for why this architecture matters for performance.

Verify the installation:

php -v

This prints the PHP version, build date, and whether thread safety is enabled. For a full breakdown of what the output means and how to confirm which PHP version your web server is actually using, see How to check your PHP version and find php.ini.

Installing a specific PHP version with the Ondrej PPA#

The Ondrej Sury PPA is the standard third-party repository for PHP on Ubuntu. It provides every actively maintained PHP version (8.1, 8.2, 8.3, 8.4) and backports security patches promptly. Nearly every hosting provider and deployment guide uses this PPA.

Add the PPA

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

The software-properties-common package provides the add-apt-repository command. After adding the PPA and updating, the new PHP packages are available alongside the default ones.

Install a specific version

sudo apt install php8.3

Replace 8.3 with the version you need. This installs the CLI binary and the core module. For Nginx, install the FPM package for that version:

sudo apt install php8.3-fpm

You can install multiple versions simultaneously. They do not conflict because each version has its own binary ( php8.2 , php8.3 ), its own FPM service ( php8.2-fpm , php8.3-fpm ), and its own configuration directory ( /etc/php/8.2/ , /etc/php/8.3/ ).

Available PHP versions

At the time of writing, the Ondrej PPA provides:

VersionStatus
8.1Security fixes only (EOL December 2025)
8.2Active support
8.3Active support (latest stable)
8.4Active support

Older versions (7.4, 8.0) are available in the PPA but have reached end of life and no longer receive security patches. Do not use them for new installations.

Installing PHP extensions#

A bare PHP installation does not do much. Most applications require extensions for database access, image processing, encryption, and other functionality. Extensions are installed as separate packages.

Extensions WordPress requires

WordPress needs a minimum set of extensions to function:

sudo apt install php8.3-mysql php8.3-curl php8.3-gd php8.3-mbstring php8.3-xml php8.3-zip

What each extension does:

ExtensionPurpose
php-mysql MySQL and MariaDB database access. WordPress cannot connect to its database without this.
php-curl HTTP requests. Used for plugin/theme updates, REST API calls, and external service communication.
php-gd Image processing. Used for thumbnail generation, image cropping, and resizing in the media library.
php-mbstring Multibyte string handling. Required for proper UTF-8 support in post content, comments, and metadata.
php-xml XML parsing. Used by the WordPress importer, RSS feeds, sitemaps, and many plugins.
php-zip ZIP archive handling. Required for plugin and theme installation from ZIP files.

Additional commonly needed extensions

sudo apt install php8.3-intl php8.3-soap php8.3-bcmath php8.3-imagick php8.3-redis php8.3-opcache
ExtensionPurpose
php-intl Internationalization functions. Required by WooCommerce and other plugins that handle currency, dates, and locale-specific formatting.
php-soap SOAP protocol support. Required by some payment gateways and enterprise integrations.
php-bcmath Arbitrary precision math. Used by WooCommerce for precise price calculations.
php-imagick ImageMagick bindings. Better image quality than GD for thumbnail generation. WordPress uses it automatically when available.
php-redis Redis client. Required if you use Redis for object caching.
php-opcache Opcode caching. Caches compiled PHP bytecode so scripts do not need to be recompiled on every request. This should always be installed on production servers.

Install all common extensions in one command

For a WordPress server with WooCommerce:

sudo apt install php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd php8.3-mbstring php8.3-xml php8.3-zip php8.3-intl php8.3-soap php8.3-bcmath php8.3-imagick php8.3-opcache

List installed extensions

To see which extensions are currently loaded:

php -m

This prints every loaded extension. To check if a specific extension is installed:

php -m | grep mysql

Check extension details

To see the version and configuration of a specific extension:

php --ri mysql

The --ri flag prints runtime information for the named extension.

Switching between PHP versions#

If you have multiple PHP versions installed, you need to control which one is used by the CLI and which one PHP-FPM serves to the web server.

Switching the CLI version

The update-alternatives system manages which php command points to which version:

sudo update-alternatives --set php /usr/bin/php8.3

To see all available versions and pick interactively:

sudo update-alternatives --config php

This shows a numbered list. Enter the number for the version you want. The change takes effect immediately for new CLI invocations.

Verify:

php -v

Switching the web server PHP version

The CLI version and the web server version are independent. Changing the CLI version with update-alternatives does not affect which PHP version serves your website.

Nginx with PHP-FPM

Nginx connects to PHP-FPM through a socket defined in the Nginx site configuration. The socket path includes the PHP version:

fastcgi_pass unix:/run/php/php8.3-fpm.sock;

To switch versions, change the socket path to the new version:

fastcgi_pass unix:/run/php/php8.2-fpm.sock;

Then make sure the new version’s FPM service is running and restart Nginx:

sudo systemctl start php8.2-fpm
sudo systemctl restart nginx

You can optionally stop the old FPM service to free resources:

sudo systemctl stop php8.3-fpm
sudo systemctl disable php8.3-fpm

Apache with PHP-FPM

If Apache is using PHP-FPM through mod_proxy_fcgi, the process is similar: update the proxy target in the Apache configuration and restart.

If Apache is using mod_php, disable the old module and enable the new one:

sudo a2dismod php8.2
sudo a2enmod php8.3
sudo systemctl restart apache2

Running multiple versions simultaneously

On a server hosting multiple sites, you can run different PHP versions for different sites. Each PHP-FPM version runs its own service and listens on its own socket. Point each Nginx server block to the appropriate socket.

Site A on PHP 8.2:

server {
    server_name sitea.com;
    # ...
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        # ...
    }
}

Site B on PHP 8.3:

server {
    server_name siteb.com;
    # ...
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        # ...
    }
}

Both FPM services need to be running:

sudo systemctl enable php8.2-fpm php8.3-fpm
sudo systemctl start php8.2-fpm php8.3-fpm

Configuring PHP-FPM#

After installation, PHP-FPM’s pool configuration controls how many worker processes run and how they behave. The default pool configuration is at:

/etc/php/8.3/fpm/pool.d/www.conf

Key settings:

[www]
user = www-data
group = www-data
listen = /run/php/php8.3-fpm.sock

pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
DirectiveWhat it controls
pm Process manager type.  dynamic  spawns and kills workers based on demand.  static  keeps a fixed number running.  ondemand  spawns workers only when requests arrive.
pm.max_children Maximum number of worker processes. Each worker handles one PHP request at a time. This is the ceiling on concurrent PHP execution.
pm.start_servers Number of workers created when PHP-FPM starts.
pm.min_spare_servers Minimum idle workers kept alive, ready for incoming requests.
pm.max_spare_servers Maximum idle workers. Excess idle workers are killed to free memory.

The right values depend on your server’s available memory. Each PHP-FPM worker consumes roughly 20-60 MB depending on the application. A server with 2 GB of RAM available for PHP can comfortably run 20-30 workers with a typical WordPress site.

After changing pool configuration:

sudo systemctl restart php8.3-fpm

Verifying the installation#

Check that PHP-FPM is running

sudo systemctl status php8.3-fpm

You should see active (running) . If it shows failed , check the logs:

sudo journalctl -u php8.3-fpm --no-pager -n 50

Check that the socket exists

ls -la /run/php/php8.3-fpm.sock

If the socket file does not exist, PHP-FPM is not running or is configured to listen on a different path.

Test PHP execution from the command line

php -r "echo 'PHP is working. Version: ' . phpversion() . PHP_EOL;"

Test PHP execution through the web server

Create a test file:

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

Visit http://your-server-ip/info.php in a browser. If you see the PHP info page, PHP-FPM and Nginx (or Apache) are communicating correctly. The page shows the PHP version, loaded extensions, and active configuration.

Delete the test file immediately after checking:

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

Leaving phpinfo() accessible on a production server exposes server internals to anyone who finds the URL.

Verify database connectivity

If you installed php-mysql for WordPress, verify it can connect to your database. The php-mysql extension provides both the mysqli and PDO_mysql drivers. WordPress uses mysqli . See MySQL vs MariaDB: which should you use for database setup and compatibility details.

Check that the extension is loaded:

php -m | grep mysqli

If mysqli appears in the output, the database extension is installed and loaded.

Troubleshooting#

“Unable to locate package php8.3-fpm”

The Ondrej PPA is not added, or apt update was not run after adding it:

sudo add-apt-repository ppa:ondrej/php
sudo apt update
sudo apt install php8.3-fpm

PHP-FPM starts but Nginx returns 502

Nginx cannot reach the PHP-FPM socket. Common causes:

  • The socket path in the Nginx configuration does not match the actual socket. Check  listen  in the FPM pool config and  fastcgi_pass  in the Nginx config.
  • PHP-FPM is running as a different user than expected. The socket’s ownership must allow Nginx to connect.
  • PHP-FPM crashed after starting. Check  journalctl -u php8.3-fpm  for errors.

Extensions not loading after installation

If php -m does not show a newly installed extension, the extension’s .ini file may not be in the right directory. Check:

ls /etc/php/8.3/fpm/conf.d/ | grep extension-name

Each extension typically has a .ini file like 20-mysql.ini that enables it. If the file exists but the extension is not loading, check for errors:

php -i 2>&1 | grep -i error

After installing extensions, restart PHP-FPM:

sudo systemctl restart php8.3-fpm

The CLI picks up new extensions immediately, but PHP-FPM needs a restart because it caches the configuration at startup.

Wrong PHP version serving the site

The CLI version ( php -v ) and the web server version can differ. If your site is running on an unexpected PHP version, check the Nginx configuration for the fastcgi_pass socket path. The version number in the socket path ( php8.2-fpm.sock vs php8.3-fpm.sock ) determines which PHP version handles web requests. See How to check your PHP version and find php.ini for how to confirm which version is active from the web server’s perspective.

PHP installation on Hostney#

On Hostney, PHP is pre-installed and managed through the control panel. You do not install PHP manually or manage extensions through apt.

The PHP version is shown and changeable through Hosting > PHP Manager. Switching versions is a dropdown selection that takes effect immediately. All commonly needed extensions (mysql, curl, gd, mbstring, xml, zip, intl, imagick, opcache) are pre-installed and enabled.

PHP-FPM pool settings, memory limits, and other php.ini directives are configurable through Hosting > PHP Manager > Variables tab without SSH access.