DevOps

Publicando Imagens no Docker Hub e GitHub Container Registry Já leu

6 min de leitura

Publicando Imagens no Docker Hub e GitHub Container Registry
Uma imagem que existe apenas na máquina do desenvolvedor não serve a nenhum pipeline de CI/CD, a nenhum servidor de produção, a nenhum colega de equipe. Para que uma imagem seja utilizável em qualquer ambiente, ela preci

Uma imagem que existe apenas na máquina do desenvolvedor não serve a nenhum pipeline de CI/CD, a nenhum servidor de produção, a nenhum colega de equipe. Para que uma imagem seja utilizável em qualquer ambiente, ela precisa ser publicada em um registro de container — um serviço que armazena, versiona e distribui imagens.

O fluxo padrão em qualquer pipeline de entrega é construir a imagem, enviá-la para um registro e, em seguida, instruir o servidor de destino a baixá-la e executá-la. O registro é o elo entre a construção e a execução.


Docker Hub: O Registro Público Padrão

O Docker Hub é o registro padrão do Docker — quando se executa docker pull nginx, é do Docker Hub que a imagem vem. Qualquer pessoa pode criar uma conta gratuita e publicar imagens públicas sem limite.

Criando uma conta e fazendo login:

# Login interativo
docker login

# Login com credenciais diretas (útil em scripts)
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin

Convenção de nomenclatura no Docker Hub:

usuario/nome-da-imagem:tag

# Exemplos
ricardomatosdocker/minha-api:1.0.0
ricardomatosdocker/minha-api:latest

Publicando uma imagem:

# Constrói com a tag no formato correto
docker build -t ricardomatosdocker/minha-api:1.0.0 .

# Adiciona a tag latest apontando para a mesma imagem
docker tag ricardomatosdocker/minha-api:1.0.0 ricardomatosdocker/minha-api:latest

# Publica ambas as tags
docker push ricardomatosdocker/minha-api:1.0.0
docker push ricardomatosdocker/minha-api:latest

GitHub Container Registry: Imagens Integradas ao Repositório

O GitHub Container Registry (GHCR) armazena imagens diretamente associadas a um repositório GitHub. A integração com GitHub Actions é nativa e as permissões seguem as mesmas regras do repositório — quem tem acesso ao repositório tem acesso às imagens.

A URL do GHCR segue o formato:

ghcr.io/usuario-ou-org/nome-da-imagem:tag

# Exemplos
ghcr.io/ricardomatosdocker/minha-api:1.0.0
ghcr.io/minha-empresa/minha-api:main

Login no GHCR:

# Usando um Personal Access Token com permissão write:packages
echo "$GITHUB_TOKEN" | docker login ghcr.io -u "$GITHUB_USERNAME" --password-stdin

Automatizando a Publicação com GitHub Actions

O fluxo mais comum em projetos modernos: a cada push na branch main, o pipeline constrói a imagem e a publica automaticamente. A cada tag de release, publica com o número de versão.

# .github/workflows/docker-publish.yml
name: Build e Publicação de Imagem

on:
  push:
    branches: [ main ]
    tags: [ 'v*.*.*' ]
  pull_request:
    branches: [ main ]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - name: Clona o repositório
        uses: actions/checkout@v4

      - name: Configura o Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login no GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extrai metadados da imagem
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=sha,prefix=sha-

      - name: Constrói e publica a imagem
        uses: docker/build-push-action@v5
        with:
          context: .
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

O que esse workflow produz em cada cenário:

Um push na main gera a tag main e uma tag com o SHA do commit como sha-abc1234. Um Pull Request gera uma imagem de teste mas não a publica. A criação da tag v1.2.0 gera as tags 1.2.0, 1.2 e v1.2.0 — seguindo as convenções do SemVer.


Multi-platform Builds: Imagens para ARM e AMD64

Com a popularização de máquinas Apple Silicon e instâncias ARM na AWS (Graviton), imagens que rodam apenas em AMD64 se tornam um problema. O Docker Buildx permite construir imagens para múltiplas arquiteturas em um único comando:

