Docker: Integração CI/CD

Última atualização: 2026-08-26

Push de código → teste automatizado → build automatizado de imagem → implantação automatizada — o CI/CD transforma o processo de lançamento de operações manuais em um pipeline automatizado.

1. O Que Você Vai Aprender



2. Uma História Real de uma Pessoa Desenvolvedora

(1) Ponto de Dor: Operações SSH manuais necessárias para cada implantação

Toda vez que implanta, Alice precisa manualmente fazer SSH no servidor, puxar o código, construir a imagem e reiniciar o contêiner. O processo é: ssh server → git pull → docker build → docker stop → docker run. Cada implantação leva 15 minutos e, com 3–4 lançamentos por semana, ela desperdiça um total de 1 hora por semana em tarefas repetitivas. Para piorar, uma vez ela acidentalmente digitou o comando errado durante um lançamento noturno.

(2) Uma Solução Usando GitHub Actions CI/CD

Bob escreveu um fluxo de trabalho usando GitHub Actions: push de código → teste automatizado → build da imagem → push para o repositório → implantação via SSH.

YAML
# .github/workflows/deploy.yml
name: Build and Deploy
on:
  push:
    branches: [main]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/build-push-action@v5
        with:
          push: true
          tags: myorg/myapp:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

(3) Tempo gasto: 1 hora/semana → 0 minutos

A implantação é totalmente automatizada — Alice simplesmente faz push do código, e ele entra no ar automaticamente em 5 minutos. O trabalho manual foi reduzido de 1 hora por semana para 0, com zero erro humano.



3. Estrutura do Fluxo de Trabalho do GitHub Actions

(1) Estrutura YAML do Workflow

100%
graph LR
    PUSH["git push"] --> TRIGGER["on: push"]
    TRIGGER --> JOB1["Job: test"]
    JOB1 --> JOB2["Job: build"]
    JOB2 --> JOB3["Job: deploy"]
Campo Propósito Exemplo
name Nome do Workflow Build and Deploy
on Condição de Disparo push, pull_request
jobs Definição de Tarefas build, test, deploy
runs-on Ambiente de Execução ubuntu-latest
steps Etapas de execução checkout, build, push

(1) Comparação de Três Estratégias de CI/CD

Plataforma Características Casos de Uso
GitHub Actions Integração nativa com GitHub, 2.000 minutos grátis/mês Projetos open-source + hospedagem GitHub
GitLab CI Nativo do GitLab, Runner auto-hospedado GitLab on-premises
Jenkins Plataforma CI/CD consolidada com ampla gama de plugins Empresas tradicionais + pipelines complexos


4. Builds Multiplataforma com Docker buildx

▶ Exemplo: Builds multi-arquitetura com buildx (Dificuldade: ⭐⭐⭐)

BASH
# Criar instância do builder buildx
docker buildx create --name multiarch --use

# Construir para amd64 + arm64 simultaneamente
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t myorg/myapp:latest \
  --push .

# Inspecionar plataformas construídas
docker buildx imagetools inspect myorg/myapp:latest

(1) buildx vs Build Comum

Dimensão docker build docker buildx
Múltiplas Arquiteturas ❌ Só pode construir a arquitetura atual ✅ Construir múltiplas arquiteturas simultaneamente
Exportação de Cache ❌ Cache Local ✅ gha/registry/s3
Formato de Saída Imagem Local Image/OCI/tar/registry
Build Paralelo


5. Estratégia de Cache no CI

(1) Comparação de Tipos de Cache

Tipo Sintaxe Localização Cenários de Uso
gha cache-from: type=gha Cache do GitHub Actions GitHub Actions CI
registry cache-from: type=registry Docker Registry Qualquer Plataforma CI
local cache-from: type=local Sistema de arquivos local Runner Auto-hospedado

▶ Exemplo: Configuração de Cache no CI (Dificuldade: ⭐⭐⭐)

YAML
# GitHub Actions com cache de build
- uses: docker/build-push-action@v5
  with:
    context: .
    push: true
    tags: myorg/myapp:${{ github.sha }}
    cache-from: type=gha
    cache-to: type=gha,mode=max

▶ Exemplo: Política de Tagging Automático (Dificuldade: ⭐⭐)

YAML
# Ação de metadados Docker para tagging automático
- uses: docker/metadata-action@v5
  id: meta
  with:
    images: myorg/myapp
    tags: |
      type=sha,prefix=
      type=ref,event=branch
      type=semver,pattern={{version}}
      type=raw,value=latest,enable={{is_default_branch}}


