Como usar o GitHub Actions para publicar imagens Docker no ECR e GCR

1. Introdução ao cenário de publicação multi-cloud

Publicar imagens Docker em múltiplos registries de nuvem, como Amazon ECR (Elastic Container Registry) e Google Container Registry (GCR), é uma prática essencial para organizações que operam em ambientes multi-cloud ou que desejam garantir alta disponibilidade e resiliência. Essa estratégia permite que equipes de desenvolvimento implantem aplicações em diferentes provedores de nuvem sem depender de um único ponto de falha, além de facilitar a migração gradual entre plataformas.

O GitHub Actions atua como orquestrador de CI/CD, oferecendo um ecossistema robusto de ações pré-construídas que simplificam a automação de builds e deploys. Com ele, é possível configurar pipelines que constroem imagens Docker, autenticam-se em registries de nuvem e publicam as imagens de forma consistente.

Pré-requisitos para este tutorial:
- Contas ativas na AWS e no GCP
- Repositório no GitHub com permissão para usar Actions
- Docker instalado localmente para testes
- Conhecimento básico de YAML e Dockerfile

2. Configuração de credenciais e autenticação nos provedores de nuvem

Antes de criar o workflow, é necessário configurar as credenciais de acesso como secrets no GitHub. No repositório, vá em Settings > Secrets and variables > Actions e adicione:

  • AWS_ACCESS_KEY_ID e AWS_SECRET_ACCESS_KEY: chaves de acesso IAM da AWS com permissões para ECR (política AmazonEC2ContainerRegistryFullAccess)
  • GCP_SA_KEY: chave JSON de uma service account do GCP com permissões para GCR (roles Storage Object Admin e Artifact Registry Writer)
  • AWS_REGION: região onde o ECR está configurado (ex: us-east-1)
  • GCP_PROJECT_ID: ID do projeto no GCP

Para autenticação no ECR, utiliza-se o comando aws ecr get-login-password combinado com o Docker. No GCR, o comando gcloud auth configure-docker registra o autenticador. No GitHub Actions, essas etapas são abstraídas por ações oficiais.

3. Estrutura do workflow do GitHub Actions para build Docker

O workflow é definido em um arquivo YAML dentro de .github/workflows/. Exemplo básico de estrutura:

name: Publicar Docker Multi-Cloud

on:
  push:
    branches:
      - main
    tags:
      - 'v*'
  pull_request:
    branches:
      - main

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        environment: [dev, staging, prod]
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3

O gatilho push na branch main e em tags semânticas (v*) ativa o pipeline. A matriz de ambientes permite criar versões separadas para dev, staging e produção, cada uma com tags específicas.

4. Publicação de imagem no Amazon ECR

A publicação no ECR utiliza a ação oficial aws-actions/amazon-ecr-login para autenticação. O workflow inclui build com metadados (SHA do commit e versão semântica) e push para o repositório.

- name: Configurar credenciais AWS
  uses: aws-actions/configure-aws-credentials@v4
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: ${{ secrets.AWS_REGION }}

- name: Login no Amazon ECR
  id: login-ecr
  uses: aws-actions/amazon-ecr-login@v2

- name: Build e push para ECR
  uses: docker/build-push-action@v5
  with:
    context: .
    push: true
    tags: |
      ${{ steps.login-ecr.outputs.registry }}/meu-app:${{ matrix.environment }}-${{ github.sha }}
      ${{ steps.login-ecr.outputs.registry }}/meu-app:${{ matrix.environment }}-latest
    cache-from: type=gha
    cache-to: type=gha,mode=max

A tag ${{ github.sha }} garante rastreabilidade exata do commit, enquanto latest oferece uma referência móvel para o ambiente específico. O cache com type=gha acelera builds subsequentes.

5. Publicação de imagem no Google Container Registry (GCR)

Para o GCR, a autenticação é feita via google-github-actions/auth, que carrega a service account. O build e push seguem padrão semelhante, mas com sufixo regional.

- name: Autenticar no Google Cloud
  uses: google-github-actions/auth@v2
  with:
    credentials_json: ${{ secrets.GCP_SA_KEY }}

- name: Configurar Docker para GCR
  run: gcloud auth configure-docker gcr.io,us.gcr.io --quiet

- name: Build e push para GCR
  uses: docker/build-push-action@v5
  with:
    context: .
    push: true
    tags: |
      gcr.io/${{ secrets.GCP_PROJECT_ID }}/meu-app:${{ matrix.environment }}-${{ github.sha }}
      us.gcr.io/${{ secrets.GCP_PROJECT_ID }}/meu-app:${{ matrix.environment }}-latest

O sufixo regional (gcr.io ou us.gcr.io) permite controle de localização geográfica. Para consistência, as tags devem espelhar as mesmas versões publicadas no ECR.

6. Otimizações e boas práticas no pipeline

Para melhorar desempenho e segurança, implemente as seguintes otimizações:

Cache de camadas Docker: Utilize docker/build-push-action com cache inline e GitHub Actions cache. Isso reduz o tempo de build em até 70% em pipelines consecutivos.

- name: Build com cache
  uses: docker/build-push-action@v5
  with:
    cache-from: type=gha
    cache-to: type=gha,mode=max

Multi-stage builds: No Dockerfile, separe etapas de build e runtime para minimizar o tamanho da imagem final.

# Estágio de build
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o meuapp

# Estágio final
FROM alpine:3.19
COPY --from=builder /app/meuapp /usr/local/bin/
CMD ["meuapp"]

Versionamento: Use tags imutáveis (SHA do commit) para deploys controlados e tags móveis (latest, stable) para ambientes de desenvolvimento. Evite sobrescrever tags em produção sem validação.

7. Tratamento de erros e notificações

Para garantir robustez, inclua validação de falhas e notificações automáticas.

Rollback automático: Caso o push para um registry falhe, o workflow pode reverter a tag do outro registry para a versão anterior.

- name: Validar push e notificar
  if: failure()
  run: |
    echo "Falha no push para ECR ou GCR"
    # Comando para reverter tag anterior, se aplicável

Notificações via Slack: Use actions/github-script para enviar alertas.

- name: Notificar falha
  if: failure()
  uses: actions/github-script@v7
  with:
    script: |
      const message = `Pipeline falhou no ambiente ${{ matrix.environment }}`;
      // Código para enviar para Slack via webhook

Logs centralizados: Configure o workflow para exportar logs para CloudWatch (AWS) ou Cloud Logging (GCP), garantindo auditoria e compliance.

Conclusão

Integrar GitHub Actions com ECR e GCR permite automatizar a publicação de imagens Docker de forma confiável e escalável, atendendo a requisitos de multi-cloud, versionamento e segurança. Com as práticas descritas — desde configuração de credenciais até tratamento de erros — sua equipe pode reduzir drasticamente o tempo de deploy e aumentar a consistência entre ambientes.

A adoção de tags imutáveis, cache de camadas e notificações proativas transforma o pipeline em um ativo estratégico para operações de DevOps. Comece implementando o workflow básico e evolua gradualmente com otimizações específicas ao seu cenário.

Referências