17 min de leitura · Guia técnico
webhooks para automatizar deploys são endpoints HTTP que recebem eventos de ferramentas externas, como repositórios Git, e acionam um script de publicação no servidor. Para configurar um deploy automático com webhook de forma segura, siga estes passos:
- Crie um usuário sem acesso interativo para executar apenas o deploy.
- Prepare um script de deploy com Git, permissões restritas e reinício controlado do serviço.
- Crie um endpoint webhook que valide um segredo antes de executar comandos.
- Publique o endpoint por HTTPS e limite o que ele pode executar.
- Cadastre a URL do webhook no repositório ou ferramenta de CI/CD.
- Teste o fluxo, valide logs e tenha um plano de rollback.
Pré-requisitos para usar webhooks para automatizar deploys
Deploy automático com Git exige que o servidor consiga receber uma requisição HTTP, validar a origem e executar uma sequência previsível de comandos. O exemplo abaixo usa Debian 12 como base, mas o fluxo também pode ser adaptado para Ubuntu 24.04 LTS, Rocky Linux 9 ou AlmaLinux 9, desde que você ajuste nomes de pacotes, usuário de serviço e caminhos da aplicação.
- Acesso SSH administrativo ao servidor onde a aplicação será publicada.
- Aplicação já versionada em um repositório Git e com uma branch de produção definida, como main.
- Domínio ou subdomínio com HTTPS para receber o webhook em produção.
- Git instalado no servidor e chave de deploy configurada para o repositório, quando o repositório for privado.
- Permissão para criar usuário de sistema, serviço systemd e script em diretórios como /opt/deploy e /var/www/app.
- Conhecimento do comando correto para recarregar sua aplicação, como reiniciar um serviço Node.js, PHP-FPM, worker, fila ou processo próprio.
Se você ainda está organizando o acesso ao servidor, veja também Acessando servidores VPS Linux da AviraHost. Em ambientes que ainda não têm uma base de hospedagem definida, o artigo Configurando um Servidor Linux para Hospedagem de Sites ajuda a entender a preparação inicial.
Criar usuário e diretórios para webhook deploy automático
Webhook deploy automático não deve rodar com root por padrão. A prática mais segura é criar um usuário de sistema dedicado, com diretórios próprios e permissão apenas no que ele precisa atualizar. Isso reduz o impacto de uma falha no script, de uma URL exposta incorretamente ou de uma tentativa de acionar comandos fora do fluxo esperado.
- Crie o usuário que executará o webhook e o script de deploy.
- Crie o diretório onde ficarão o endpoint e o script.
- Defina o dono correto dos arquivos.
sudo useradd --system --home /opt/deploy --shell /usr/sbin/nologin deploybot
sudo mkdir -p /opt/deploy
sudo chown -R deploybot:nogroup /opt/deploy
Output esperado:
nenhum erro exibido
diretorio /opt/deploy criado
usuario deploybot disponivel no sistema
Agora prepare o diretório da aplicação. Se ela já existe em /var/www/app, apenas confirme permissões. Se ainda não existe, clone o repositório como o usuário de deploy ou ajuste o dono após clonar. O ponto importante é que o script consiga executar git fetch e git reset sem pedir senha interativa.
sudo mkdir -p /var/www/app
sudo chown -R deploybot:nogroup /var/www/app
Output esperado:
nenhum erro exibido
diretorio da aplicacao pronto para receber arquivos
Atenção: não dê permissão ampla em todo o servidor para facilitar o deploy. Evite chmod 777, evite executar o webhook como root e limite o usuário de deploy ao diretório da aplicação e aos comandos estritamente necessários.
Preparar script de deploy no servidor com Git
Script de deploy no servidor deve ser simples, auditável e repetível. A ideia é que o webhook apenas chame esse script, enquanto o script concentra a lógica de atualização: entrar no diretório correto, buscar a branch de produção, aplicar a versão mais recente, instalar dependências quando necessário e recarregar o serviço da aplicação.
Atenção: o comando git reset --hard descarta alterações locais não commitadas no diretório da aplicação. Use somente em diretórios de deploy, nunca em uma pasta onde alguém edita arquivos manualmente em produção.
sudo tee /opt/deploy/deploy.sh > /dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
APP_DIR="/var/www/app"
BRANCH="main"
cd "$APP_DIR"
git fetch origin "$BRANCH"
git reset --hard "origin/$BRANCH"
if test -f package.json
then
npm install --omit=dev
fi
if test -f composer.json
then
composer install --no-dev --optimize-autoloader
fi
if systemctl list-unit-files | grep -q app.service
then
sudo systemctl reload-or-restart app.service
fi
echo "deploy concluido"
EOF
sudo chmod 750 /opt/deploy/deploy.sh
sudo chown deploybot:nogroup /opt/deploy/deploy.sh
Output esperado:
nenhum erro exibido
arquivo /opt/deploy/deploy.sh criado
permissao de execucao aplicada
Se sua aplicação usa outro fluxo, substitua os trechos de npm, composer e app.service pelos comandos reais do projeto. Para PHP 8.3 com PHP-FPM, por exemplo, o recarregamento pode ser feito no serviço PHP-FPM correspondente. Para Node.js, pode ser um serviço systemd próprio. Para uma aplicação estática, talvez o git reset já seja suficiente.
Quando o script precisar reiniciar um serviço com sudo, libere apenas o comando necessário para o usuário deploybot. O exemplo abaixo permite recarregar ou reiniciar somente app.service.
echo "deploybot ALL=NOPASSWD: /bin/systemctl reload-or-restart app.service" | sudo tee /etc/sudoers.d/deploybot
sudo chmod 440 /etc/sudoers.d/deploybot
Output esperado:
deploybot ALL=NOPASSWD: /bin/systemctl reload-or-restart app.service
permissao 440 aplicada ao arquivo sudoers
Teste o script manualmente antes de conectar o webhook. Ao rodar este comando, você verá o Git buscar a branch, atualizar os arquivos e imprimir a confirmação final.
sudo -u deploybot /opt/deploy/deploy.sh
Output esperado:
From repositorio-remoto
HEAD is now at codigo-do-commit mensagem-do-commit
deploy concluido
Criar endpoint webhook seguro com validação de segredo
Endpoint webhook seguro precisa validar um segredo antes de executar qualquer comando. Sem essa validação, qualquer pessoa que descubra a URL poderia tentar acionar o deploy. O exemplo a seguir cria um pequeno servidor HTTP local em Python que escuta apenas em 127.0.0.1, valida o cabeçalho X-Hub-Signature-256 e chama o script de deploy.
sudo tee /opt/deploy/webhook.py > /dev/null <<'PY'
#!/usr/bin/env python3
from http.server import BaseHTTPRequestHandler, HTTPServer
import hmac
import hashlib
import subprocess
import os
SECRET = os.environ.get("WEBHOOK_SECRET", "")
SCRIPT = "/opt/deploy/deploy.sh"
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
if self.path != "/deploy":
self.send_response(404)
self.end_headers()
self.wfile.write(b"not found")
return
length = int(self.headers.get("Content-Length", "0"))
body = self.rfile.read(length)
sent = self.headers.get("X-Hub-Signature-256", "")
expected = "sha256=" + hmac.new(SECRET.encode(), body, hashlib.sha256).hexdigest()
if not SECRET or not hmac.compare_digest(sent, expected):
self.send_response(403)
self.end_headers()
self.wfile.write(b"forbidden")
return
result = subprocess.run([SCRIPT], capture_output=True, text=True, timeout=300)
code = 200 if result.returncode == 0 else 500
self.send_response(code)
self.end_headers()
self.wfile.write(result.stdout.encode())
self.wfile.write(result.stderr.encode())
HTTPServer(("127.0.0.1", 9000), Handler).serve_forever()
PY
sudo chmod 750 /opt/deploy/webhook.py
sudo chown deploybot:nogroup /opt/deploy/webhook.py
Output esperado:
nenhum erro exibido
arquivo /opt/deploy/webhook.py criado
endpoint pronto para ser executado localmente
O endpoint foi deixado em 127.0.0.1 de propósito. Em produção, publique esse serviço atrás de um proxy HTTPS já configurado no servidor, expondo apenas o caminho /deploy. Se você precisa revisar redirecionamento seguro para HTTPS em sites existentes, consulte Como redirecionar um site http para https?.
Para manter o webhook ativo, crie uma unidade systemd. Troque o valor de WEBHOOK_SECRET por um segredo longo e exclusivo, diferente de senhas de usuário, banco de dados ou painel.
sudo tee /etc/systemd/system/webhook-deploy.service > /dev/null <<'EOF'
[Unit]
Description=Webhook de deploy automatico
After=network.target
[Service]
User=deploybot
Group=nogroup
Environment=WEBHOOK_SECRET=troque-este-segredo
ExecStart=/opt/deploy/webhook.py
Restart=always
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now webhook-deploy.service
sudo systemctl status webhook-deploy.service --no-pager
Output esperado:
Created symlink
Active: active running
Webhook de deploy automatico iniciado
Configurar webhook GitHub deploy VPS e testar o disparo
Webhook GitHub deploy VPS é um dos cenários mais comuns: a cada push em uma branch, o repositório envia uma requisição HTTP para o seu endpoint. A mesma lógica pode ser usada em outras ferramentas que enviem webhooks, desde que elas permitam configurar URL, evento, segredo e cabeçalhos compatíveis.
- No repositório, acesse a área de webhooks.
- Informe a URL pública HTTPS que aponta para o caminho /deploy.
- Configure o segredo igual ao WEBHOOK_SECRET do serviço.
- Selecione o evento de push ou o evento equivalente do seu fluxo.
- Restrinja o deploy à branch de produção no script ou na ferramenta externa.
Antes de depender do provedor Git, teste localmente a validação da assinatura. O comando abaixo gera uma assinatura HMAC para o corpo teste=1 e envia a requisição ao endpoint local.
SIGNATURE=$(printf "teste=1" | openssl dgst -sha256 -hmac "troque-este-segredo" | cut -d " " -f 2)
curl -X POST http://127.0.0.1:9000/deploy -H "X-Hub-Signature-256: sha256=$SIGNATURE" --data "teste=1"
Output esperado:
deploy concluido
Se o retorno for forbidden, o segredo usado para assinar a requisição não é o mesmo configurado no serviço. Se o retorno for not found, o caminho chamado não foi /deploy. Se o retorno for erro 500, o endpoint validou a assinatura, mas o script de deploy falhou; nesse caso, consulte os logs do systemd e rode o script manualmente como deploybot.
sudo journalctl -u webhook-deploy.service -n 80 --no-pager
Output esperado:
linhas recentes do servico webhook-deploy
status da requisicao recebida
mensagens do script quando houver falha
Boas práticas para automatizar deploy com webhook
Automatizar deploy com webhook melhora o fluxo de publicação, mas também aumenta a responsabilidade sobre permissões, logs e reversão. O objetivo não é executar qualquer comando remotamente; é permitir uma rotina pequena, previsível e segura, acionada por um evento confiável.
- Use HTTPS: o segredo não deve trafegar em texto aberto. Publique o endpoint apenas por HTTPS em produção.
- Valide assinatura: não confie apenas na URL obscura. A validação HMAC reduz o risco de acionamento indevido.
- Evite root: execute o webhook com usuário dedicado e sudo restrito somente quando necessário.
- Separe ambientes: use endpoints e segredos diferentes para staging e produção.
- Controle branch: o script deve puxar apenas a branch esperada, como main, evitando deploy acidental de branches de teste.
- Registre logs: mantenha journalctl, logs da aplicação e saída do script suficientes para diagnosticar falhas.
- Tenha rollback: saiba voltar para um commit anterior antes de automatizar publicações em produção.
Também vale manter o script pequeno. Se o deploy exige build pesado, migrações sensíveis ou múltiplos serviços, considere dividir etapas: build em pipeline, artefato versionado e apenas sincronização no servidor. Isso reduz o tempo de execução do webhook e diminui a chance de timeout durante a requisição.
Problemas comuns e como resolver
Sintoma: o webhook retorna forbidden
Causa: a assinatura enviada no cabeçalho não corresponde ao corpo da requisição ou o segredo configurado no repositório é diferente do WEBHOOK_SECRET do serviço.
Solução: gere novamente o segredo, atualize o serviço systemd, rode sudo systemctl daemon-reload quando alterar a unidade e reinicie o serviço. Depois teste com curl usando exatamente o mesmo corpo enviado na assinatura.
Sintoma: o deploy funciona manualmente, mas falha pelo webhook
Causa: o ambiente do systemd é mais restrito do que o shell interativo. Caminhos, variáveis, permissões de chave SSH ou acesso ao Git podem estar disponíveis para seu usuário, mas não para deploybot.
Solução: rode o script com sudo -u deploybot, corrija permissões em /var/www/app e confirme que o usuário de deploy consegue executar git fetch sem solicitar senha. Use journalctl para ver a saída real do serviço.
Sintoma: o repositório envia o evento, mas nada muda no site
Causa: o webhook pode estar chamando a URL errada, a branch configurada no script pode não ser a branch que recebeu push ou a aplicação pode depender de cache, build ou recarregamento de serviço.
Solução: confirme o caminho /deploy, verifique a branch definida em BRANCH, acompanhe o commit exibido pelo git reset e adicione ao script os comandos necessários para limpar cache, instalar dependências ou recarregar o serviço correto.
Sintoma: o endpoint demora e a ferramenta marca timeout
Causa: o script está executando etapas demoradas, como instalação de muitas dependências, build completo ou migrações longas dentro da requisição HTTP.
Solução: reduza o trabalho do webhook. Deixe builds para uma pipeline externa, use artefatos prontos quando possível e mantenha o endpoint apenas como gatilho de atualização controlada no servidor.
Perguntas frequentes sobre webhooks para automatizar deploys
O que é um webhook para deploy automático?
Um webhook para deploy automático é uma chamada HTTP enviada por uma ferramenta externa, como um repositório Git, para avisar o servidor que uma ação deve ser executada. Na prática, ele pode acionar um script de atualização da aplicação, reiniciar serviços ou sincronizar arquivos sem exigir login manual a cada alteração.
Webhook é seguro para automatizar deploy em produção?
Webhook pode ser seguro quando usa HTTPS, segredo de validação, permissões restritas e scripts bem definidos. O risco aumenta quando o endpoint fica público sem autenticação, executa comandos amplos demais ou roda com usuário root sem necessidade.
Preciso usar Git para trabalhar com webhooks de deploy?
Git não é obrigatório, mas é um dos usos mais comuns porque permite acionar o deploy quando há push em uma branch específica. Também é possível usar webhooks com pipelines, painéis internos, sistemas de CI/CD ou ferramentas de automação que enviem requisições HTTP.
Qual a diferença entre webhook e cron job no deploy?
Webhook executa o deploy quando um evento acontece, como um push no repositório. Cron job executa em horários definidos, mesmo que nada tenha mudado, por isso é menos imediato e pode gerar execuções desnecessárias dependendo do fluxo.
Posso usar webhooks em hospedagem compartilhada?
Depende dos recursos disponíveis no plano, como suporte a scripts, acesso SSH, execução de comandos e permissões do ambiente. Em projetos que exigem controle de serviços, filas, processos e scripts de deploy mais avançados, um VPS costuma oferecer mais flexibilidade.
Conclusão
- Crie um usuário dedicado, com permissões mínimas, para executar o webhook e o script de deploy.
- Valide todo disparo com segredo, HTTPS e logs antes de habilitar o fluxo em produção.
- Teste rollback, branch, permissões e reinício de serviços antes de depender do deploy automático no dia a dia.
Leia também
- Docker para ambiente de desenvolvimento no VPS
- Otimizar MySQL: como reduzir uso de memória e acelerar consultas
- Entenda o que é Swap no Linux: como funciona e quando usar
Precisa de ajuda com webhooks para automatizar deploys?
Um VPS bem configurado oferece mais controle para scripts, serviços systemd, Git e automações de deploy. Se o seu projeto precisa sair do deploy manual para um fluxo mais previsível, escolha uma infraestrutura que permita esse nível de administração.