6. Etapas para Implantação via SSH

▶ Exemplo: Implantando via SSH em um Servidor (Dificuldade: ⭐⭐⭐)

YAML
# Etapa de deploy no GitHub Actions
- name: Deploy to server
  uses: appleboy/ssh-action@v1
  with:
    host: ${{ secrets.SERVER_HOST }}
    username: ${{ secrets.SERVER_USER }}
    key: ${{ secrets.SSH_PRIVATE_KEY }}
    script: |
      cd /opt/myapp
      docker compose pull
      docker compose up -d --remove-orphans
      docker image prune -f
🔒 Segurança: Armazene informações sensíveis, como endereços de servidor e chaves SSH, usando GitHub Secrets; não as inclua no arquivo YAML. Adicione-as em Settings → Secrets and variables → Actions.



7. Exemplo Completo: CI/CD para uma Aplicação Node.js

YAML
# ============================================
# .github/workflows/deploy.yml
# CI/CD completo: test → build → push → deploy
# ============================================

name: CI/CD Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

env:
  REGISTRY: docker.io
  IMAGE_NAME: myorg/myapp

jobs:
  # ---------- Job 1: Test ----------
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run tests
        run: |
          docker build --target builder -t test-image .
          docker run test-image npm test

  # ---------- Job 2: Build & Push ----------
  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.event_name == 'push'
    steps:
      - uses: actions/checkout@v4

      - uses: docker/setup-buildx-action@v3

      - uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - uses: docker/metadata-action@v5
        id: meta
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=sha,prefix=
            type=raw,value=latest

      - uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

  # ---------- Job 3: Deploy ----------
  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /opt/myapp
            docker compose pull
            docker compose up -d --remove-orphans
            docker image prune -f
            echo "Deployed at $(date)"

❓ Perguntas Frequentes

P: Qual é a diferença entre buildx e um build comum? R: buildx é uma extensão CLI para o Docker BuildKit. Suas principais vantagens são: ① Builds simultâneos para múltiplas arquiteturas (amd64+arm64); ② Exportação avançada de cache (gha/registry); ③ Builds paralelos. O GitHub Actions recomenda sempre usar buildx.

P: Como compartilhar caches de camadas Docker no CI? R: Use cache-from: type=gha (GitHub Actions) ou type=registry (uso geral). Os caches GHA são armazenados no Cache do GitHub Actions e são automaticamente compartilhados entre fluxos de trabalho no mesmo repositório. Os caches de registro são armazenados em um manifesto especial dentro do registro e podem ser usados por qualquer plataforma de CI.

P: Como construo imagens multi-arquitetura? R: docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest --push .. Você precisará do emulador QEMU (docker/setup-qemu-action) e do builder buildx. A saída do build é uma lista de manifestos, que seleciona automaticamente a imagem para a arquitetura atual durante docker pull.

P: Como as credenciais sensíveis são gerenciadas no CI/CD? R: GitHub Secrets (Settings → Secrets). Chaves SSH, senhas de banco de dados e credenciais de registro são todas armazenadas em Secrets e referenciadas no YAML usando ${{ secrets.XXX }}. Secrets são armazenadas de forma criptografada e automaticamente mascaradas nos logs.

P: Como posso reverter automaticamente em caso de falha na implantação? R: Existem duas maneiras: ① Adicione uma verificação de saúde ao script de implantação; se falhar, use docker compose rollback (Swarm) ou alterne manualmente para a versão anterior; ② Mantenha as últimas N versões com tag na imagem; para reverter, simplesmente use docker compose up -d myapp:previous-sha. O rollback automático é suportado nativamente no Swarm e K8s.


📖 Resumo


📝 Exercícios

  1. Exercício Básico (Dificuldade: ⭐): Escreva um fluxo de trabalho GitHub Actions de build para a aplicação Flask da Aula 12, para que ela construa e faça push da imagem automaticamente quando um commit for enviado para a branch main.
  2. Exercício Avançado (Dificuldade: ⭐⭐): Use buildx para construir uma imagem de arquitetura dupla amd64+arm64 e envie para o Docker Hub.
  3. Desafio (Dificuldade: ⭐⭐⭐): Configure um pipeline CI/CD completo (test → build → implantação via SSH), use GitHub Secrets para gerenciar chaves do servidor e verifique se a implantação ocorre automaticamente após um push.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%