Inicio Projetos Experiências Contato Code Lab
CI/CD Intermediário

CI/CD GIT ACTIONS + SSH + WEBHOOK

Publicado em 23/03/2026

Contexto e Motivação

Sempre que realizava alterações no sistema, era necessário acessar o servidor manualmente para atualizar os arquivos, tornando o processo lento e suscetível a erros.

Para resolver isso, implementei uma automação de deploy utilizando GitHub Actions, onde a cada push na branch principal o processo é executado automaticamente. A comunicação com o servidor é feita via SSH, garantindo segurança na execução dos comandos remotos.

Também integrei Webhooks para envio de notificações em tempo real sobre o status do deploy (sucesso ou falha), direcionadas para um canal no Discord, permitindo acompanhamento contínuo sem necessidade de acesso direto ao servidor.

Todo o fluxo foi configurado no arquivo .github/workflows/deploy.yml, e as credenciais sensíveis foram isoladas utilizando variáveis de ambiente do GitHub, garantindo maior segurança.

Implementação

Terminal
name: Deploy # Define o nome do workflow que aparecerá na interface do GitHub Actions

on:
  push:
    branches:
      - main # Dispara o deploy automaticamente sempre que houver um push na branch de produção

env:
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true # Garante compatibilidade das actions com a versão mais recente do Node.js no runner

jobs:
  deploy:
    name: Update Portfólio
    runs-on: ubuntu-latest # Utiliza uma máquina virtual Linux limpa para executar o processo
    environment: portifolio # Associa o job a um ambiente específico para gerenciar segredos de forma isolada

    steps:
      - name: Checkout code
        uses: actions/checkout@v4.2.2 # Baixa o código fonte do repositório para o runner do GitHub

      - name: Configure SSH Agent
        uses: webfactory/ssh-agent@v0.9.1 # Gerencia a chave privada SSH para autenticação segura sem senha
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

      - name: Add server to known_hosts
        run: |
          mkdir -p ~/.ssh
          echo "StrictHostKeyChecking no" >> ~/.ssh/config # Evita que o script pare pedindo confirmação manual da identidade do servidor

      - name: Sync files to server
        run: |
          rsync -avz --delete \
            --exclude='.git/' \
            --exclude='.github/' \
            --exclude='.env' \
            --exclude='*.log' \
            --exclude='vendor/' \
            -e "ssh -p ${{ secrets.SSH_PORT }} -o StrictHostKeyChecking=no" \
            ./ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.REMOTE_PATH }}/ # Sincroniza apenas arquivos alterados e remove deletados, otimizando o tempo de deploy

      - name: Create .env file on server
        run: |
          ssh -p ${{ secrets.SSH_PORT }} -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "cat > ${{ secrets.REMOTE_PATH }}/.env" << 'EOF'
          APP_NAME=${{ secrets.APP_NAME }}
          DB_HOST=${{ secrets.DB_HOST }}
          DB_NAME=${{ secrets.DB_NAME }}
          DB_USER=${{ secrets.DB_USER }}
          DB_PASS=${{ secrets.DB_PASS }}
          MAIL_HOST=${{ secrets.MAIL_HOST }}
          MAIL_PORT=${{ secrets.MAIL_PORT }}
          MAIL_USER=${{ secrets.MAIL_USER }}
          MAIL_PASS=${{ secrets.MAIL_PASS }}
          MAIL_FROM_NAME=${{ secrets.MAIL_FROM_NAME }}
          MAIL_FROM_ADDRESS=${{ secrets.MAIL_FROM_ADDRESS }}
          MAIL_TO_ADDRESS=${{ secrets.MAIL_TO_ADDRESS }}
          MAIL_ENCRYPTION=${{ secrets.MAIL_ENCRYPTION }}
          EOF # Reconstrói o arquivo de ambiente no servidor usando os segredos protegidos do GitHub

      - name: Pós-deploy
        run: |
          ssh -p ${{ secrets.SSH_PORT }} -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'EOF'
            cd ${{ secrets.REMOTE_PATH }}
            composer install --no-dev --optimize-autoloader # Instala dependências de produção e otimiza o carregamento das classes
            php migrate.php # Executa migrações de banco de dados para manter o esquema atualizado
          EOF

      - name: Deploy Confirmation
        run: echo "Deploy successful!"

      - name: Notify Discord
        uses: rjstone/discord-webhook-notify@v2
        if: always() # Garante que a notificação seja enviada tanto em caso de sucesso quanto em falha
        with:
          severity: ${{ job.status == 'success' && 'info' || 'error' }}
          details: ${{ job.status == 'success' && 'Deploy realizado com sucesso na branch Main!' || 'Falha no Deploy!' }}
          webhookUrl: ${{ secrets.DISCORD_WEBHOOK }}
          username: 'GitHub Action Bot' # Automatiza o feedback visual no Discord, evitando a necessidade de monitorar o painel do GitHub constantemente

Decisão Técnica

Automatizar o deploy com GitHub Actions elimina a necessidade de acesso manual ao servidor, reduzindo erros humanos e aumentando a velocidade de entrega. O uso de SSH permite uma comunicação segura e direta com o servidor de produção, mantendo o controle total do processo sem depender de ferramentas externas mais complexas.

A integração com Webhook foi adotada para fornecer feedback imediato sobre o status do deploy (sucesso ou falha), melhorando a visibilidade e permitindo ações rápidas em caso de erro. O envio dessas notificações para o Discord foi uma escolha prática, pois é uma ferramenta já presente no fluxo diário.

Além disso, a utilização de variáveis de ambiente no GitHub Actions garante maior segurança, evitando exposição de credenciais sensíveis no repositório.

Tecnologias

#CI/CD #GitHub Actions #Deploy Automatizado #SSH #Webhook #DevOps #Segurança