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_domainyapp.your_domain.
Estado de soporte de las versiones de PHP usadas en esta guía:
| Versión | Soporte de seguridad hasta | Uso recomendado |
|---|---|---|
| 8.2 | 31 de diciembre de 2026 | Solo aplicaciones heredadas; planifica la migración |
| 8.3 | 31 de diciembre de 2027 | Versión incluida en Ubuntu 24.04 |
| 8.4 | 31 de diciembre de 2028 | Aplicaciones 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
NotaA partir de este momento apt también actualizará PHP 8.3 con los paquetes del PPA, que suelen ir por delante de los de Ubuntu. Es el comportamiento esperado.
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>/:
| Ruta | Contenido |
|---|---|
/etc/php/8.4/fpm/php.ini | php.ini de PHP-FPM 8.4 |
/etc/php/8.4/fpm/pool.d/www.conf | Pool por defecto de PHP-FPM 8.4 |
/etc/php/8.4/cli/php.ini | php.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.
ConsejoSi cada sitio necesita además su propio usuario del sistema, crea un pool dedicado en
/etc/php/<versión>/fpm/pool.d/con su propio socket, igual que harías con una sola versión de PHP.
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.
