Como usar o comando docker buildx imagetools create para combinar e marcar imagens

DockerBeginner
Pratique Agora

Introdução

Neste laboratório, você aprenderá como usar efetivamente o comando docker buildx imagetools create para combinar e marcar imagens Docker. Esta experiência prática irá guiá-lo através do processo de criação de uma nova imagem, fundindo o conteúdo de múltiplas imagens de origem, uma prática comum na construção de aplicações complexas.

Em seguida, você explorará como marcar a imagem recém-criada, visualizar a estrutura final da imagem sem fazer o push usando a flag --dry-run, e adicionar anotações valiosas ao índice da imagem para melhor organização e gerenciamento de metadados. Ao final deste laboratório, você terá uma sólida compreensão de como aproveitar o docker buildx imagetools create para manipulação e gerenciamento avançados de imagens.

Criar uma nova imagem a partir de múltiplas imagens de origem

Nesta etapa, aprenderemos como criar uma nova imagem Docker combinando o conteúdo de múltiplas imagens de origem. Este é um cenário comum quando você precisa construir uma imagem que inclui componentes de diferentes imagens base ou imagens pré-construídas.

Primeiro, vamos baixar (pull) as imagens de origem necessárias. Usaremos as imagens ubuntu e alpine como exemplos.

docker pull ubuntu:latest
docker pull alpine:latest

Você deve ver uma saída indicando que as imagens estão sendo baixadas.

latest: Pulling from library/ubuntu
...
Status: Downloaded newer image for ubuntu:latest
latest: Pulling from library/alpine
...
Status: Downloaded newer image for alpine:latest

Agora, criaremos uma nova imagem usando um Dockerfile. Um Dockerfile é um documento de texto que contém todos os comandos que um usuário pode chamar na linha de comando para montar uma imagem. Crie um novo arquivo chamado Dockerfile no seu diretório ~/project.

nano ~/project/Dockerfile

Adicione o seguinte conteúdo ao Dockerfile:

FROM ubuntu:latest AS base
FROM alpine:latest AS alpine_base

COPY --from=alpine_base /etc/alpine-release /app/alpine-release
COPY --from=base /etc/os-release /app/ubuntu-release

WORKDIR /app

CMD ["ls", "-l"]

Vamos detalhar este Dockerfile:

  • FROM ubuntu:latest AS base: Esta linha define a imagem base para o primeiro estágio da nossa construção como ubuntu:latest e nomeia este estágio como base.
  • FROM alpine:latest AS alpine_base: Esta linha inicia um novo estágio de construção usando alpine:latest como imagem base e nomeia este estágio como alpine_base. Esta é uma construção de múltiplos estágios (multi-stage build), permitindo que copiemos arquivos entre os estágios.
  • COPY --from=alpine_base /etc/alpine-release /app/alpine-release: Este comando copia o arquivo /etc/alpine-release do estágio alpine_base para o diretório /app/alpine-release no estágio atual.
  • COPY --from=base /etc/os-release /app/ubuntu-release: Este comando copia o arquivo /etc/os-release do estágio base para o diretório /app/ubuntu-release no estágio atual.
  • WORKDIR /app: Isso define o diretório de trabalho para as instruções subsequentes como /app.
  • CMD ["ls", "-l"]: Isso especifica o comando padrão a ser executado quando um container é iniciado a partir desta imagem. Ele listará o conteúdo do diretório /app.

Salve o Dockerfile pressionando Ctrl + X, depois Y e Enter.

Agora, construa a imagem usando o comando docker build. O . no final do comando especifica o contexto de construção (build context), que é o diretório atual (~/project).

docker build -t my-multi-stage-image:latest ~/project

Você deve ver uma saída indicando o processo de construção, incluindo os diferentes estágios sendo executados.

[+] Building
...
Successfully built <image_id>
Successfully tagged my-multi-stage-image:latest

Após a conclusão da construção, você pode verificar se a imagem foi criada listando suas imagens locais.