- name: Configura QEMU para emulação de ARM
  uses: docker/setup-qemu-action@v3

- name: Configura Docker Buildx
  uses: docker/setup-buildx-action@v3

- name: Constrói para múltiplas plataformas
  uses: docker/build-push-action@v5
  with:
    context: .
    platforms: linux/amd64,linux/arm64
    push: true
    tags: ${{ steps.meta.outputs.tags }}

O registro armazena um manifesto multi-plataforma — quando docker pull é executado, o Docker automaticamente baixa a variante correta para a arquitetura do host.


Gerenciando Tags de Forma Consistente

Uma estratégia de tagging bem definida evita confusão sobre qual versão está rodando em cada ambiente:

# SHA do commit — imutável, rastreável, ideal para rollbacks
ghcr.io/empresa/api:sha-abc1234

# Branch — sempre aponta para o último build daquela branch
ghcr.io/empresa/api:main
ghcr.io/empresa/api:develop

# Versão semântica — para releases estáveis
ghcr.io/empresa/api:1.2.0
ghcr.io/empresa/api:1.2      # última patch da minor 1.2
ghcr.io/empresa/api:1        # última minor do major 1

# Ambiente — prático mas menos rastreável
ghcr.io/empresa/api:staging
ghcr.io/empresa/api:production

# latest — conveniente mas perigoso em produção
ghcr.io/empresa/api:latest

A recomendação para ambientes de produção é usar sempre o SHA do commit ou a versão semântica exata — nunca latest ou tags de ambiente mutáveis. Isso garante que o deploy é determinístico e que um rollback pode ser feito apontando para um SHA específico.


Inspecionando Imagens Publicadas

# Inspeciona uma imagem remota sem baixá-la
docker manifest inspect ghcr.io/empresa/api:1.2.0

# Verifica as plataformas suportadas
docker manifest inspect ghcr.io/empresa/api:1.2.0 | \
  grep -A2 '"platform"'

# Histórico de camadas de uma imagem publicada
docker history ghcr.io/empresa/api:1.2.0

Encerrando o Módulo 3

Com este artigo conclui-se o Módulo 3. Foram cobertos os conceitos fundamentais de containers, a instalação e uso do Docker, a escrita de Dockerfiles eficientes, volumes e redes, orquestração local com Docker Compose, boas práticas de produção e publicação em registros.

O Módulo 4 entra no tema que une tudo isso em um fluxo contínuo: CI/CD na Prática. Os containers construídos neste módulo serão testados, publicados e implantados automaticamente por pipelines que rodam sem intervenção humana.


Referências para Aprofundamento

Documentação oficial - Docker Hub Documentation — docs.docker.com — Guia completo do Docker Hub, incluindo repositórios privados, webhooks e automação de builds. - GitHub Container Registry — docs.github.com — Documentação oficial do GHCR com exemplos de autenticação e publicação via Actions.

GitHub Actions - docker/build-push-action — GitHub — Repositório oficial da action usada para construir e publicar imagens. Documentação detalhada de todos os parâmetros disponíveis. - docker/metadata-action — GitHub — Repositório da action de geração automática de tags e labels. Inclui exemplos de todas as estratégias de tagging.

Leitura complementar - Multi-platform Images — docs.docker.com — Guia oficial sobre construção de imagens multi-plataforma com Buildx e QEMU.

Comentários

Mais em DevOps

Artigo 27 — Módulos no Terraform: Reusabilidade e Organização
Artigo 27 — Módulos no Terraform: Reusabilidade e Organização

Artigo 27 — Módulos no Terraform: Reusabilidade e Organização O Problema da R...

Alertas Inteligentes e Cultura de Resposta a Incidentes
Alertas Inteligentes e Cultura de Resposta a Incidentes

Existe um paradoxo bem documentado em times de operações: quanto mais alertas...

Trabalhando com arquivos CSV
Trabalhando com arquivos CSV

JSON domina as APIs modernas, mas o CSV domina o mundo real dos dados. Planil...