Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 15

Tagging and Versioning Docker Images

Recommended resources

Olá! Na lição anterior, você aprendeu a usar o docker history para analisar a estrutura em camadas de uma imagem. Compreender como uma imagem é construída é o primeiro passo. Agora, vamos focar em como gerenciá-la e identificá-la de forma eficaz.

Nesta lição, vamos mergulhar no processo de etiquetagem (tagging) e versionamento de imagens Docker seguindo convenções de nomenclatura. Esta é uma prática fundamental no ciclo de vida do desenvolvimento de software. Um bom versionamento garante que você e sua equipe saibam exatamente qual versão de uma aplicação está em um contêiner, permitindo builds reproduzíveis, rollbacks seguros e uma organização clara dos seus artefatos de software.

A Anatomia de um Nome de Imagem

Antes de aplicarmos uma tag, é crucial entender a estrutura completa de uma referência de imagem Docker. Uma tag é apenas a parte final de um nome mais complexo. Sua experiência com redes e sistemas distribuídos o ajudará a apreciar a lógica por trás dessa nomenclatura, que se assemelha a um endereço de recurso em uma rede.

How to name, version, and reference container images

Para obter uma definição precisa dos componentes de uma referência de imagem, vamos consultar o artigo 'How to name, version, and reference container images' da Red Hat.

Leia a seção 'What is an image reference'. Preste atenção na Figura 1, que decompõe a referência nos seus componentes: domínio (registry), repositório (namespace/image name), tag e digest. Entender essa estrutura é a base para tudo o que se segue.

Resumindo a estrutura:

[registry_domain/][username_or_namespace/]<repository_name>:<tag>

  • Registry Domain: Onde a imagem está hospedada (ex: docker.io para Docker Hub, quay.io, ghcr.io, ou o endereço do seu registry privado). Se omitido, o padrão é o Docker Hub.
  • Username/Namespace: O nome do usuário ou organização proprietária do repositório (ex: kalkost no exemplo que veremos, ou library para imagens oficiais como python).
  • Repository Name: O nome da sua aplicação ou componente (ex: my-api, frontend).
  • Tag: Um rótulo, geralmente usado para a versão (ex: v1.2.0, latest).

Tags vs. Digests: Mutabilidade vs. Imutabilidade

Uma tag é um ponteiro mutável. Isso significa que a tag myapp:latest hoje pode apontar para uma imagem, e amanhã, após um novo build, pode apontar para outra imagem completamente diferente.

Docker Image Tagging and Versioning Illustration
Esta imagem ilustra como múltiplas tags (`mycoredns:latest`, `mycoredns:1.9`) podem apontar para o mesmo ID de imagem subjacente (`coredns/coredns:1.9.1`). Ela também mostra que a tag `latest` é dinâmica e pode ser movida para apontar para uma nova versão quando esta é lançada.

Em contrapartida, um digest é um identificador imutável. É um hash SHA256 do conteúdo da imagem (especificamente, do seu manifesto de configuração). Se você referenciar uma imagem pelo seu digest (myapp@sha256:...), você tem a garantia absoluta de que está usando exatamente aquela versão da imagem, para sempre.

How to name, version, and reference container images

Para aprofundar a distinção entre tags e digests, continue no mesmo artigo da Red Hat. Este conceito é fundamental para a reprodutibilidade em ambientes de produção.

Leia as seções 'What is an image tag' e 'What is an image digest'. Foque na diferença chave: tags são mutáveis (ponteiros), enquanto digests são imutáveis (identificadores únicos).


Comandos para Aplicar Tags

Existem duas maneiras principais de aplicar uma tag a uma imagem:

  1. Durante o build, com docker build -t: Esta é a forma mais comum. Você constrói a imagem e a etiqueta em um único passo.
  2. Após o build, com docker tag: Útil para adicionar uma tag a uma imagem que já existe localmente.

Docker Image Naming and Tagging

O artigo 'Docker Image Naming and Tagging' oferece uma explicação prática e direta sobre como usar esses comandos.

Leia a primeira parte do artigo, que introduz os comandos docker tag e docker build -t. Observe o exemplo de como incluir seu nome de usuário do Docker Hub no nome da imagem, um passo necessário para publicá-la mais tarde.

A sintaxe é repository:tag. Deixar a tag de fora resulta em um erro, como mostra a imagem abaixo.

Docker Image Tagging and Build Process Demonstration
Esta imagem do terminal mostra um build bem-sucedido com a tag `my-app1:v2` e um build com falha (`docker build -t my-app1: .`) devido a um formato de tag inválido. É obrigatório fornecer um valor para a tag após os dois pontos.

Mão na Massa: Praticando o Tagging

Vamos aplicar esses conceitos. O exercício a seguir, adaptado do recurso que acabamos de ler, solidificará seu entendimento.