docker images my-multi-stage-image

Você deve ver sua imagem recém-criada na lista.

REPOSITORY             TAG       IMAGE ID       CREATED         SIZE
my-multi-stage-image   latest    <image_id>     About a minute ago   ...MB

Finalmente, vamos executar um container a partir desta imagem para ver os arquivos copiados.

docker run --rm my-multi-stage-image:latest

A flag --rm remove automaticamente o container quando ele sai. A saída deve mostrar os arquivos copiados das imagens ubuntu e alpine.

total 8
-rw-r--r-- 1 root root 25 Aug 24 10:00 alpine-release
-rw-r--r-- 1 root root 281 Aug 24 10:00 ubuntu-release

Isso confirma que criamos com sucesso uma imagem combinando o conteúdo de múltiplas imagens de origem usando uma construção de múltiplos estágios.

Marcar a imagem recém-criada

Nesta etapa, aprenderemos como adicionar tags adicionais à imagem Docker que criamos na etapa anterior. Marcar uma imagem é útil para versionamento, identificação de diferentes construções (builds) ou associação de uma imagem a um repositório específico.

Na etapa anterior, construímos uma imagem e a marcamos automaticamente como my-multi-stage-image:latest. Agora, vamos adicionar outra tag a esta imagem, por exemplo, my-multi-stage-image:v1.0.

O comando docker tag é usado para criar uma tag TARGET_IMAGE que se refere a SOURCE_IMAGE. A sintaxe é docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG].

Primeiro, vamos listar as imagens existentes para confirmar o ID da imagem de my-multi-stage-image:latest.

docker images my-multi-stage-image

Você verá uma saída semelhante a esta, onde <image_id> é o identificador único para sua imagem:

REPOSITORY             TAG       IMAGE ID       CREATED         SIZE
my-multi-stage-image   latest    <image_id>     ...             ...MB

Agora, use o comando docker tag para adicionar a tag v1.0 a esta imagem. Você pode usar o nome e a tag da imagem (my-multi-stage-image:latest) ou o ID da imagem (<image_id>) como a fonte. Usar o nome e a tag é geralmente mais fácil.

docker tag my-multi-stage-image:latest my-multi-stage-image:v1.0

Este comando cria uma nova tag v1.0 que aponta para o mesmo ID de imagem que my-multi-stage-image:latest. Não haverá saída se o comando for bem-sucedido.

Para verificar se a nova tag foi adicionada, liste as imagens novamente.

docker images my-multi-stage-image

Você deve agora ver ambas as tags associadas ao mesmo ID de imagem:

REPOSITORY             TAG       IMAGE ID       CREATED         SIZE
my-multi-stage-image   latest    <image_id>     ...             ...MB
my-multi-stage-image   v1.0      <image_id>     ...             ...MB

Você adicionou com sucesso uma nova tag à sua imagem Docker. Isso permite que você se refira à mesma imagem usando nomes ou versões diferentes.

Mostrar a imagem final sem fazer push usando --dry-run

Nesta etapa, exploraremos como visualizar os detalhes da imagem final que seria enviada (pushed) para um registro (registry) sem realmente realizar a operação de push. Isso é útil para inspecionar o manifesto da imagem e a configuração antes de compartilhá-la.

O comando docker manifest permite inspecionar e gerenciar manifestos de imagem. Um manifesto de imagem é um documento JSON que descreve a imagem, incluindo suas camadas (layers), configuração e, potencialmente, referências a outras imagens específicas da plataforma em uma lista de manifestos.

Para mostrar o manifesto da nossa imagem my-multi-stage-image:latest sem fazer o push, podemos usar o comando docker manifest inspect com a flag --dry-run.

docker manifest inspect --dry-run my-multi-stage-image:latest

Este comando exibirá o manifesto da imagem em formato JSON no seu terminal. A flag --dry-run impede que o comando tente contatar um registro ou enviar quaisquer dados.

