Nginx como proxy reverso à frente de um contêiner

Node.js, Python e Docker··· 401 visualizações· 4 min de leitura

Um proxy reverso é o nginx a receber os pedidos nas portas 80 e 443, com o seu domínio, e a entregá-los à aplicação que está em outra porta, dentro do servidor. É o desenho normal para pôr um contêiner na internet: a aplicação fica escondida em 127.0.0.1, e o nginx trata do domínio e do HTTPS. Este artigo é para um VPS seu, com Ubuntu 22.04 LTS e a aplicação já a rodar num contêiner (exemplo com Compose).

Montar o proxy

1 Aponte o nome para o VPS. Crie um registro A de, por exemplo, app.yourcompany.com para o IP do VPS, e espere que se propague: apontar um domínio ao seu VPS.
2 Publique a aplicação só no próprio servidor. No Compose: "127.0.0.1:3000:3000". Assim só o nginx lhe chega.
3 Instale o nginx: sudo apt install nginx.
4 Crie o arquivo do site, com sudo nano /etc/nginx/sites-available/app:server {
    listen 80;
    server_name app.yourcompany.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        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;
    }
}
5 Active, teste e recarregue: sudo ln -s /etc/nginx/sites-available/app /etc/nginx/sites-enabled/app
sudo nginx -t
sudo systemctl reload nginx
O nginx -t confere a sintaxe antes de recarregar. Se mostrar «syntax is ok», pode recarregar.
6 Abra as portas 80 e 443 na firewall: sudo ufw allow 80/tcp e sudo ufw allow 443/tcp. Veja portas e firewall.
7 Ponha o HTTPS com o certbot: HTTPS para um contêiner.

Os erros que aparecem

O que vê Causa habitual O que fazer
502 Bad Gateway O nginx não consegue falar com a aplicação: contêiner parado, ou porta errada. docker ps e confira a porta no proxy_pass.
504 Gateway Time-out A aplicação demora mais do que o nginx espera. Veja o que a aplicação faz e os registros dela. Só depois pense em subir os tempos do nginx.
A página de boas-vindas do nginx O pedido não casou com o server_name, ou o site por padrão ficou ativo. Confira o nome e o DNS. Retire o site por padrão: sudo rm /etc/nginx/sites-enabled/default (é só a ligação).
413 Request Entity Too Large Um envio maior do que o nginx aceita. Acrescente client_max_body_size no bloco server com o tamanho que precisa.
Ciclo de redirecionamentos A aplicação não sabe que o visitante veio por HTTPS. Confirme o X-Forwarded-Proto e configure a aplicação para o respeitar.

Os logs de erros do nginx ficam em /var/log/nginx/error.log. Se a aplicação usa websockets (conversas ao vivo, painéis que atualizam sozinhos), acrescente ao bloco location as linhas proxy_http_version 1.1;, proxy_set_header Upgrade $http_upgrade; e proxy_set_header Connection "upgrade";.

Não deixe a aplicação também aberta numa porta pública. Se o contêiner publica 3000:3000 (sem o 127.0.0.1), o Docker abre essa porta a todo mundo, mesmo que o ufw diga o contrário, e o proxy passa a ser só um enfeite. É a falha mais frequente deste desenho.
Pode também usar o Caddy ou o Traefik em vez do nginx: tratam do HTTPS por si. O nginx tem a vantagem de ser o mais documentado. Num VPS não gerenciado, qualquer dos três é seu de instalar e manter: até onde vai o nosso suporte.

O domínio já aponta para o VPS mas o servidor não responde nem ao ping? Isso verificamos nós.

Abrir um pedido de suporte

VEJA TAMBÉM

HTTPS para um contêiner: um certificado e um domínio

Portas e firewall num VPS: porque a aplicação não é alcançável

Apontar um domínio ao seu VPS: nameservers e registros glue

Mais sobre Node.js, Python e Docker

Mais artigos sobre o mesmo assunto, para quando este não chega.

PRODUTO RECOMENDADO

Servidor VPS com acesso root

Recursos só seus, o sistema que escolher, reinstalação quando quiser. desde R$ 46,20/mês (plano de 3 anos, com cupom)

Ver planos
Esta resposta foi útil? Sua resposta nos ajuda a melhorar este artigo.