Docker Image Naming and Tagging

Siga este passo a passo para praticar o uso dos comandos de tagging. Você irá baixar uma imagem, renomeá-la e criar múltiplas tags para o mesmo ID de imagem.

Siga as instruções na seção 'Tagging Docker Images'. Execute cada comando em seu terminal. Use seu próprio nome de usuário do Docker Hub no lugar de 'kalkost'. Ao final, execute docker images e observe como a mesma 'IMAGE ID' aparece com diferentes nomes de repositório e tags. Isso demonstra na prática que as tags são apenas aliases.


Estratégias de Versionamento e o Problema da Tag latest

Agora que você sabe como aplicar uma tag, a próxima pergunta é qual tag aplicar. Uma estratégia de versionamento inconsistente (ou inexistente) é uma receita para o desastre em produção.

O Perigo da Tag :latest

Por convenção, a tag :latest é aplicada por padrão quando você constrói uma imagem sem especificar uma tag. É tentador usá-la durante o desenvolvimento, mas evite-a em ambientes de produção.

O problema é que :latest é uma tag flutuante e ambígua. Ela não garante que você está usando a "versão mais nova"; ela aponta para a imagem mais recente que foi construída ou baixada com essa tag específica. Isso leva a builds não reproduzíveis e dificulta a depuração e os rollbacks.

Docker Image Naming and Tagging

O artigo 'Docker Image Naming and Tagging' tem uma excelente demonstração prática dos problemas que a tag latest pode causar. Realizar este exercício lhe dará uma intuição clara do porquê evitá-la.

Leia e execute os passos na seção 'Using the Latest Tag in Docker'. O exercício demonstra como executar docker run kalkost/test pode resultar em uma versão antiga, porque a tag latest está implicitamente ligada a ela, enquanto a versão mais nova está sob a tag :v2.

Políticas de Tagging Recomendadas

Para evitar a ambiguidade da tag :latest, adote uma política de versionamento clara. Sua experiência em desenvolvimento de software e pesquisa acadêmica certamente o expôs a diferentes esquemas de versionamento. Para contêineres, as estratégias mais comuns são:

  1. Semantic Versioning (SemVer): O padrão-ouro para a maioria das aplicações. Usa o formato MAJOR.MINOR.PATCH (ex: 1.2.3).

    • MAJOR: Mudanças incompatíveis (breaking changes).
    • MINOR: Adição de novas funcionalidades de forma retrocompatível.
    • PATCH: Correções de bugs retrocompatíveis.
      Esta abordagem comunica claramente o impacto de uma nova versão.
  2. Git Commit Hash: Usa o hash curto do commit do Git (ex: a1b2c3d). Isso fornece rastreabilidade perfeita entre a imagem do contêiner e o código-fonte exato que a gerou. É excelente para ambientes de Integração Contínua (CI).

  3. Data/Timestamp: Usa a data e hora do build (ex: 20240520-1430). Simples e cronológico, mas menos descritivo sobre o conteúdo.

Docker Image Naming and Tagging

Para uma visão geral dessas políticas, vamos consultar novamente o artigo 'Docker Image Naming and Tagging'.

Leia a seção 'Docker Image Tagging Policies'. O texto descreve as três principais estratégias que acabamos de mencionar: Semantic Versioning, Git commit hash e Date value.

Uma prática recomendada em pipelines de CI/CD é automatizar o versionamento, por exemplo, extraindo a versão de um arquivo de projeto (.csproj no seu caso com .NET) ou de tags Git.


Conclusão

Parabéns! Você agora domina um dos aspectos mais críticos do gerenciamento de contêineres. Saber como nomear e versionar imagens corretamente é essencial para manter um fluxo de trabalho de desenvolvimento e deploy organizado, seguro e reproduzível.

Principais pontos a reter:

  • Anatomia do Nome: Uma referência de imagem é composta por [registry/][namespace/]<repository>:<tag>.
  • Tags vs. Digests: Tags são rótulos mutáveis, ideais para referência humana. Digests são hashes imutáveis, garantindo reprodutibilidade absoluta.
  • Comandos: Use docker build -t para etiquetar durante o build ou docker tag para etiquetar uma imagem existente.
  • Evite :latest: A tag :latest é ambígua e perigosa para produção. Ela não garante a versão mais recente e quebra a reprodutibilidade.
  • Adote uma Política: Use uma estratégia de versionamento explícita, como Semantic Versioning (SemVer), para comunicar claramente as mudanças entre as versões.

Agora que suas imagens estão devidamente construídas, analisadas e, o mais importante, etiquetadas, o próximo passo lógico é compartilhá-las. Na próxima lição, você aprenderá a enviar (push) e baixar (pull) imagens de um registro de contêineres como o Docker Hub, tornando seus artefatos disponíveis para seus colegas de equipe ou para seus ambientes de deploy.