A saída será uma estrutura JSON detalhada descrevendo a imagem. Ela incluirá informações como a configuração da imagem, as camadas que a compõem (representadas por seus digests) e outros metadados.

{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "config": {
      "mediaType": "application/vnd.docker.container.image.v1+json",
      "size": ...,
      "digest": "sha256:..."
   },
   "layers": [
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": ...,
         "digest": "sha256:..."
      },
      ...
   ]
}

Você pode examinar esta saída para entender a estrutura e o conteúdo da sua imagem, como ela seria representada em um registro. Isso é particularmente útil para depurar ou verificar a composição da imagem.

Observe que o conteúdo exato da saída JSON variará dependendo das camadas e da configuração da imagem.

Adicionar anotações ao índice da imagem criada

Nesta etapa, aprenderemos como adicionar anotações a um índice de imagem (também conhecido como lista de manifestos). Um índice de imagem é usado para referenciar múltiplos manifestos de imagem, tipicamente para diferentes arquiteturas ou sistemas operacionais. Adicionar anotações ao índice fornece metadados sobre todo o conjunto de imagens.

Embora nossa my-multi-stage-image atual seja uma imagem de arquitetura única, ainda podemos demonstrar o conceito de adicionar anotações ao seu manifesto, que atua como um índice simples neste caso.

O comando docker manifest annotate é usado para adicionar ou atualizar anotações para uma imagem específica dentro de uma lista de manifestos. A sintaxe é docker manifest annotate MANIFEST_LIST IMAGE --annotation KEY=VALUE.

Primeiro, vamos criar uma lista de manifestos para nossa imagem. Como temos apenas uma imagem, a lista de manifestos simplesmente fará referência à nossa imagem existente. Usaremos o comando docker manifest create.

docker manifest create my-multi-stage-image:annotated my-multi-stage-image:latest

Este comando cria uma nova lista de manifestos chamada my-multi-stage-image:annotated que inclui uma referência a my-multi-stage-image:latest. Não haverá saída se for bem-sucedido.

Agora, podemos usar o comando docker manifest annotate para adicionar uma anotação à entrada para my-multi-stage-image:latest dentro da lista de manifestos my-multi-stage-image:annotated. Vamos adicionar uma anotação indicando o sistema operacional.

docker manifest annotate my-multi-stage-image:annotated my-multi-stage-image:latest --annotation "os=linux"

Este comando adiciona a anotação os=linux à entrada do manifesto para my-multi-stage-image:latest dentro da lista my-multi-stage-image:annotated. Novamente, não há saída em caso de sucesso.

Para verificar se a anotação foi adicionada, podemos inspecionar a lista de manifestos usando docker manifest inspect.

docker manifest inspect my-multi-stage-image:annotated

A saída será uma estrutura JSON representando a lista de manifestos. Você deve ver a anotação que adicionou dentro da entrada para my-multi-stage-image:latest. Procure o campo "annotations" dentro do array "manifests".

{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "manifests": [
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": ...,
         "digest": "sha256:...",
         "platform": {
            "architecture": "amd64",
            "os": "linux"
         },
         "annotations": {
            "os": "linux"
         }
      }
   ]
}

Você adicionou com sucesso uma anotação ao índice da imagem. As anotações fornecem metadados valiosos que podem ser usados por registros e clientes para entender mais sobre as imagens com as quais estão lidando.

Resumo

Neste laboratório, aprendemos como usar o comando docker buildx imagetools create para combinar e marcar (tag) imagens. Começamos criando uma nova imagem a partir de múltiplas imagens de origem usando um Dockerfile de múltiplos estágios, demonstrando como copiar arquivos entre diferentes imagens base.

Após a criação da imagem, exploramos como marcar a imagem recém-criada e usamos a flag --dry-run para visualizar a imagem final sem enviá-la (push). Finalmente, aprendemos como adicionar anotações ao índice da imagem criada, fornecendo metadados adicionais para a imagem combinada.