Pular para o conteúdo

guia: como usar webhooks para automatizar deploys

Por Equipe Técnica AviraHost · 17 min de leitura · Atualizado em · webhooks, deploy, automacao, git, linux, seguranca, AviraHost · 0

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:

  1. Crie um usuário sem acesso interativo para executar apenas o deploy.
  2. Prepare um script de deploy com Git, permissões restritas e reinício controlado do serviço.
  3. Crie um endpoint webhook que valide um segredo antes de executar comandos.
  4. Publique o endpoint por HTTPS e limite o que ele pode executar.
  5. Cadastre a URL do webhook no repositório ou ferramenta de CI/CD.
  6. 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.

  1. Crie o usuário que executará o webhook e o script de deploy.
  2. Crie o diretório onde ficarão o endpoint e o script.
  3. 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.

  1. No repositório, acesse a área de webhooks.
  2. Informe a URL pública HTTPS que aponta para o caminho /deploy.
  3. Configure o segredo igual ao WEBHOOK_SECRET do serviço.
  4. Selecione o evento de push ou o evento equivalente do seu fluxo.
  5. 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

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.

Conheça os planos de Servidor VPS da AviraHost


Esta resposta foi útil?