Es habitual tener en el mismo servidor una aplicación antigua que solo funciona con PHP 8.2 y otra nueva que ya aprovecha PHP 8.4. Como cada versión de PHP-FPM es un servicio independiente con su propio socket, puedes instalar varias en paralelo y decidir en Nginx qué versión atiende a cada sitio. En este tutorial instalarás PHP 8.2, 8.3 y 8.4 en Ubuntu 24.04, configurarás dos sitios con versiones distintas y aprenderás a cambiar la versión de la línea de comandos.

Requisitos previos

Para seguir esta guía necesitas:

  • Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath.
  • Un usuario no root con privilegios sudo.
  • Nginx instalado (sudo apt install nginx) y el puerto 80 abierto (sudo ufw allow 'Nginx HTTP').
  • Dos nombres de dominio o subdominios apuntando al servidor. En los ejemplos se usan legacy.your_domain y app.your_domain.

Estado de soporte de las versiones de PHP usadas en esta guía:

VersiónSoporte de seguridad hastaUso recomendado
8.231 de diciembre de 2026Solo aplicaciones heredadas; planifica la migración
8.331 de diciembre de 2027Versión incluida en Ubuntu 24.04
8.431 de diciembre de 2028Aplicaciones nuevas

No instales versiones que ya no reciben parches de seguridad (7.4, 8.0 y 8.1) en un servidor expuesto a Internet.

Paso 1: Añadir el PPA de Ondřej Surý

Los repositorios de Ubuntu 24.04 solo incluyen PHP 8.3. El PPA ondrej/php, mantenido por el responsable de los paquetes de PHP en Debian, publica todas las versiones soportadas compiladas para Ubuntu con la misma estructura de rutas y servicios.

Instala la herramienta para gestionar PPAs y añade el repositorio:

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

Pulsa Enter cuando te pida confirmación. add-apt-repository descarga la clave de firma y actualiza el índice de paquetes.

Comprueba que las versiones adicionales ya están disponibles:

apt-cache policy php8.4-fpm php8.2-fpm
php8.4-fpm:
  Installed: (none)
  Candidate: 8.4.x-1+ubuntu24.04.1+deb.sury.org+1
...
php8.2-fpm:
  Installed: (none)
  Candidate: 8.2.x-1+ubuntu24.04.1+deb.sury.org+1

Paso 2: Instalar varias versiones de PHP-FPM

Instala cada versión con las extensiones que necesiten tus aplicaciones. Los nombres de paquete siguen siempre el patrón phpX.Y-extension:

sudo apt install php8.4-fpm php8.4-cli php8.4-mysql php8.4-curl php8.4-xml php8.4-mbstring php8.4-zip php8.4-intl php8.4-gd
sudo apt install php8.3-fpm php8.3-cli php8.3-mysql php8.3-curl php8.3-xml php8.3-mbstring php8.3-zip php8.3-intl php8.3-gd
sudo apt install php8.2-fpm php8.2-cli php8.2-mysql php8.2-curl php8.2-xml php8.2-mbstring php8.2-zip php8.2-intl php8.2-gd

Cada versión instala su propio servicio systemd, que se habilita y arranca automáticamente. Compruébalo:

systemctl list-units 'php*-fpm.service' --no-pager
  UNIT               LOAD   ACTIVE SUB     DESCRIPTION
  php8.2-fpm.service loaded active running The PHP 8.2 FastCGI Process Manager
  php8.3-fpm.service loaded active running The PHP 8.3 FastCGI Process Manager
  php8.4-fpm.service loaded active running The PHP 8.4 FastCGI Process Manager

Y verifica que cada una escucha en su propio socket:

