Instalar PHP 8.5 con apt en Ubuntu 26.04
Ayer subí cómo instalar Node.js 26 con apt para que el sistema operativo lo mantenga parcheado tras las actualizaciones de seguridad de octubre. Hoy le toca a PHP, por el mismo motivo: las brechas de seguridad no dan tregua, y PHP también ha tenido lo suyo.
El 24 de septiembre, PHP 8.5.11 corrigió más de diez CVE en OpenSSL, FPM, SOAP, Phar y el wrapper de streams HTTP, entre ellos un desbordamiento de buffer en el heap y un fallo que se saltaba la verificación del hostname en TLS. El 21 de octubre, PHP 8.5.12 fue más allá: una release de emergencia para dos vulnerabilidades críticas (CVE-2026-109618 y CVE-2026-109619, CVSS 9.2) que permiten ejecutar código en remoto sin autenticación. Según el propio php.net, "actualizar es la única opción segura". Las ramas 8.4, 8.3 y 8.2 recibieron las mismas correcciones.
Aquí viene la trampa: Ubuntu 26.04 LTS (Resolute Raccoon) incluye PHP 8.5 en sus repositorios, pero congela la versión en el momento del lanzamiento y le aplica por encima los parches que considera importantes. Mientras escribo esto, apt te instala PHP 8.5.4 con parches, y php.net ya va por la 8.5.12. Para ser justos, el equipo de seguridad de Ubuntu responde bien a lo urgente: publicó los parches de los RCE de octubre el mismo día que php.net. Pero la tanda de septiembre tardó 25 días en llegar, y las correcciones de bugs normales de upstream rara vez llegan.
Si quieres la versión completa de upstream, lo más sencillo sigue siendo que el propio sistema operativo se encargue. Instala PHP con apt desde el repositorio de Ondřej Surý, los mismos paquetes que llevan más de una década dando vida a PHP en Debian y Ubuntu, y deja que sudo apt upgrade haga el resto.
Fechas de soporte de un vistazo
Cada rama de PHP tiene dos años de soporte activo y otros dos solo con correcciones de seguridad. Así está el panorama según la página oficial de versiones soportadas:
| Versión | Publicada | Soporte activo hasta | Soporte de seguridad hasta |
|---|---|---|---|
| 8.2 | 8 de diciembre de 2022 | 31 de diciembre de 2024 | 31 de diciembre de 2026 |
| 8.3 | 23 de noviembre de 2023 | 31 de diciembre de 2025 | 31 de diciembre de 2027 |
| 8.4 | 21 de noviembre de 2024 | 31 de diciembre de 2026 | 31 de diciembre de 2028 |
| 8.5 | 20 de noviembre de 2025 | 31 de diciembre de 2027 | 31 de diciembre de 2029 |
Si sigues en PHP 8.2, te quedan menos de dos meses. PHP 8.6 está previsto para el 19 de noviembre de 2026, pero hoy PHP 8.5 es la apuesta segura para acompañar a una distribución LTS. Siempre puedes probar la 8.6 en paralelo (lo vemos más abajo).
En cuanto al sistema operativo, Ubuntu 26.04 LTS salió en abril de 2026 y tiene mantenimiento de seguridad estándar hasta mayo de 2031, ampliable hasta 2036 con Ubuntu Pro. Así que esta instalación te va a durar una buena temporada.
Novedades de PHP 8.5
Si vienes de PHP 8.4 o anterior, hay motivos para actualizar más allá de la seguridad. El anuncio oficial tiene la lista completa, pero mis novedades favoritas son:
- El operador pipe, para encadenar callables de izquierda a derecha sin variables temporales.
clone()con propiedades, que resuelve en una sola línea el patrón "with-er" de las clasesreadonly.- El atributo
#[\NoDiscard], que avisa cuando alguien ignora un valor de retorno que importa. - Una extensión URI nativa, con parseo de URL compatible con RFC 3986 y WHATWG, sin más sorpresas con
parse_url(). array_first()yarray_last(). Por fin.
Así queda el operador pipe convirtiendo un título en un slug:
$slug = $title
|> trim(...)
|> (fn (string $str): string => str_replace(' ', '-', $str))
|> strtolower(...);
Qué ha cambiado: adiós PPA, hola packages.sury.org
Si ya has instalado PHP en Ubuntu alguna vez, seguramente usaste add-apt-repository ppa:ondrej/php. Eso ya no es lo recomendable: Ondřej Surý está trasladando sus paquetes de Ubuntu desde Launchpad a packages.sury.org, el servidor que ya alojaba los de Debian. Los paquetes de resolute para Ubuntu 26.04 se publican solo ahí.
Si todavía tienes el PPA configurado, puede que este verano apt update se quejara de que el repositorio había cambiado su valor 'Label', un error que hacía fallar apt-get update en scripts hasta aceptar el cambio. De momento el PPA sigue recibiendo actualizaciones para Ubuntu 22.04 y 24.04, pero se está fusionando con packages.sury.org. Y si tienes los dos configurados, apt sigue prefiriendo los paquetes del PPA, así que elimínalo antes de seguir los pasos de abajo:
sudo add-apt-repository --remove ppa:ondrej/php
El nuevo método también mejora la gestión de la clave de firma. En lugar de descargar un fichero .gpg a pelo, instalas el paquete oficial debsuryorg-archive-keyring.
La vía fácil
Como de costumbre, puedes instalarlo todo con un solo comando. El script añade el repositorio de Sury, instala PHP 8.5 con las extensiones más habituales, lo configura como php por defecto y, opcionalmente, instala Composer.
curl -fsSL https://angelblanco.dev/scripts/ubuntu-install-php-85.sh | bash
El script te pide confirmación en cada paso importante. Como siempre, lee el script antes de pasárselo a bash. Fiarse de URL aleatorias con sudo es una forma estupenda de aprender a gestionar incidentes.
Si no tienes curl instalado:
sudo apt update
sudo apt install curl
La guía paso a paso
Esto es lo que hace el script, por si prefieres ir paso a paso.
1. Instalar los requisitos previos
sudo apt update
sudo apt install -y ca-certificates curl unzip
PHP no necesita unzip, pero Composer lo usa para descomprimir paquetes mucho más rápido que con su alternativa en PHP.
2. Instalar la clave de firma de Sury
curl -fsSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb \
&& sudo dpkg -i /tmp/debsuryorg-archive-keyring.deb \
&& rm /tmp/debsuryorg-archive-keyring.deb
Esto deja la clave en /usr/share/keyrings/debsuryorg-archive-keyring.gpg (y, de momento, una copia global en /etc/apt/trusted.gpg.d/). En Debian el repositorio también publica el paquete del keyring, así que las renovaciones llegan con apt upgrade. En las suites de Ubuntu todavía no está, así que si algún día se renueva la clave, vuelve a descargar e instalar el .deb.
3. Añadir el repositorio de Sury
Desde la 24.04, Ubuntu usa el formato deb822 (ficheros .sources) para sus propios repositorios, y el formato clásico .list de una línea ya está oficialmente obsoleto. El nombre en clave se lee de /etc/os-release, así que el mismo fragmento funciona también en Ubuntu 22.04 y 24.04, y en derivadas como Linux Mint.
sudo tee /etc/apt/sources.list.d/php.sources > /dev/null <<EOF
Types: deb
URIs: https://packages.sury.org/php/
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: main
Architectures: $(dpkg --print-architecture)
Signed-By: /usr/share/keyrings/debsuryorg-archive-keyring.gpg
EOF
sudo apt update
4. Instalar PHP 8.5
sudo apt install -y php8.5-cli php8.5-mbstring php8.5-curl php8.5-zip php8.5-xml
Fíjate en que instalamos php8.5-cli y no el metapaquete php8.5 a secas. El metapaquete arrastra Apache y su módulo de PHP, que seguramente no quieres en tu máquina de desarrollo. Si necesitas un servidor web, añade php8.5-fpm y combínalo con Nginx o Caddy. ¿Base de datos? Añade php8.5-mysql, php8.5-pgsql o php8.5-sqlite3.
No hace falta fijar prioridades en apt: la 8.5.12 de Sury tiene una versión mayor que la 8.5.4 de Ubuntu, así que apt la elige automáticamente. Puedes comprobar de dónde viene cada paquete con:
apt policy php8.5-cli
5. Configurar PHP 8.5 por defecto
El comando php se gestiona con update-alternatives, así que puedes elegir qué versión responde a él:
sudo update-alternatives --set php /usr/bin/php8.5
php --version
6. Instalar Composer
El instalador oficial publica un checksum SHA-384, así que verifícalo antes de ejecutar nada:
EXPECTED_CHECKSUM="$(curl -fsSL https://composer.github.io/installer.sig)"
curl -fsSLo composer-setup.php https://getcomposer.org/installer
ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
if [ "$EXPECTED_CHECKSUM" = "$ACTUAL_CHECKSUM" ]; then
php composer-setup.php --quiet
sudo install -m 0755 composer.phar /usr/local/bin/composer
rm composer.phar
composer --version
else
>&2 echo "ERROR: checksum del instalador de Composer no válido"
fi
rm composer-setup.php
Usar install en lugar de mv deja el binario a nombre de root, algo importante porque más adelante ejecutarás sudo composer self-update.
¿Y otras versiones de PHP?
Aquí es donde el repositorio de Sury brilla de verdad. Publica todas las ramas desde php5.6 hasta php8.5, además de las release candidates de PHP 8.6, y pueden convivir todas a la vez:
sudo apt install -y php8.4-cli php8.4-mbstring php8.4-curl php8.4-zip php8.4-xml
sudo update-alternatives --config php
update-alternatives --config php muestra un menú interactivo para cambiar el php por defecto. También puedes llamar directamente a una versión concreta con php8.4 o php8.5, algo muy práctico para pasar los tests de un proyecto antiguo sin tocar tu versión por defecto.
Si pruebas la 8.6 antes de la versión final del 19 de noviembre, revisa apt policy php8.6-cli: las builds anteriores a la RC4 no incluyen los parches de los RCE de octubre.
Ten en cuenta que cada versión que instalas es una más que tienes que mantener parcheada. Con Sury, al menos, apt upgrade las parchea todas de una vez.
El script
Este es el script completo. Incluye confirmaciones, usa un directorio temporal que se borra al terminar y lee tus respuestas desde la terminal, así que funciona cuando lo ejecutas con curl. Puedes cambiar la versión de PHP y las extensiones con las variables del principio.
Este script sale de mi repo de configuración de Neovim, donde guardo mis scripts de instalación. El editor necesita php y composer para que funcionen los language servers y formateadores de PHP, así que los actualizo con frecuencia. Si quieres la versión más reciente, pásate por allí.
#!/bin/bash
#
# Author: Ángel Blanco
# License: MIT
#
# This script is provided "as is", without warranty of any kind. Use at your own risk.
#
# Source: https://angelblanco.dev/blog/apt-install-php-85-on-ubuntu-26
#
# Usage:
# curl -fsSL https://angelblanco.dev/scripts/ubuntu-install-php-85.sh | bash
#
# Install PHP (from packages.sury.org) and Composer on Ubuntu.
# Normally you will call it from your non-root user; elevated permissions
# will be granted with sudo.
#
set -euo pipefail
# You can configure these variables if needed
PHP_VERSION="8.5"
PHP_EXTENSIONS="cli mbstring curl zip xml"
KEYRING="/usr/share/keyrings/debsuryorg-archive-keyring.gpg"
SOURCE_FILE="/etc/apt/sources.list.d/php.sources"
# Basic confirmation module before executing the script.
confirm_action() {
while true; do
read -r -p "$1 (y/n): " choice < /dev/tty
case "$choice" in
[Yy]|[Yy][Ee][Ss]) return 0 ;;
[Nn]|[Nn][Oo]) return 1 ;;
*) echo "Invalid choice. Please enter 'y' or 'n'." ;;
esac
done
}
WORKDIR="$(mktemp -d)"
trap 'rm -rf "$WORKDIR"' EXIT
if ! confirm_action "Install PHP $PHP_VERSION from packages.sury.org?"; then
echo "Skipping PHP installation. Exiting."
exit 0
fi
# --- Prerequisites ---------------------------------------------------------
sudo apt update
sudo apt install -y ca-certificates curl unzip
# --- Sury signing key (official keyring package) ---------------------------
curl -fsSLo "$WORKDIR/debsuryorg-archive-keyring.deb" https://packages.sury.org/debsuryorg-archive-keyring.deb
sudo dpkg -i "$WORKDIR/debsuryorg-archive-keyring.deb"
# --- Sury repository --------------------------------------------------------
CODENAME="$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")"
sudo tee "$SOURCE_FILE" > /dev/null <<EOF
Types: deb
URIs: https://packages.sury.org/php/
Suites: $CODENAME
Components: main
Architectures: $(dpkg --print-architecture)
Signed-By: $KEYRING
EOF
sudo apt update
# --- PHP --------------------------------------------------------------------
# Use -cli instead of the bare "phpX.Y" metapackage, which pulls in Apache.
PACKAGES=""
for EXTENSION in $PHP_EXTENSIONS; do
PACKAGES="$PACKAGES php${PHP_VERSION}-${EXTENSION}"
done
# shellcheck disable=SC2086
sudo apt install -y $PACKAGES
sudo update-alternatives --set php "/usr/bin/php${PHP_VERSION}"
echo ""
php --version
echo ""
# --- Composer ---------------------------------------------------------------
if confirm_action "Install Composer?"; then
cd "$WORKDIR"
EXPECTED_CHECKSUM="$(curl -fsSL https://composer.github.io/installer.sig)"
curl -fsSLo composer-setup.php https://getcomposer.org/installer
ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]; then
>&2 echo "ERROR: Invalid Composer installer checksum"
exit 1
fi
php composer-setup.php --quiet
sudo install -m 0755 composer.phar /usr/local/bin/composer
echo ""
composer --version
fi
echo ""
echo "Installation process finished."
echo "Run 'sudo apt update && sudo apt upgrade' periodically to get PHP security releases."
Mantén todo al día
Una vez instalado, mantenerlo actualizado es cosa de un par de comandos:
# Sistema operativo y PHP
sudo apt update && sudo apt upgrade
# Composer
sudo composer self-update
Incluso con la 8.5.12, php.net recomienda desactivar el progreso de subida de sesiones hasta la próxima release, para cerrar del todo una vía de RCE poco probable (CVE-2026-115560). Si sirves PHP con FPM, es cosa de una línea:
echo 'session.upload_progress.enabled=0' | sudo tee /etc/php/8.5/fpm/conf.d/99-session-upload-progress.ini
sudo systemctl restart php8.5-fpm
Y no te olvides de las dependencias de tus proyectos: composer outdated y composer audit te dicen qué toca actualizar y qué paquetes tienen vulnerabilidades conocidas.
Dos tandas de parches de seguridad de PHP en menos de un mes, una de ellas de emergencia, recuerdan que no puedes saber qué parche será el importante. Lo que sí puedes hacer es que aplicarlos sea aburrido: un apt upgrade para PHP, un composer self-update para Composer y composer audit para tus proyectos. Déjalo configurado una vez y olvídate.