Nginx e várias versões de PHP no Debian e Ubuntu

Galpão no porto de Rotterdam com o wordmark nginx na parede e um elefante PHP num container

Debian 12 traz PHP 8.2. Ubuntu 24.04, 8.3. Debian 13, 8.4. Ubuntu 26.04, 8.5. Um host de verdade precisa dos três ao mesmo tempo: o WordPress antigo, o Laravel novo, o CLI do cron. O repo da distro não deixa. O de Ondřej Surý deixa. O nginx sai do nginx.org — estável, pinado, sem misturar módulo da distro.

O mapa em setembro de 2026

PHP no ciclo oficial:

  • 8.5 — ativo até dez/2027, segurança até dez/2029 (saiu 20 nov 2025)
  • 8.4 — ativo até dez/2026, segurança até dez/2028
  • 8.3 — só segurança, até dez/2027
  • 8.2 — segurança até 31 dez 2026
  • 8.1 morreu em 31 dez 2025 — não instale em caixa nova

Sury coinstala php8.3-fpm, php8.4-fpm e php8.5-fpm no mesmo box. Cada um tem socket próprio em /run/php/. O nginx escolhe o socket no vhost.

O repo de nginx do Sury fechou em abril de 2026. PHP continua em packages.sury.org/php. Nginx: distro ou nginx.org. Não misture os dois binários.

Nginx pelo nginx.org

Debian 12 (bookworm), 13 (trixie); Ubuntu 24.04 (noble), 26.04 (resolute). amd64 e arm64. Fingerprint da chave: 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 (expira 24 mai 2027).

Debian:

sudo apt install -y curl gnupg2 ca-certificates lsb-release debian-archive-keyring
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
  | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
gpg --dry-run --quiet --no-keyring --import --import-options import-show \
  /usr/share/keyrings/nginx-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://nginx.org/packages/debian $(lsb_release -cs) nginx" \
  | sudo tee /etc/apt/sources.list.d/nginx.list

Ubuntu — só muda o keyring e a URL:

sudo apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
  | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" \
  | sudo tee /etc/apt/sources.list.d/nginx.list

Pin para o apt não voltar ao nginx da distro, e instale o estável (número par: 1.30.x em 2026). Mainline é .../mainline/debian ou .../mainline/ubuntu.

printf '%s\n' 'Package: *' 'Pin: origin nginx.org' 'Pin: release o=nginx' 'Pin-Priority: 900' \
  | sudo tee /etc/apt/preferences.d/99nginx
sudo apt update
sudo apt install -y nginx
sudo systemctl enable --now nginx
nginx -v

Pacote nginx.org usa o usuário nginx e /etc/nginx/conf.d/ — não tem sites-available. O da distro usa www-data e o layout Debian. Escolha um e fique nele. O systemd cuida do serviço nos dois.

Quer o nginx da distro, com sites-enabled e nginx-extras? Pule esta seção e faça sudo apt install nginx. O resto do PHP é igual; só o dono do socket muda.

PHP: o DPA do Sury

Receita oficial de packages.sury.org/php/README.txt — vale Debian 12/13 e Ubuntu 24.04/26.04:

sudo apt-get update
sudo apt-get -y install lsb-release ca-certificates curl
curl -sSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb
sudo dpkg -i /tmp/debsuryorg-archive-keyring.deb
echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" \
  | sudo tee /etc/apt/sources.list.d/php.list
sudo apt-get update

Atalho só Ubuntu (PPA Launchpad do mesmo Ondřej):

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

Não ative os dois ao mesmo tempo. Um source de PHP basta.

Três FPM lado a lado + extensões típicas de WordPress/Laravel:

sudo apt install -y \
  php8.3-fpm php8.3-cli php8.3-mysql php8.3-xml php8.3-curl php8.3-mbstring php8.3-zip php8.3-gd php8.3-intl php8.3-bcmath \
  php8.4-fpm php8.4-cli php8.4-mysql php8.4-xml php8.4-curl php8.4-mbstring php8.4-zip php8.4-gd php8.4-intl php8.4-bcmath \
  php8.5-fpm php8.5-cli php8.5-mysql php8.5-xml php8.5-curl php8.5-mbstring php8.5-zip php8.5-gd php8.5-intl php8.5-bcmath
sudo systemctl enable --now php8.3-fpm php8.4-fpm php8.5-fpm
ls /run/php/
# php8.3-fpm.sock  php8.4-fpm.sock  php8.5-fpm.sock

CLI padrão (o que o php sem número chama):

sudo update-alternatives --config php
php -v
php8.5 -v

Alinhar o socket com o nginx

Três gabinetes de PHP ligados por fibra a um rack nginx, com Tux em pé

No nginx.org o worker é o usuário nginx. O pool padrão do FPM é www-data. Sem alinhar, dá 502. Em cada pool:

sudo sed -i 's/^listen.owner.*/listen.owner = nginx/' /etc/php/8.4/fpm/pool.d/www.conf
sudo sed -i 's/^listen.group.*/listen.group = nginx/' /etc/php/8.4/fpm/pool.d/www.conf
# repita 8.3 e 8.5
sudo systemctl restart php8.3-fpm php8.4-fpm php8.5-fpm

Se o nginx for o da distro, deixe www-data e pule o sed.

Vhost de exemplo — três sites, três PHPs. No nginx.org o arquivo vai em /etc/nginx/conf.d/:

server {
    listen 80;
    server_name wp.exemplo.com.br;
    root /var/www/wp.exemplo.com.br;
    index index.php index.html;
    location / { try_files $uri $uri/ /index.php?$args; }
    location ~ \.php$ {
        try_files $uri =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }
}
server {
    listen 80;
    server_name app.exemplo.com.br;
    root /var/www/app.exemplo.com.br/public;
    index index.php;
    location / { try_files $uri $uri/ /index.php?$query_string; }
    location ~ \.php$ {
        try_files $uri =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass unix:/run/php/php8.5-fpm.sock;
    }
}
sudo mkdir -p /var/www/wp.exemplo.com.br /var/www/app.exemplo.com.br/public
echo '<?php phpinfo();' | sudo tee /var/www/wp.exemplo.com.br/index.php
sudo nginx -t && sudo systemctl reload nginx

Confirme no phpinfo() o PHP Version e o caminho do php.ini (/etc/php/8.3/fpm/php.ini, etc.). Cada major tem ini próprio — mudar 8.4 não mexe no 8.5.

Firewall e o que não fazer

sudo ufw allow 22,80,443/tcp
sudo ufw enable

Não instale libapache2-mod-php* neste box. Não aponte dois server_name iguais para sockets diferentes e espere milagre. Não suba PHP 8.1 “porque o plugin pede”: o Sury ainda empacota, mas o upstream acabou. 8.2 só até o fim de 2026.

Painel com nginx+PHP já mastigado: ISPConfig. Este post é a caixa nua, sem painel.

O que ficou

Um pin no nginx.org, um DPA no Sury, três FPM, três sockets, três server. O apt atualiza o ponto; o vhost escolhe o major. Quando o 8.2 sair de segurança, apague o pacote — o 8.5 no outro vhost nem percebe.

Nginx: nginx.org/en/linux_packages.html · PHP Sury: packages.sury.org/php · ciclo PHP: php.net/supported-versions.