Buildah é uma ferramenta especializada na construção de imagens OCI, utilizando tecnologias de baixo nível como containers/image e containers/storage.
O trio de ferramentas OCI inclui:
- Buildah, focado na construção de imagens
- Podman, dedicado à gestão de imagens e contêineres
- Skopeo, especializado em operações com imagens e repositórios remotos
Juntas, essas ferramentas formam um ecossistema de contêineres sem Docker, permitindo construir, gerenciar, enviar e operar imagens e contêineres sem depender do daemon do Docker.
É importante notar que existe alguma sobreposição de funcionalidades entre essas ferramentas, especialmente entre Buildah e Podman, mas cada uma tem seu foco específico. O uso combinado delas é recomendado.
Para entender melhor a relação entre Buildah e Podman, consulte a documentação oficial: buildah-and-podman-relationship
- O que é Buildah?
Buildah é uma ferramenta projetada especificamente para a construção de imagens OCI. A interface de linha de comando (CLI) do Buildah é implementada usando tecnologias baseadas em OCI, como os projetos containers/image e containers/storage.
A descrição oficial diz:
Uma ferramenta que facilita a construção de imagens OCI. A ferramenta de linha de comando Buildah (CLI) e as tecnologias baseadas em OCI subjacentes (por exemplo, containers/image e containers/storage).
A CLI do Buildah utiliza esses projetos para implementar funcionalidades de construção, movimento e gestão de imagens:
- O projeto
containers/imagefornece mecanismos para copiar (enviar, buscar), inspecionar e assinar imagens de contêineres - O projeto
containers/storagefornece mecanismos para armazenar camadas de sistema de arquivos, imagens de contêineres e contêineres
A questão que surge é: já existindo o Docker para a construção de imagens, por que precisaríamos do Buildah?
Buildah funciona sem daemon e pode ser executado em modo rootless, tornando-se mais leve em comparação com o docker. Se usado para substituir a capacidade de construção de imagens do Docker, por não requerer um daemon e poder ser executado sem privilégios root, torna-se muito conveniente mesmo quando usado dentro de contêineres, sendo uma excelente escolha para DevOps.
Em resumo: em comparação com as ferramentas de construção existentes, o Buildah é mais leve, oferece uma abordagem Dockerless e Rootless.
- Instalação do Buildah
Documentação oficial: buildah#install.md
O Buildah oferece pacotes para as principais distribuições Linux, que podem ser instalados facilmente usando gerenciadores de pacotes como yum, apt-get, dnf, etc. Também é possível instalar a partir do código fonte.
A instalação usando o gerenciador de pacotes da distribuição é recomendada:
# CentOS
sudo yum -y install buildah
# Ubuntu 20.10 e mais recentes
sudo apt-get -y update
sudo apt-get -y install buildah
# Fedora
sudo dnf -y install buildah
Para este demo, usaremos Ubuntu 22.04:
sudo apt-get -y update
sudo apt-get -y install buildah
Verificando a versão do Buildah
Nota: a versão do sistema é relativamente antiga, então a versão do buildah instalada também é mais antiga
root@construtor-ubuntu:~# buildah version
Versão: 1.23.1
Versão Go: go1.17
Especificação de Imagem: 1.0.1
Especificação de Runtime: 1.0.2-dev
Especificação CNI: 0.4.0
Versão libcni:
Versão de imagem: 5.16.0
Commit Git:
Compilado: Thu Jan 1 08:00:00 1970
SO/Arquitetura: linux/amd64
Plataforma de Compilação: linux/amd64
- Funcionalidades Básicas
Construção de imagens usando comandos
Em comparação com o Dockerfile, o Buildah oferece uma poderosa abordagem de construção baseada em comandos, transformando as instruções do Dockerfile em comandos individuais, proporcionando uma nova alternativa para a construção de imagens:
# Busca uma imagem, similar ao FROM do Dockerfile
contêiner=$(buildah from nginx)
# Similar ao RUN do Dockerfile
buildah run $contêiner -- bash -c 'echo "olá mundo" > /usr/share/nginx/html/index.html'
# Salva a imagem
buildah commit $contêiner nginx-ola
Saída esperada:
[root@construtor ~]# contêiner=$(buildah from nginx)
[root@construtor ~]# buildah run $contêiner -- bash -c 'echo "olá mundo" > /usr/share/nginx/html/index.html'
[root@construtor ~]# buildah commit $contêiner nginx-ola
Obtendo assinaturas da fonte da imagem
Copiando blob c0f1022b22a9 pulado: já existe
Copiando blob fc00b055de35 pulado: já existe
Copiando blob 2c3a053d7b67 pulado: já existe
Copiando blob b060cc3bd13c pulado: já existe
Copiando blob 8aa4787aa17a pulado: já existe
Copiando blob c28e0f7d0cc5 pulado: já existe
Copiando blob d32d820bcf1c pulado: já existe
Copiando blob c6a7a8084917 feito |
Copiando config 19de2f1f4a feito |
Escrevendo manifesto para destino da imagem
19de2f1f4afc6e0ff9da11e9dfb988619f4bcd1d388ea4c18413ab574487a0d4
Verificando a imagem construída recentemente
[root@construtor ~]# buildah images
REPOSITÓRIO TAG ID DA IMAGEM CRIADO TAMANHO
localhost/nginx-ola mais recente 19de2f1f4afc 22 segundos atrás 196 MB
Construção de imagens através de Dockerfile
Naturalmente, o Buildah também suporta a construção de imagens através de Dockerfile, que deve ser o método mais comum de uso.
Preparando um Dockerfile
FROM nginx
RUN echo "Olá Mundo" > /usr/share/nginx/html/index.html
EXPOSE 80
Usando o buildah para construir a imagem
buildah build -t nginx-ola2 .
Saída esperada
[root@construtor ~]# buildah build -t nginx-ola2 .
ETAPA 1/3: FROM nginx
ETAPA 2/3: RUN echo "Olá Mundo" > /usr/share/nginx/html/index.html
ETAPA 3/3: EXPOSE 80
COMMIT nginx-ola2
Obtendo assinaturas da fonte da imagem
Copiando blob c0f1022b22a9 pulado: já existe
Copiando blob fc00b055de35 pulado: já existe
Copiando blob 2c3a053d7b67 pulado: já existe
Copiando blob b060cc3bd13c pulado: já existe
Copiando blob 8aa4787aa17a pulado: já existe
Copiando blob c28e0f7d0cc5 pulado: já existe
Copiando blob d32d820bcf1c pulado: já existe
Copiando blob eec64f0b2723 feito |
Copiando config 1b63bdb270 feito |
Escrevendo manifesto para destino da imagem
--> 1b63bdb270c1
Imagem etiquetada com sucesso como localhost/nginx-ola2:latest
1b63bdb270c1066520a5ae37dcea3d5c3b9c5e9af581e76bf1287f9f79f77f03
O uso é basicamente idêntico ao docker build, com baixo custo de aprendizado para migração.
- Arquivos de Configuração
Assim como no trio de ferramentas OCI, os arquivos de configuração do Podman e Buildah são compartilhados.
Você pode encontrar os arquivos de configuração padrão do Podman e Buildah nos seguintes diretórios:
- Arquivo de configuração global:
/etc/containers/ - Arquivo de configuração do usuário:
~/.config/containers/
Nota: o arquivo de configuração do usuário tem prioridade; se não existir, será usado o arquivo global.
Isso significa que diferentes usuários podem especificar seus próprios arquivos de configuração
No diretório /etc/containers, existem vários arquivos de configuração:
- storage.conf: configurações relacionadas ao armazenamento
- registries.conf: configurações relacionadas a repositórios de imagens
- policy.json: configurações relacionadas à verificação de assinatura de contêineres
- auth.json: informações de autenticação de repositórios de imagens, os tokens são armazenados neste arquivo após executar o comando login
- ...
Para detalhes específicos de cada arquivo, consulte: Podman&Buildah Arquivos de Configuração
Como usuário, o arquivo registries.conf é o mais relevante, então vamos analisá-lo em detalhes.
vi /etc/containers/registries.conf
Conteúdo Completo
O conteúdo completo de /etc/containers/registries.conf é o seguinte:
unqualified-search-registries = ["registry.access.redhat.com", "registry.redhat.io", "docker.io"]
# Configuração do repositório Docker.io
[[registry]]
prefixo = "docker.io"
localização = "registry-1.docker.io"
# Configuração de espelho para Docker.io
[[registry.mirror]]
localização = "espelho.gcr.io"
[[registry.mirror]]
localização = "espelho2.gcr.io"
# Configuração do repositório privado 10.10.10.49:5000
[[registry]]
prefixo = "10.10.10.49:5000"
localização = "10.10.10.49:5000"
inseguro = true
# Configuração de espelho para repositório privado
[[registry.mirror]]
localização = "espelho.gcr.io"
modo-short-name = "permissivo"
Podemos dividir em várias seções:
- Repositórios de imagens padrão
- Configuração de Insecure, Mirror etc. para repositórios de imagens
- Modo de processamento de shortName
Diferentes configurações de repositório são distinguidas usando blocos [[registry]].
Atenção: a seguinte configuração é da versão V1, que está obsoleta. Embora ainda possa ser usada, não é recomendada.
[registries.search]
registries = ['registry1.com', 'registry2.com']
[registries.insecure]
registries = ['registry3.com']
[registries.block]
registries = ['registry.nãoconfiável.com', 'registry.inseguro.com']
Explicação dos Parâmetros
Documentação oficial: containers-registries.conf.5.md
unqualified-search-registries
unqualified-search-registries é uma configuração que especifica quais repositórios (registries) devem ser tentados ao buscar uma imagem sem caminho copmleto (ou seja, sem domínio e caminho). Isso geralmente se aplica ao caso de "nome de repositório não especificado".
unqualified-search-registries = ["registry.access.redhat.com", "registry.redhat.io", "docker.io"]
Em uma frase: ao buscar uma imagem sem caminho completo (sem domínio e caminho), quais repositórios devem ser tentados.
short-name-mode
A opção short-name-mode define como nomes de imagem sem caminho de repositório (por exemplo, golang:1.20) são tratados. Existem três modos:
- disabled: não permite o uso de nomes curtos, deve ser especificado o caminho completo do repositório.
- permissive (padrão): permite o uso de nomes curtos e tenta encontrar a imagem na lista de repositórios configurados na ordem especificada.
- full: só é possível buscar imagens quando o nome do repositório for completo.
O valor padrão é suficiente, sem necessidade de alteração.
modo-short-name = "permissivo"
prefixo
O prefixo sob o bloco Registry é usado para corresponder qual bloco de configuração de Registry será usado ao buscar imagens, apenas o bloco de correspondência mais longo será usado.
Suponha que tenhamos a seguinte configuração, com dois blocos Registry
[[registry]]
prefixo = "docker.io"
[[registry]]
prefixo = "docker.io.exemplo.com"
Quando buscamos a imagem docker.io.exemplo.com/library/busybox:latest, o domínio extraído do nome completo da imagem corresponderá ao prefixo no arquivo de configuração, e o segundo bloco de Registry será correspondido, usando assim as configurações desse bloco.
Em uma frase: geralmente preencha o endereço do Registry, mas no formato *.exemplo.com, ou especifique a localização.
localização
A localização no bloco Registry especifica o endereço final para buscar a imagem.
Ao buscar a imagem especificamos docker.io/library/busybox:1.36, mas o acesso final será feito no endereço registry-1.docker.io.
Para o docker.io, a seguinte configuração é necessária:
[[registry]]
prefixo = "docker.io"
localização = "registry-1.docker.io"
Além disso, quando o prefixo não está no formato *.exemplo.com, a localização também deve ser especificada, com o mesmo conteúdo do prefixo.
Em uma frase: usado para especificar o endereço real para buscar a imagem, por exemplo registry-1.docker.io, ou quando o prefixo não está no formato *.exemplo.com, a localização também deve ser especificada, com o mesmo conteúdo do prefixo.
inseguro
O parâmetro Insecure sob o bloco registry é comum, configura o uso de http para acessar o repositório, geralmente usado em repositórios privados autoconstruídos.
# Configuração do repositório privado 10.10.10.49:5000
[[registry]]
prefixo = "10.10.10.49:5000"
localização = "10.10.10.49:5000"
inseguro = true
bloqueado
A explicação oficial é: Se verdadeiro, a busca de imagens com nomes correspondentes é proibida.
O padrão é falso. Quando configurado como verdadeiro, não é mais possível buscar imagens do repositório especificado pelo prefixo.
# Configuração do repositório privado 10.10.10.49:5000
[[registry]]
prefixo = "10.10.10.49:5000"
bloqueado = false
Em uma frase: usado para desativar certos repositórios proibidos.
espelho
Para repositórios que não podem ser buscados ou cuja busca é lenta, podem ser configurados repositórios espelho.
# Configuração de espelho para Docker
[[registry]]
prefixo = "docker.io"
localização = "registry-1.docker.io"
[[registry.mirror]]
localização = "docker.m.daocloud.io"
O bloco registry.mirror deve estar sob o bloco Registry correspondente para configurar o espelho para esse repositório.
Arquivo de Configuração de Referência
A seguir está um exemplo de arquivo de configuração comum, incluindo configurações como localização, espelho, inseguro, que pode servir como referência ao adicionar outros repositórios de imagens.
unqualified-search-registries = ["docker.io"]
modo-short-name = "permissivo"
# Configuração de espelho para Docker
[[registry]]
prefixo = "docker.io"
localização = "registry-1.docker.io"
[[registry.mirror]]
localização = "docker.m.daocloud.io"
# Configuração do repositório privado "172.20.150.222"
[[registry]]
prefixo = "172.20.150.222"
localização = "172.20.150.222"
inseguro = true
- Uso Avançado
Aqui compartilharei alguns usos avançados, incluindo:
- Construção multiestágio
- Construção de imagens multiarquitetura
- Uso do Buildah em ambientes CI
Construção Multiestágio
A construção multiestágio é uma técnica comum para otimizar o tamanho das imagens, separando o ambiente de compilação do ambiente de execução para reduzir o tamanho final da imagem. Vamos demonstrar com um simples programa Go.
main.go
Usando net/http para iniciar um serviço http.
// main.go
package main
import (
"fmt"
"log"
"net/http"
)
func manipulador(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Olá, Mundo!")
}
func main() {
http.HandleFunc("/", manipulador)
log.Fatal(http.ListenAndServe(":8080", nil))
}
Dockerfile
O núcleo da construção multiestágio é o Dockerfile, que pode ver que o Dockerfile atual tem duas instruções FROM, correspondentes às fases de compilação e execução.
- Fase de compilação: usa golang:1.20-alpine como imagem base para garantir que o programa Go possa ser compilado normalmente
- Fase de execução: como o programa Go compilado pode ser executado diretamente sem depender do ambiente Go, usa diretamente alpine como imagem base, reduzindo o volume final da imagem
# Estágio 1: Estágio de compilação (construtor)
FROM golang:1.20-alpine as construtor
# Define o Diretório de Trabalho atual dentro do contêiner
WORKDIR /app
# Copia o código fonte para dentro do contêiner
COPY . .
# Compila o binário Go
RUN CGO_ENABLED=0 go build main.go
# Estágio 2: Estágio de Runtime
FROM alpine:latest
# Instala as bibliotecas necessárias para executar o binário (se houver)
RUN apk --no-cache add ca-certificates
# Define o Diretório de Trabalho atual dentro do contêiner
WORKDIR /root/
# Copia o binário compilado do estágio construtor
COPY --from=construtor /app/main .
# Expõe a porta 8080
EXPOSE 8080
# Executa a aplicação Go
CMD ["./main"]
Construção
buildah build -t servidor:v0.0.1 .
Saída esperada:
[root@construtor ~]# buildah build -t servidor:v0.0.1 .
[1/2] ETAPA 1/4: FROM golang:1.20-alpine AS construtor
[1/2] ETAPA 2/4: WORKDIR /app
[1/2] ETAPA 3/4: COPY . .
[1/2] ETAPA 4/4: RUN CGO_ENABLED=0 go build main.go
[2/2] ETAPA 1/6: FROM alpine:latest
Resolvido "alpine" como um alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Tentando buscar docker.io/library/alpine:latest...
Obtendo assinaturas da fonte da imagem
Copiando blob 38a8310d387e feito |
Copiando config 4048db5d36 feito |
Escrevendo manifesto para destino da imagem
[2/2] ETAPA 2/6: RUN apk --no-cache add ca-certificates
fetch https://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.21/community/x86_64/APKINDEX.tar.gz
(1/1) Instalando ca-certificates (20241010-r0)
Executando busybox-1.37.0-r8.trigger
Executando ca-certificates-20241010-r0.trigger
OK: 7 MiB em 16 pacotes
[2/2] ETAPA 3/6: WORKDIR /root/
[2/2] ETAPA 4/6: COPY --from=construtor /app/main .
[2/2] ETAPA 5/6: EXPOSE 8080
[2/2] ETAPA 6/6: CMD ["./main"]
[2/2] COMMIT servidor:v0.0.1
Obtendo assinaturas da fonte da imagem
Copiando blob 3e01818d79cd pulado: já existe
Copiando blob 529cb79624ea feito |
Copiando config 8d0a6344f5 feito |
Escrevendo manifesto para destino da imagem
--> 8d0a6344f55c
Imagem etiquetada com sucesso como localhost/servidor:v0.0.1
8d0a6344f55c0611c94b23f2571adb0ba1ce98ee1d5009c79fd656fd42247c1b
Construção de Imagens Multiarquitetura
Muitos aplicativos e serviços precisam ser executados em máquinas com diferentes arquiteturas, como amd64 e arm64, mas não é possível ter uma máquina dedicada para cada arquitetura.
Anteriormente, o Docker Buildx era a principle ferramenta, mas o Buildah também suporta construção multiarquitetura.
Nota: ambas as ferramentas dependem do qemu
Instalação do qemu-user-static
O buildah usa qemu para simular diferentes arquiteturas.
Primeiro, certifique-se de que o qemu está instalado no seu sistema.
Nota: após testes, se seu Dockerfile não tiver comandos RUN para executar certas operações, o qemu não é necessário para construir imagens multiarquitetura.
Instale diretamente usando o gerenciador de pacotes:
# Ubuntu
sudo apt-get install qemu-user-static
# Fedora
sudo dnf install qemu-user-static
Construir e enviar imagens multiarquitetura
Assim como o Docker buildx, o Buildah também usa o parâmetro --platform para especificar a arquitetura a ser construída.
No entanto, o Buildah não tem o parâmetro --push, não podendo gerar automaticamente o manifesto e enviar após a construção. Portanto, precisamos criar manualmente um manifesto e vincular as imagens construídas e o manifesto antes de enviar para o repositório final de imagens.
O fluxo geral pode ser dividido em três etapas:
-
- Criar Manifesto
- O manifesto criado aqui é na verdade uma imagem, que aparecerá na lista buildah images
- O nome é recomendado usar o nome completo da imagem, por exemplo: 172.20.150.222/lixd/nginx-ola:v0.0.2, mas usar outro não afeta
-
- Construir imagem multiarquitetura
- Note que o parâmetro --manifest deve ser usado em vez de --tag para vincular a imagem ao manifesot
-
- Enviar Manifesto e Imagem para o repositório de imagens
- Ao enviar, é necessário especificar o nome do Manifesto e o caminho completo do Registry
- Se o manifesto já usar o nome completo da imagem, os dois serão iguais
Comandos:
PUSH_WAY=172.20.150.222/lixd/nginx-ola:v0.0.2
# Criar manifesto
buildah manifest create ${PUSH_WAY}
# Construir
buildah build --manifest ${PUSH_WAY} --platform linux/amd64,linux/arm64 .
# Enviar
buildah manifest push ${PUSH_WAY} --all "docker://${PUSH_WAY}"
Definimos um script simples para implementar a construção de imagens multiarquitetura, o conteúdo completo do build.sh é o seguinte:
# Definir as variáveis necessárias
export REGISTRO="172.20.150.222"
export REPOSITORIO="lixd"
export NOME_IMAGEM="servidor"
export TAG_IMAGEM="v0.0.1"
export CAMINHO_CONSTRUÇÃO="."
# Arquiteturas para construir
export ARQUITETURAS="linux/amd64,linux/arm64"
PUSH_WAY="${REGISTRO}/${REPOSITORIO}/${NOME_IMAGEM}:${TAG_IMAGEM}"
NOME_MANIFESTO=$PUSH_WAY
echo $PUSH_WAY
# Criar manifesto multiarquitetura
### Na verdade, este comando pode ser ignorado, pois durante a construção o manifesto será criado se não existir
buildah manifest create ${NOME_MANIFESTO}
# Construir o contêiner para todas as arquiteturas
### Nota: quando há mais de uma plataforma, use manifest em vez da flag tag.
buildah build \
--manifest ${NOME_MANIFESTO} \
--platform ${ARQUITETURAS} \
${CAMINHO_CONSTRUÇÃO}
# Enviar o manifesto completo, com ambas as Arquiteturas de CPU
### Se enviando para Docker Hub ou Gitlab Registry, é necessário adicionar a flag: --format v2s2, o Padrão é oci
buildah manifest push --all \
${NOME_MANIFESTO} \
"docker://${PUSH_WAY}"
Vamos usar o Demo Go anterior para compilar e gerar uma imagem multiarquitetura:
bash build.sh
Saída esperada:
root@construtor-ubuntu:~/multiestágio# bash build.sh
172.20.150.222/lixd/servidor:v0.0.1
e6ba6ec459a1fd7303c19242ab0d85c7c23af8cb156ce348928e2a4135327f15
# amd64
[linux/amd64] ETAPA 1/4: FROM golang:1.20-alpine AS construtor
[linux/amd64] ETAPA 2/4: WORKDIR /app
[linux/amd64] ETAPA 3/4: COPY . .
[linux/amd64] ETAPA 4/4: RUN CGO_ENABLED=0 go build main.go
[linux/amd64] ETAPA 1/6: FROM alpine:latest
[linux/amd64] ETAPA 2/6: RUN apk --no-cache add ca-certificates
[linux/amd64] ETAPA 3/6: WORKDIR /root/
[linux/amd64] ETAPA 4/6: COPY --from=construtor /app/main .
[linux/amd64] ETAPA 5/6: EXPOSE 8080
[linux/amd64] ETAPA 6/6: CMD ["./main"]
# arm64
[linux/arm64] [1/2] ETAPA 1/4: FROM golang:1.20-alpine AS construtor
[linux/arm64] [1/2] ETAPA 2/4: WORKDIR /app
[linux/arm64] [1/2] ETAPA 3/4: COPY . .
[linux/arm64] [1/2] ETAPA 4/4: RUN CGO_ENABLED=0 go build main.go
[linux/amd64] [2/2] ETAPA 1/6: FROM alpine:latest
[linux/arm64] [2/2] ETAPA 3/6: WORKDIR /root/
[linux/arm64] [2/2] ETAPA 4/6: COPY --from=construtor /app/main .
[linux/arm64] [2/2] ETAPA 5/6: EXPOSE 8080
[linux/arm64] [2/2] ETAPA 6/6: CMD ["./main"]
[linux/arm64] [2/2] COMMIT
# push
Obtendo assinaturas da fonte da imagem
Copiando blob 977340364f39 pulado: já existe
Copiando blob d8b4b7adc1e8 feito
Copiando config d97c60d03e feito
Escrevendo manifesto para destino da imagem
Armazenando assinaturas
--> d97c60d03e8
d97c60d03e822bb29c02c6b5c2c51b0f47871e52bc8c210c1e6324863797ce64
Obtendo lista de assinaturas de imagem
Copiando 4 de 4 imagens na lista
Escrevendo manifesto de lista para destino da imagem
...
Uso em Sistemas CI
Aqui usaremos o Github Action como exemplo para demonstrar como usar o Buildah para construir imagens multiarquitetura.
Código-fonte: lixd/github-action-lab
O Dockerfile e o main.go são os mesmos de antes, então não serão repetidos. Os interessados podem verificar no Github~
Workflow.yaml
O Workflow é o pipeline final executado, dividido em várias etapas:
-
- Iniciar o ambiente de execução, aqui ubuntu-20.04
-
- Clonar o código
-
- Instalar QEMU
-
- Construir imagem multiarquitetura com Buildah
-
- Enviar para o repositório de imagens
name: Build and Push Multi-Arch Image
on:
push:
env:
NOME_IMAGEM: test-multi-arch
TAG_IMAGEM: latest
REGISTRO_IMAGEM: docker.io
ESPAÇO_NOMES: lixd96
jobs:
build:
name: Build and Push Multi-Architecture Image
runs-on: ubuntu-20.04
steps:
# Checkout do repositório
- name: Checkout repository
uses: actions/checkout@v2
# Configurar QEMU para builds multi-plataforma
- name: Set up QEMU for multi-arch support
uses: docker/setup-qemu-action@v1
# Construir imagem Docker usando Buildah
- name: Build multi-architecture image
id: build-image
uses: redhat-actions/buildah-build@v2
with:
image: ${{ env.NOME_IMAGEM }}
tags: ${{ env.TAG_IMAGEM }}
archs: amd64,ppc64le,s390x,arm64 # Especificar as arquiteturas para suporte multi-arquitetura
dockerfiles: |
./Dockerfile
# Enviar a imagem construída para o registro de contêineres especificado
- name: Push image to registry
id: push-to-registry
uses: redhat-actions/push-to-registry@v2
with:
image: ${{ steps.build-image.outputs.image }}
tags: ${{ steps.build-image.outputs.tags }}
registry: ${{ env.REGISTRO_IMAGEM }}/${{ env.ESPAÇO_NOMES }}
username: ${{ secrets.REGISTRY_USERNAME }} # Nome de usuário do registro seguro
password: ${{ secrets.REGISTRY_PASSWORD }} # Senha do registro seguro
# Imprimir o URL da imagem após o envio
- name: Print pushed image URL
run: echo "Image pushed to ${{ steps.push-to-registry.outputs.registry-paths }}"
Verificação
Após enviar o código, o Workflow será executado automaticamente. Verifique no Dockerhub se a imagem foi enviada com sucesso:
Podemos ver que as 4 arquiteturas especificadas foram construídas e enviadas com sucesso.
- Conclusão
O Buildah oferece uma forma flexível e eficiente de construir imagens, sem dependência do Docker, com suporte ao modo seguro rootless, adequado para vários ambientes DevOps e CI/CD. Ele suporta métodos de construção baseados em comandos e Dockerfile, além de permitir construções multiestágio e multiarquitetura.