Deploy Automatizado com GitHub Actions e Docker: Tutorial Passo a Passo

10/10/2026  ·  Devskin

Deploy Automatizado com GitHub Actions e Docker: Tutorial Passo a Passo

Um deploy automatizado elimina a etapa manual mais frágil do ciclo de entrega: o acesso ao servidor por SSH para copiar arquivos, reiniciar serviços e torcer para que nada quebre. Neste tutorial, você vai montar um fluxo completo com GitHub Actions, Docker e um servidor Linux, com health check e rollback básico. É uma base enxuta, ideal para times de TI que ainda não precisam de Kubernetes, mas já não aceitam deploy manual.

Arquitetura do deploy automatizado

Antes de escrever qualquer configuração, é importante entender o fluxo. A cada push na branch main, o pipeline executa estas etapas:

  • Build: o GitHub Actions constrói a imagem Docker a partir do Dockerfile do repositório.
  • Publicação: a imagem vai para um registry (aqui, o GitHub Container Registry), com o SHA do commit como tag.
  • Release: o runner acessa o servidor via SSH e executa um script que baixa a nova imagem e troca o contêiner.
  • Verificação: o script consulta um endpoint de saúde e, se falhar, restaura a versão anterior.

Usar o SHA do commit como tag, e não latest, garante rastreabilidade: você sempre sabe qual código está em produção e consegue reverter para uma versão exata.

Passo 1: Dockerfile e endpoint de saúde

O primeiro requisito de qualquer deploy automatizado confiável é uma aplicação que informe se está saudável. Exponha uma rota como /health que retorne HTTP 200 quando a aplicação estiver pronta, validando dependências críticas como o banco de dados. Um Dockerfile simples para uma aplicação Node.js seria:

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

Ajuste a imagem base e o comando de inicialização para a sua stack. O princípio vale para qualquer linguagem: dependências em camadas separadas aproveitam o cache de build e reduzem o tempo do pipeline.

Passo 2: Preparar o servidor e a chave SSH

No servidor Linux, instale o Docker e crie um usuário dedicado, sem privilégios de root:

  • Crie o usuário deploy e adicione-o ao grupo docker.
  • Gere um par de chaves ed25519 exclusivo para o pipeline e adicione a chave pública em ~/.ssh/authorized_keys.
  • Faça docker login ghcr.io no servidor com um token com permissão apenas de leitura de pacotes.
  • Armazene a chave privada, o host e o usuário como secrets do repositório (SSH_KEY e HOST).

Atenção: membros do grupo docker têm, na prática, poder equivalente ao root na máquina. Por isso, a chave do pipeline deve ser exclusiva e fácil de revogar.

Passo 3: Script de release com rollback

Salve este script em /opt/app/deploy.sh no servidor. Ele recebe a imagem completa como argumento, sobe o novo contêiner e valida a saúde:

#!/usr/bin/env bash
set -euo pipefail
IMAGE="$1"
PREV=$(docker inspect --format '{{.Config.Image}}' app 2>/dev/null || true)
docker pull "$IMAGE"
docker rm -f app 2>/dev/null || true
docker run -d --name app -p 3000:3000 --restart unless-stopped "$IMAGE"
for i in $(seq 1 15); do
  if curl -fsS http://localhost:3000/health; then exit 0; fi
  sleep 2
done
echo 'Health check falhou' >&2
docker rm -f app
if [ -n "$PREV" ]; then
  docker run -d --name app -p 3000:3000 --restart unless-stopped "$PREV"
fi
exit 1

O script guarda a imagem anterior antes de remover o contêiner. Se o health check não responder com sucesso após cerca de 30 segundos, ele restaura a versão anterior e retorna erro, fazendo o job do GitHub Actions falhar e sinalizando o problema ao time.

Passo 4: Workflow do GitHub Actions

Crie o arquivo .github/workflows/deploy.yml. Este é o núcleo do deploy automatizado:

name: deploy
on:
  push:
    branches: [main]
permissions:
  contents: read
  packages: write
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v5
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
      - name: Deploy via SSH
        run: |
          mkdir -p ~/.ssh
          echo '${{ secrets.SSH_KEY }}' > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          ssh-keyscan -H ${{ secrets.HOST }} >> ~/.ssh/known_hosts
          ssh deploy@${{ secrets.HOST }} '/opt/app/deploy.sh ghcr.io/${{ github.repository }}:${{ github.sha }}'

Dois cuidados práticos: o nome do repositório no GHCR precisa estar em minúsculas, e vale conferir as versões atuais das actions na documentação oficial antes de adotar o arquivo em produção. Para maior segurança, registre a fingerprint do host como secret em vez de depender apenas do ssh-keyscan.

Trade-offs e quando evoluir

Esse modelo é simples e barato, mas tem limites claros:

  • Downtime curto: como o contêiner é substituído, há uma breve janela de indisponibilidade. Blue/green com proxy reverso (Nginx ou Traefik) resolve isso.
  • Servidor único: não há alta disponibilidade. Para múltiplos nós, considere orquestração com Kubernetes ou Nomad.
  • Estado fora do pipeline: migrações de banco precisam de estratégia própria, de preferência compatíveis com versões consecutivas da aplicação.
  • Infraestrutura manual: o servidor foi preparado à mão. Padronize-o depois, como mostra o review técnico do Terraform para times de TI.

Vale também observar que o mesmo raciocínio se aplica a tarefas repetitivas fora do código. Se você quer expandir a automação para outras rotinas da empresa, leia sobre como automatizar processos internos com IA sem depender de agência.

Conclusão

Com um Dockerfile, um registry, um script de release e um workflow de poucas linhas, você já tem um deploy automatizado rastreável, repetível e com rollback básico. Comece por esse modelo, meça o tempo de entrega e a taxa de falhas no seu contexto e só então avance para estratégias mais sofisticadas, como blue/green ou orquestração. Automatizar cedo é o que libera o time de TI para focar no que gera valor de verdade.

Contact

Send a message

Get in touch