ls -l /run/php/*.sock
srw-rw---- 1 www-data www-data 0 Sep 25 10:12 /run/php/php8.2-fpm.sock
srw-rw---- 1 www-data www-data 0 Sep 25 10:12 /run/php/php8.3-fpm.sock
srw-rw---- 1 www-data www-data 0 Sep 25 10:12 /run/php/php8.4-fpm.sock

No hace falta cambiar puertos ni sockets: al llevar la versión en el nombre, no chocan entre sí.

Paso 3: Entender dónde vive la configuración de cada versión

Cada versión tiene su árbol de configuración independiente bajo /etc/php/<versión>/:

RutaContenido
/etc/php/8.4/fpm/php.iniphp.ini de PHP-FPM 8.4
/etc/php/8.4/fpm/pool.d/www.confPool por defecto de PHP-FPM 8.4
/etc/php/8.4/cli/php.iniphp.ini de la CLI 8.4
/etc/php/8.4/mods-available/Extensiones disponibles para 8.4

Un cambio en /etc/php/8.2/fpm/php.ini solo afecta a PHP-FPM 8.2. Cada versión tiene también su propio comando de prueba de configuración:

sudo php-fpm8.2 -t
sudo php-fpm8.4 -t
[25-Sep-2026 10:15:02] NOTICE: configuration file /etc/php/8.2/fpm/php-fpm.conf test is successful
[25-Sep-2026 10:15:02] NOTICE: configuration file /etc/php/8.4/fpm/php-fpm.conf test is successful

Paso 4: Asignar una versión de PHP a cada sitio en Nginx

La versión de PHP que usa un sitio la decide únicamente la directiva fastcgi_pass de su bloque server. Crea los directorios de los dos sitios:

sudo mkdir -p /var/www/legacy.your_domain /var/www/app.your_domain

Crea el bloque del sitio heredado, que usará PHP 8.2:

sudo nano /etc/nginx/sites-available/legacy.your_domain
server {
    listen 80;
    listen [::]:80;
    server_name legacy.your_domain;

    root /var/www/legacy.your_domain;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

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

Crea el bloque del sitio nuevo, que usará PHP 8.4:

sudo nano /etc/nginx/sites-available/app.your_domain
server {
    listen 80;
    listen [::]:80;
    server_name app.your_domain;

    root /var/www/app.your_domain;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

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

Activa ambos sitios, valida y recarga Nginx:

sudo ln -s /etc/nginx/sites-available/legacy.your_domain /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/app.your_domain /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Verificar qué versión atiende cada sitio

Crea un archivo de prueba en cada sitio:

echo '<?php echo PHP_VERSION, " ", PHP_SAPI, "\n";' | sudo tee /var/www/legacy.your_domain/version.php /var/www/app.your_domain/version.php > /dev/null

Consulta los dos sitios desde el servidor:

curl -H "Host: legacy.your_domain" http://127.0.0.1/version.php
curl -H "Host: app.your_domain" http://127.0.0.1/version.php
8.2.29 fpm-fcgi
8.4.12 fpm-fcgi

Cada sitio responde con su versión. Borra los archivos de prueba:

sudo rm /var/www/legacy.your_domain/version.php /var/www/app.your_domain/version.php

Para cambiar un sitio de versión más adelante, basta con editar su fastcgi_pass, ejecutar sudo nginx -t y recargar Nginx. Antes, instala en la versión de destino las mismas extensiones que usa el sitio.

Paso 5: Elegir la versión de PHP de la línea de comandos

El comando php es un enlace gestionado por update-alternatives. Tras instalar el PPA suele apuntar a la versión más reciente instalada. Compruébalo:

php -v
PHP 8.4.12 (cli) (built: ...) (NTS)

Para cambiar la versión por defecto de forma interactiva:

sudo update-alternatives --config php
There are 3 choices for the alternative php (providing /usr/bin/php).

  Selection    Path             Priority   Status
------------------------------------------------------------
* 0            /usr/bin/php8.4   84        auto mode
  1            /usr/bin/php8.2   82        manual mode
  2            /usr/bin/php8.3   83        manual mode
  3            /usr/bin/php8.4   84        manual mode

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

O de forma no interactiva, útil en scripts de aprovisionamiento:

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

Cambiar la versión por defecto de la CLI no afecta a PHP-FPM ni a Nginx. Para tareas concretas es más claro llamar al binario con versión explícita, por ejemplo en el cron o el despliegue del sitio heredado:

php8.2 /var/www/legacy.your_domain/artisan schedule:run
php8.2 /usr/local/bin/composer install --no-dev

Así Composer resuelve las dependencias con la versión de PHP con la que se ejecutará la aplicación.

Paso 6: Gestionar extensiones por versión

Las extensiones se instalan por versión. Para ver cuáles tiene cada una:

php8.2 -m
php8.4 -m

Para comparar rápidamente qué le falta a una versión respecto a otra:

diff <(php8.2 -m) <(php8.4 -m)

Instala una extensión solo en la versión que la necesita y recarga su servicio:

sudo apt install php8.4-redis
sudo systemctl reload php8.4-fpm

Para desactivar una extensión instalada sin desinstalarla, usa phpdismod indicando versión y SAPI (fpm o cli):

sudo phpdismod -v 8.4 -s fpm redis
sudo systemctl reload php8.4-fpm

phpenmod funciona igual para volver a activarla.

Paso 7: Mantener y retirar versiones

Las actualizaciones de todas las versiones llegan con el apt upgrade habitual y los paquetes reinician su servicio al actualizarse:

sudo apt update && sudo apt upgrade

Cuando migres el último sitio que usaba una versión, elimínala para no dejar software sin parches en el servidor. Primero confirma que ningún sitio apunta a su socket:

grep -r "php8.2-fpm.sock" /etc/nginx/sites-enabled/

Si el comando no devuelve nada, elimina todos los paquetes de esa versión:

sudo apt purge 'php8.2*'
sudo apt autoremove

Comprueba que solo quedan las versiones que usas:

systemctl list-units 'php*-fpm.service' --no-pager

Solución de problemas

El sitio muestra una versión distinta de la esperada. Nginx usa el fastcgi_pass del bloque server que coincide con el Host. Revisa qué bloque atiende la petición y a qué socket apunta:

sudo nginx -T | grep -E "server_name|fastcgi_pass"

502 Bad Gateway tras cambiar de versión. El servicio de la versión de destino no está en marcha o el socket no existe. Comprueba el estado y el journal:

systemctl status php8.4-fpm
sudo journalctl -u php8.4-fpm -n 50 --no-pager

"Call to undefined function" tras cambiar de versión. Falta una extensión en la nueva versión. Compara con diff <(php8.2 -m) <(php8.4 -m) e instala los paquetes php8.4-* correspondientes.

Composer instala dependencias incompatibles. Estás ejecutando Composer con una versión de PHP diferente a la del sitio. Invócalo con el binario explícito (php8.2 /usr/local/bin/composer ...) o fija la versión de destino en composer.json con config.platform.php.

Conclusión

Ahora tienes PHP 8.2, 8.3 y 8.4 funcionando en paralelo en Ubuntu 24.04, cada sitio de Nginx apuntando al socket de PHP-FPM de su versión y la CLI configurada con update-alternatives. Cambiar un sitio de versión se reduce a editar una línea y recargar Nginx.

Como siguientes pasos, crea un pool con usuario propio para cada sitio, añade HTTPS con Certbot y planifica la migración de las aplicaciones que siguen en PHP 8.2 antes de que termine su soporte.