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

Mascote do LinuxPro ligando o nginx a três PHP-FPM, placa 3D do hexágono verde na parede

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 o 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 o .../mainline/ubuntu.

printf '%sn' '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

Diagrama: navegadores chegam no nginx, que roteia para três pools de PHP-FPM no mesmo host

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.