Instalar e configurar o nginx em Debian e Ubuntu
Do pacote apt ao primeiro bloco server com PHP-FPM e HTTPS: que versão de nginx traz cada distribuição, o que muda com o repositório nginx.org e como resolver os erros mais típicos.
Instalar o nginx demora trinta segundos. O resto do dia perde-se porque o bloco server não pega, porque o PHP devolve um 502 ou porque o Apache já ocupa a porta 80. Este artigo percorre exatamente esses pontos, e fá-lo separadamente para Debian 13, Debian 12, Ubuntu 24.04 e Ubuntu 22.04, porque os quatro sistemas comportam-se de forma diferente em vários aspetos.
Que nginx escolher: pacote da distribuição ou repositório oficial
A primeira decisão toma-se antes do primeiro comando. Cada distribuição inclui uma versão congelada que só recebe patches de segurança. Em julho de 2026, o panorama é este:
| Sistema | nginx do pacote da distribuição |
| Debian 13 (trixie) | 1.26.3 |
| Debian 12 (bookworm) | 1.22.1 |
| Ubuntu 24.04 LTS (noble) | 1.24.0 |
| Ubuntu 22.04 LTS (jammy) | 1.18.0 |
No próprio nginx.org estão disponíveis, em julho de 2026, os ramos 1.30.4 (stable) e 1.31.3 (mainline). A distância em relação ao Ubuntu 22.04 corresponde assim a cerca de seis anos de desenvolvimento de funcionalidades.
Escolha o pacote da distribuição se gere sites clássicos ou montagens de reverse proxy e quer que o unattended-upgrades faça o trabalho por si. Escolha o repositório nginx.org se precisa de HTTP/3 e QUIC (inexistentes no Ubuntu 22.04 e também no Debian 12), se quer módulos dinâmicos já compilados como nginx-module-brotli ou o módulo ACME, ou se quer usar exatamente a mesma versão em várias distribuições.
O que muitos guias não dizem: os dois pacotes não são o mesmo programa em versões diferentes, são compilados de forma diferente e empacotados de forma diferente. Essa é a causa mais frequente de um guia copiado não funcionar.
| Característica | Pacote Debian/Ubuntu | Pacote nginx.org |
| Utilizador do processo | www-data | nginx |
| Docroot predefinido | /var/www/html | /usr/share/nginx/html |
| sites-available e sites-enabled | existem | não existem |
| /etc/nginx/snippets/ | existe | não existe |
| Perfis ufw (Nginx Full, etc.) | existem | não existem |
| Módulos dinâmicos | libnginx-mod-* | nginx-module-* |
Instalação a partir do pacote da distribuição
Idêntica nos quatro sistemas:
apt update
apt install -y nginx
apt install -y curl
O metapacote nginx chega. nginx-full e nginx-extras continuam a existir no Debian 12 e 13, mas apenas arrastam pacotes de módulos adicionais. Os módulos individuais instala-os de forma seletiva, por exemplo com apt install libnginx-mod-http-headers-more-filter.
O curl aparece ali de propósito. Não é uma dependência do nginx e falta num Debian ou num Ubuntu acabados de instalar, mesmo depois de o nginx ter sido instalado sem problemas. Sem esse passo, o primeiro comando de verificação mais abaixo termina com curl: command not found, e a mesma armadilha atinge depois o teste do cabeçalho Host e o teste do PHP.
Agora a parte que a maioria dos guias salta: a prova de que aquilo está mesmo a funcionar. Um apt install sem mensagem de erro não prova nada.
nginx -v
systemctl is-enabled nginx
systemctl is-active nginx
curl -I http://127.0.0.1/
O esperado é enabled, active e um HTTP/1.1 200 OK com um cabeçalho Server que mencione o nginx (o Debian 13 responde com Server: nginx e o Ubuntu 24.04 com Server: nginx/1.24.0). Só então o servidor web está de pé. Quem quiser saber com que opções o pacote foi compilado usa nginx -V (V maiúsculo); aí fica também indicado se --with-http_v3_module está incluído.
Se o ufw estiver ativo, falta ainda a regra de firewall. Antes disso, um olhar sobre o próprio pacote: no Ubuntu Server o ufw vem instalado de fábrica e apenas inativo, no Debian não existe de todo. Aí, a primeira chamada responde com ufw: command not found. Instale-o também, o pacote existe nos quatro sistemas:
apt install -y ufw
ufw app list
ufw allow 'Nginx Full'
Os perfis vêm com o pacote nginx-common da distribuição: Nginx Full, Nginx HTTP e Nginx HTTPS, e no Debian 13 ainda Nginx QUIC. Instalado a partir do repositório nginx.org, nem sequer aparecem em ufw app list (ver a tabela acima).
Adicionar o repositório oficial do nginx
O nginx.org suporta bookworm, trixie, jammy e noble. O apt-key está descontinuado: a chave pertence a um keyring próprio e é referenciada através de signed-by.
apt install -y curl gnupg2 ca-certificates lsb-release debian-archive-keyring
No Ubuntu, o último pacote chama-se ubuntu-keyring em vez de debian-archive-keyring. Depois:
mkdir -p /root/.gnupg && chmod 700 /root/.gnupg
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | 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
O mkdir da primeira linha não é enchimento. Num servidor acabado de instalar, /root/.gnupg ainda não existe, e o gpg 2.4.7 do Debian 13 não cria o diretório por iniciativa própria nesta combinação exata de opções. O comando de verificação termina então com gpg: Fatal: /root/.gnupg: directory does not exist!, e fá-lo a meio da saída, ou seja, antes de as impressões digitais aparecerem. Quem as quiser ver tem de criar o diretório previamente; em alternativa basta executar gpg --list-keys uma única vez.
O último comando também não é enfeite, é a verificação a sério. Mostra três chaves, o que é intencional e não é motivo para desistir: a chave de assinatura atual 8540 A6F1 8833 A80E 9C16 53A4 2FD2 1310 B49F 6B46 (signing-key-2@nginx.com), mais 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62 e 9E9B E90E ACBC DE69 FE9B 204C BCDC D8A3 8D88 A2B3. Se aí aparecerem outras impressões digitais, o download entregou algo diferente do esperado e deve parar neste ponto.
Agora a fonte de pacotes. Repare no segmento de caminho a seguir a /packages/, porque o nginx.org mantém duas árvores de diretórios separadas para Debian e para Ubuntu. Em /packages/debian/dists/ não existe nem noble nem jammy: os pacotes do Ubuntu estão exclusivamente em /packages/ubuntu/. Esta versão define o segmento sozinha e por isso funciona sem alterações nas duas famílias:
OS=$(. /etc/os-release; echo $ID)
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/$OS $(lsb_release -cs) nginx" | tee /etc/apt/sources.list.d/nginx.list
$ID vale debian no Debian e ubuntu no Ubuntu, portanto o caminho ajusta-se automaticamente à distribuição. Se em vez disso escrever fixo packages/debian, porque está a seguir um guia de Debian num Ubuntu, o echo escreve a linha sem reclamar e o erro só surge no apt update seguinte:
Err: http://nginx.org/packages/debian noble Release
E: The repository 'http://nginx.org/packages/debian noble Release' does not have a Release file.
No Ubuntu 22.04 aparece aí jammy em vez de noble, mas a causa é a mesma. Para o ramo mainline, coloque mainline/ antes do nome da distribuição. E para que o apt prefira mesmo o pacote nginx.org ao da distribuição é preciso um pinning, caso contrário ganha o errado consoante o número de versão:
printf 'Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n' | tee /etc/apt/preferences.d/99nginx
apt update
apt-cache policy nginx
apt install -y nginx
apt-cache policy nginx é o controlo antes da instalação: como Candidate tem de constar a versão do nginx.org (por exemplo 1.30.4-1~noble) e como prioridade o 900 do ficheiro de pin. Se aí continuar a aparecer a versão da distribuição, o pinning não está a pegar e vai instalar já o pacote errado.
Mudar a partir de uma instalação já existente da distribuição
Se o pacote da distribuição já estiver a correr, a atualização falha. A mensagem é, no essencial, esta:
dpkg: error processing archive /var/cache/apt/archives/nginx_1.30.4-1~bookworm_amd64.deb (--unpack):
trying to overwrite '/etc/nginx/mime.types', which is also in package nginx-common 1.22.1-9+deb12u9
O pacote nginx.org não conhece nenhum nginx-common, por isso os ficheiros colidem. O caminho limpo: primeiro guardar a configuração, depois remover o pacote da distribuição e só então instalar de novo.
tar czf /root/nginx-config-backup.tar.gz /etc/nginx
systemctl stop nginx
apt purge -y nginx nginx-common
apt install -y nginx
Que o tar mostre pelo caminho tar: Removing leading '/' from member names é normal e não é um erro. Depois disso, /etc/nginx/sites-available desapareceu e os seus vHosts antigos só existem dentro do tarball. Copie-os para /etc/nginx/conf.d/ e dê-lhes a extensão .conf, caso contrário não são carregados. Tenha atenção a duas coisas: include snippets/fastcgi-php.conf; não existe no pacote nginx.org, e o utilizador do processo passa a chamar-se nginx, o que afeta as permissões dos ficheiros e os sockets do PHP-FPM.
Perceber bem sites-available e sites-enabled
O modelo de dois diretórios é uma invenção puramente do Debian, o próprio nginx não o conhece. Em /etc/nginx/sites-available/ estão todos os ficheiros de configuração, em /etc/nginx/sites-enabled/ estão ligações simbólicas para os que estão ativos. Só é carregado aquilo que consta do nginx.conf através de include. Em caso de dúvida, verifique-o diretamente:
grep include /etc/nginx/nginx.conf
No pacote do Debian e do Ubuntu estão aí duas linhas, include /etc/nginx/conf.d/*.conf; e include /etc/nginx/sites-enabled/*;. No pacote nginx.org está apenas a primeira. É precisamente daí que vem o clássico: alguém segue um guia de Ubuntu num pacote nginx.org, cria /etc/nginx/sites-available/meu-site, coloca a ligação simbólica, obtém um syntax is ok impecável com nginx -t e, ainda assim, não acontece nada. Não há mensagem de erro, porque o diretório simplesmente não interessa a ninguém.
A contraprova que diz sempre a verdade é nginx -T com T maiúsculo. Mostra a configuração completa já resolvida, ou seja, exatamente aquilo que o nginx vê de facto:
nginx -T | grep -n "server_name\|listen\|root"
Se o seu server_name não aparecer aí, o ficheiro não está a ser lido. Ponto final. Continuar a depurar a configuração em si é, nesse caso, perda de tempo.
O segundo erro frequente é uma ligação simbólica que aponta para o vazio, por exemplo depois de uma gralha ou porque o ficheiro de destino foi renomeado:
nginx: [emerg] open() "/etc/nginx/sites-enabled/meu-site" failed (2: No such file or directory) in /etc/nginx/nginx.conf:62
As ligações simbólicas partidas encontra-as com find /etc/nginx/sites-enabled/ -xtype l. E um site nunca se desativa apagando o ficheiro em sites-available, mas sim removendo a ligação simbólica com unlink /etc/nginx/sites-enabled/meu-site.
O primeiro bloco server próprio
Vamos criar um site estático. Primeiro o diretório e um ficheiro de teste:
mkdir -p /var/www/exemplo/html
echo '<h1>Página de teste da KernelHost</h1>' > /var/www/exemplo/html/index.html
chown -R www-data:www-data /var/www/exemplo
No pacote nginx.org, o proprietário é nginx:nginx. Agora a configuração, e mesmo como um passo à parte: o ficheiro tem de existir antes de a ligação simbólica apontar para ele. Crie-o com o editor ou escreva-o diretamente através de um heredoc; no pacote nginx.org vai antes para /etc/nginx/conf.d/exemplo.conf:
cat > /etc/nginx/sites-available/exemplo <<'EOF'
server {
listen 80;
listen [::]:80;
server_name exemplo.pt www.exemplo.pt;
root /var/www/exemplo/html;
index index.html;
access_log /var/log/nginx/exemplo.access.log;
error_log /var/log/nginx/exemplo.error.log;
location / {
try_files $uri $uri/ =404;
}
}
EOF
As aspas simples à volta de 'EOF' são importantes: sem elas, a shell substitui $uri por nada e o bloco já fica estragado no momento em que é gravado. Só depois é que se ativa, verifica e recarrega:
ln -s /etc/nginx/sites-available/exemplo /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
A ordem não é arbitrária. O ln cria a ligação simbólica mesmo quando o ficheiro de destino não existe, e sem dizer uma palavra. Isso só se descobre no teste:
nginx: [emerg] open() "/etc/nginx/sites-enabled/exemplo" failed (2: No such file or directory) in /etc/nginx/nginx.conf:61
O número da linha varia consoante o sistema (61 no Debian 13, 60 no Debian 12 e nos dois Ubuntu), mas a mensagem é idêntica. Um reload seria recusado neste estado, portanto a configuração em execução fica intacta. Este caso concreto também é detetado por find /etc/nginx/sites-enabled/ -xtype l.
Neste ponto surgem repetidamente mais três erros.
Servidor predefinido duplicado. Quem copia default_server de um guia, apesar de o site predefinido do Debian continuar ativo, recebe isto:
nginx: [emerg] a duplicate default server for 0.0.0.0:80 in /etc/nginx/sites-enabled/exemplo:2
Ou se omite a palavra-chave, ou se desativa o site predefinido com unlink /etc/nginx/sites-enabled/default.
Nome de servidor duplicado. Se o mesmo nome aparecer em dois blocos, ganha sem comentários o que for carregado primeiro e é emitido apenas um aviso:
nginx: [warn] conflicting server name "exemplo.pt" on 0.0.0.0:80, ignored
Nome de servidor demasiado longo. Com domínios longos ou muitos subdomínios:
nginx: [emerg] could not build server_names_hash, you should increase server_names_hash_bucket_size: 32
A solução é server_names_hash_bucket_size 64; no bloco http do nginx.conf.
A prova de funcionamento faz-se sem DNS, através do cabeçalho Host:
curl -H 'Host: exemplo.pt' -sS http://127.0.0.1/
Se aparecer o site predefinido do Debian em vez da sua página de teste, o seu bloco não está a pegar e acaba no servidor predefinido. Se aparecer a sua página, está tudo certo.
Integrar o PHP-FPM
Aqui espreita a armadilha mais desagradável de todo o guia, e custa uma hora a muita gente. O metapacote php depende, através de php8.x, da alternativa libapache2-mod-php8.x | php8.x-fpm | php8.x-cgi. O apt escolhe sempre a primeira, por isso apt install php instala fielmente o Apache também, e o Apache ocupa depois a porta 80. Instale por isso de forma seletiva:
apt install -y php-fpm php-mysql php-xml php-curl php-mbstring php-zip
A versão de PHP que recebe e o nome do socket dependem da distribuição:
| Sistema | PHP | Socket | Serviço |
| Debian 13 | 8.4 | /run/php/php8.4-fpm.sock | php8.4-fpm |
| Debian 12 | 8.2 | /run/php/php8.2-fpm.sock | php8.2-fpm |
| Ubuntu 24.04 | 8.3 | /run/php/php8.3-fpm.sock | php8.3-fpm |
| Ubuntu 22.04 | 8.1 | /run/php/php8.1-fpm.sock | php8.1-fpm |
Não adivinhe o caminho, leia-o:
ls -l /run/php/
O bloco PHP dentro do server (exemplo com Debian 12, adapte o caminho):
index index.php index.html;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.(?!well-known).* {
deny all;
}
No Debian e no Ubuntu pode substituir as primeiras linhas por include snippets/fastcgi-php.conf;. No pacote nginx.org esse snippet não existe, aí precisa da versão escrita por extenso. O try_files $uri =404; não é um recurso de estilo: impede que ficheiros carregados com um .php acrescentado no caminho sejam executados.
Falta ainda um passo, e é quase sempre saltado. A chamada de teste que se segue passa pelo vhost predefinido que vem de fábrica, e em /etc/nginx/sites-available/default a secção location ~ \.php$ está totalmente comentada de origem. Enquanto assim for, o nginx entrega os ficheiros .php sem alterações: recebe um 200 OK com Content-Type: application/octet-stream e o código-fonte PHP em texto simples. Isto não é um defeito estético. Num ficheiro real estão nesse sítio as credenciais da base de dados ou chaves de API, e lê-as toda a gente que conheça o URL.
Por isso, primeiro há que ativar o bloco. Em /etc/nginx/sites-available/default, retire os caracteres de comentário que o precedem ou escreva-o por extenso:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
}
O nome do socket depende da distribuição e consta da tabela acima: php8.4 no Debian 13, php8.3 no Ubuntu 24.04, php8.2 no Debian 12, php8.1 no Ubuntu 22.04. Depois, verificar e recarregar:
nginx -t
systemctl reload nginx
Só agora tem valor a prova de que o PHP corre mesmo através do FPM e de que não se está apenas a oferecer o download do ficheiro:
printf '<?php echo "PHP ", PHP_VERSION, " via ", php_sapi_name(), "\n";' > /var/www/html/kh-check.php
curl -s http://127.0.0.1/kh-check.php
rm /var/www/html/kh-check.php
O correto é uma saída do género PHP 8.4.23 via fpm-fcgi, e no Ubuntu 24.04 a equivalente PHP 8.3.6 via fpm-fcgi. Se em vez disso voltar o código-fonte, location ~ \.php$ ainda não está a pegar no vhost ativo, ou seja, continua comentado ou aponta para o socket errado. Não se esqueça de apagar o ficheiro, e não use phpinfo() num servidor acessível a partir do exterior.
Ler corretamente um 502 Bad Gateway
Um 502 não é um diagnóstico, o diagnóstico está em /var/log/nginx/error.log. Há três linhas típicas:
connect() to unix:/run/php/php8.2-fpm.sock failed (2: No such file or directory) while connecting to upstream
Caminho errado ou o FPM não está a correr. Verifique com systemctl status php8.2-fpm e ls /run/php/. Um desencadeador frequente é uma atualização de distribuição: depois do salto do Debian 12 para o 13, a configuração antiga continua a apontar para php8.2-fpm.sock, mas o que está instalado é o 8.4.
connect() to unix:/run/php/php8.2-fpm.sock failed (13: Permission denied) while connecting to upstream
Isto atinge quase exclusivamente instalações a partir do repositório nginx.org. O pool do FPM pertence a www-data e tem o modo 0660, mas aí o nginx corre como utilizador nginx. Defina em /etc/php/8.2/fpm/pool.d/www.conf o valor listen.group = nginx e reinicie o FPM.
FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream
SCRIPT_FILENAME aponta para o vazio. Na maioria dos casos, root está no bloco location em vez de estar no bloco server, ou falta por completo.
HTTPS com Let's Encrypt
As versões de certbot das distribuições estão muito afastadas: o Debian 13 traz a 4.0.0, o Ubuntu 24.04 a 2.9.0, o Debian 12 a 2.1.0 e o Ubuntu 22.04 apenas a 1.21.0. Todas falam ACMEv2, mas para funcionalidades mais recentes, como os certificados de vida curta, a 1.21 é demasiado antiga. No Ubuntu 22.04 compensa o desvio pelo snap.
apt install -y certbot python3-certbot-nginx
certbot --version
Antes da emissão têm de estar cumpridas três condições, caso contrário a validação falha sem uma mensagem aproveitável: o registo A (e, se aplicável, o AAAA) aponta para o servidor, a porta 80 está acessível a partir do exterior e existe um bloco server com o server_name correspondente. O último ponto é decisivo, porque o plugin do nginx localiza o bloco através de server_name e não através do nome do ficheiro. Depois:
certbot --nginx -d exemplo.pt -d www.exemplo.pt
A seguir, o certbot escreve no seu ficheiro de configuração: um segundo bloco server com listen 443 ssl, os caminhos para fullchain.pem e privkey.pem, um include /etc/letsencrypt/options-ssl-nginx.conf e um redirecionamento a partir da porta 80. O facto de o ficheiro ser alterado surpreende com regularidade. Quem o sobrescrever à mão depois disso perde o HTTPS e obtém no reload seguinte:
nginx: [emerg] cannot load certificate "/etc/letsencrypt/live/exemplo.pt/fullchain.pem": BIO_new_file() failed
A renovação automática funciona através de um timer do systemd, não através de um cronjob. Verifique as duas coisas:
systemctl list-timers | grep certbot
certbot renew --dry-run
A execução em seco é a única prova real de que a renovação vai funcionar daqui a noventa dias. Se usar o repositório nginx.org, desde o nginx 1.29 existe além disso, com nginx-module-acme, uma variante totalmente sem certbot, na qual o próprio nginx pede e renova os certificados.
nginx -t, reload e restart
A regra é simples e mesmo assim é violada constantemente: nunca faça reload sem um nginx -t prévio. Perante um erro de sintaxe, o nginx recusa-se a adotar a configuração estragada, mas com um restart o processo antigo já terminou e o site fica offline.
nginx -t
O esperado é exatamente isto:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
O reload arranca workers novos com a nova configuração e deixa os antigos terminarem de servir as ligações que têm abertas. Não se perde um único pedido. O restart só é necessário quando algo muda no próprio processo, por exemplo depois de uma atualização de pacotes, com um user alterado ou ao carregar diretivas load_module.
Se o arranque falhar, a saída do systemd é quase inútil:
Job for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xeu nginx.service" for details.
O texto aproveitável está um nível abaixo:
journalctl -xeu nginx.service --no-pager -n 30
Resolver o conflito de porta com o Apache na porta 80
O erro de nginx mais conhecido de todos:
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Note que nginx -t não encontra este erro, porque o teste não liga nenhuma porta. Só o arranque é que falha. Descubra primeiro quem detém a porta, em vez de adivinhar:
apt install -y iproute2
ss -tlnp | grep ':80'
A saída indica o processo em texto simples, tipicamente users:(("apache2",pid=612,fd=4)). Em nove de cada dez casos, o Apache entrou no sistema através de apt install php ou através de um painel de controlo. Há três saídas limpas.
Primeira, desligar o Apache. Se não precisa dele, basta desativá-lo para que não volte depois do próximo reinício:
systemctl disable --now apache2
systemctl start nginx
Segunda, remover o Apache. Atenção: se libapache2-mod-php depender dele, o apt purge apache2 pode levar o PHP à frente. Verifique a lista que o apt mostra antes da execução e instale o php-fpm a seguir.
Terceira, manter os dois em paralelo. Faz sentido quando os vHosts de Apache existentes com .htaccess devem continuar a funcionar e o nginx trabalha à frente como reverse proxy. Para isso, coloque em /etc/apache2/ports.conf um Listen 127.0.0.1:8080, altere em cada vHost <VirtualHost *:80> para <VirtualHost *:8080> e deixe o nginx encaminhar:
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Para que o Apache deixe de ver apenas 127.0.0.1 nos seus logs, ative aí o módulo remoteip. Sem esse passo, as regras do Fail2ban sobre os logs do Apache não valem nada, porque todos os pedidos parecem vir de localhost.
Duas variantes do mesmo erro passam facilmente despercebidas. Se a mesma entrada listen aparecer duplicada em dois ficheiros seus, o nginx comunica igualmente Address already in use, mesmo sem nenhum Apache envolvido. E no caso de bind() to [::]:80 failed só o IPv6 está afetado, normalmente porque um segundo bloco define também listen [::]:80 sem ipv6only=on.
A aceitação final: oito verificações em vez de intuição
Antes de dar uma instalação por concluída, percorra estes pontos. Cada um deles já evitou alguma vez uma falha silenciosa.
nginx -tcomunica test is successful.systemctl is-enabled nginxdevolveenabled, portanto o serviço volta depois de um reboot.ss -tlnp | grep nginxmostra a porta 80 e, se estiver configurada, a porta 443.nginx -T | grep server_namelista todos os domínios que devem funcionar.curl -I http://127.0.0.1/devolve um 200 ou um redirecionamento intencional.- O ficheiro de teste do PHP mostra
fpm-fcgie foi apagado a seguir. certbot renew --dry-runcorre sem erros./var/log/nginx/error.lognão contém entradas novas depois de um acesso de teste.
Num servidor acabado de instalar falta depois ainda a firewall; para isso consulte o nosso guia sobre a configuração do ufw. O Debian 10 e o Ubuntu 20.04 estão sem suporte desde junho de 2024 e maio de 2025, respetivamente, e já não recebem atualizações de segurança do nginx: aí, uma atualização não é uma questão de conforto, é algo que já vai tarde.
O que a KernelHost acrescenta
Nos servidores root KVM e nos servidores dedicados da KernelHost instala o Debian 13, o Debian 12, o Ubuntu 24.04 ou o Ubuntu 22.04 diretamente a partir da área de cliente e fica depois com acesso root completo, pelo que os passos descritos acima funcionam sem alterações. Os sistemas estão no datacenter maincubes em Frankfurt am Main (Alemanha), certificado pelo TÜV segundo a norma TIER3+ e ligado através da nossa própria rede. A proteção DDoS atua à frente do servidor e não apenas dentro do nginx: 3,2 Tbps de filtragem Arbor em tempo real diretamente na localização e, nos tarifários Professional, ainda até 17 Tbps de capacidade de filtragem global. Tudo funciona em regime PrePaid, ou seja, sem prazo mínimo, sem período de aviso prévio e sem taxa de instalação.
Perguntas frequentes
Devo instalar o nginx a partir do pacote da distribuição ou do repositório oficial nginx.org?
Porque é que o meu bloco server em sites-available é completamente ignorado, apesar de o nginx -t terminar com sucesso?
O nginx não arranca e indica bind() to 0.0.0.0:80 failed (98: Address already in use). O que fazer?
Que versão de PHP e que socket do FPM preciso na minha distribuição?
Como confirmo de forma fiável que o nginx está mesmo a funcionar e que não foi apenas o comando que correu?
2026 KernelHost GmbH. Todos os direitos reservados. Este guia está protegido por direitos de autor. A sua republicação noutros sites, na íntegra, em parte ou de forma editada, não é permitida sem o nosso consentimento por escrito. Citações com indicação da fonte e ligação são expressamente bem-vindas.

