Reader Stacks

Installing PHP on Ubuntu: Single and Multiple Versions

The Ondřej Surý PPA is what makes running several PHP versions side by side on one Ubuntu server actually practical — Ubuntu's own default repositories only ship one PHP version at a time.

Installing PHP on Ubuntu is straightforward through the default package manager — running multiple versions side by side, needed when different projects on the same server require different PHP versions, needs a specific third-party repository instead.

Installing PHP from Ubuntu's default repositories

sudo apt update
sudo apt install php php-cli php-fpm php-mysql
php -v

Ubuntu's default repositories ship one specific PHP version tied to that particular Ubuntu release — this is fine for a server running a single project, but it means apt install php alone can't provide a choice of PHP versions or run more than one at once.

Adding the Ondřej Surý PPA, for access to every PHP version

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

This community-maintained PPA (Personal Package Archive) is the de facto standard source for installing a specific, current PHP version on Ubuntu — it's what makes installing PHP 8.1, 8.2, 8.3, or several at once actually possible, beyond whatever single version ships with Ubuntu's own repositories.

Installing a specific PHP version

sudo apt install php8.3 php8.3-cli php8.3-fpm php8.3-mysql php8.3-mbstring php8.3-xml

Installing multiple PHP versions side by side

sudo apt install php8.1 php8.1-fpm php8.1-cli
sudo apt install php8.3 php8.3-fpm php8.3-cli

Installing versions via the PPA doesn't uninstall or conflict with each other — each version installs to its own separate path (like /usr/bin/php8.1 and /usr/bin/php8.3), which is exactly why explicitly calling /usr/bin/php8.4 (rather than the bare php command) is the reliable way to target a specific version in a multi-version setup.

Switching the default CLI version with update-alternatives

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

update-alternatives is what controls which installed version the bare php command actually points to — without explicitly setting this, the bare php command's version can be ambiguous or unexpectedly tied to whichever version was installed or configured last.

Configuring which version Nginx or Apache actually serves

# Nginx: point fastcgi_pass at the specific version's socket
fastcgi_pass unix:/run/php/php8.3-fpm.sock;

The web server's own configuration (not update-alternatives, which only affects the CLI) is what determines which PHP-FPM version actually serves a given site — each PHP-FPM version runs its own separate socket file, and a site's config must point at the correct one for the version actually intended.

Verifying which version is running

php8.3 -v
sudo systemctl status php8.3-fpm

Installing common extensions

sudo apt install php8.3-curl php8.3-gd php8.3-zip php8.3-bcmath php8.3-intl

A fresh PHP install includes only a minimal set of extensions — a real Laravel application typically needs several of these added explicitly, and the specific set needed varies by project, worth checking against composer.json's require section for extension requirements listed there.