Docker multi stage builds

Publicado por Leonardo Berbert Gomes em 04/08/2020

[ Hits: 644 ]

Blog: https://www.linkedin.com/in/leoberbert

 


Docker multi stage builds



Após o lançamento da versão 17.05 do Docker, ele permite que um build possa ser reutilizado em diversas etapas da geração da imagem, deixando os Dockerfiles mais fáceis de ler e manter. Outro ponto a relatar e sobre o tamanho que as imagens dos contêineres passaram a ter, veremos na prática como funciona, onde utilizaremos de exemplo um simples "hello world" em golang.

Pré-requisitos:
Abaixo iremos criar um arquivo de Dockerfile para construção de um contêiner para uma aplicação golang.

vim Dockerfile

FROM golang as builder

WORKDIR /app
COPY meuapp.go /app
RUN go build -o hello
ENTRYPOINT ./hello

E seguida no mesmo diretório criaremos o famoso "hello world" em golang:

vim meuapp.go

package main

import "fmt"

func main() {
            fmt.Println("hello world")
    }

Pois bem, vamos agora realizar o build da nossa imagem do docker normalmente, para isso utilizaremos o comando abaixo:

docker build -t leoberbert/hello:1.0 .

Em seguida vamos verificar a nossa imagem criada com a versão 1.0:

docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
leoberbert/hello    1.0                 2a45d5978956        About a minute ago   812MB
golang              latest              a794da9351a3        12 days ago          810MB

Note que nossa imagem ficou com o tamanho de "812MB", o que para um contêiner é muito ruim.

Agora, com a inclusão do multi stage é que entra a mágica. Incluiremos o bloco abaixo em nosso arquivo, ficando da seguinte maneira:

vim Dockerfile

FROM golang as builder

WORKDIR /app
COPY meuapp.go /app
RUN go build -o hello
ENTRYPOINT ./hello

FROM alpine:latest

WORKDIR /app
COPY --from=builder /app/hello /app
ENTRYPOINT ./hello

Vamos realizar o build da nossa imagem novamente, porém agora vamos incluir a tag 2.0 para diferenciá-la na anterior.

docker build -t leoberbert/hello:2.0 .

Iremos verificar o tamanho dessas imagens criadas e compará-las:

docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
leoberbert/hello    2.0                 d7837a8feba7        18 minutes ago      7.64MB
leoberbert/hello    1.0                 2a45d5978956        25 minutes ago      812MB
golang              latest              a794da9351a3        12 days ago         810MB
alpine              latest              a24bb4013296        2 months ago        5.57MB

Perceba que as imagens "leoberbert/hello" possuem tamanhos totalmente diferentes:

leoberbert/hello 1.0 - 812 MB
leoberbert/hello 2.0 - 7.64 MB


Vamos realizar um teste executando os 2 contêineres utilizando as duas imagens e verificar se funcionam da mesma forma?

docker container run leoberbert/hello:1.0
hello world

docker container run leoberbert/hello:2.0
hello world

Ambos fazem a mesma coisa, porém, o contêiner 2 está bem mais otimizado e mais enxuto em seu tamanho o que é ideal para um contêiner.

Fonte: Use multi-stage builds | Docker Documentation

Espero que essa dica seja útil.

Outras dicas deste autor

Acessando Gmail pelo celular

VIM - Personalizando barra de status

RRDtool no CentOS 6.x - Instalação via Yum

Configurando o GitHub em 2 minutos

Já pensou em adquirir adesivos grátis do Rundeck?

Leitura recomendada

Servidor LAMP em Contêiner no Podman

Docker - remover imagens não utilizadas (limpeza)

Instalando Docker no Raspberry Pi

Docker: "ps: command not found" [Resolvido]

Rodando Jenkins no Podman

  

Comentários
[1] Comentário enviado por mauricio123 em 04/08/2020 - 20:48h


É útil que é uma loucura. Vai servir.

___________________________________
Conhecimento não se Leva para o Túmulo.

[2] Comentário enviado por ru4n em 05/08/2020 - 15:04h

Recurso muito interessante! Não tinha visto



Contribuir com comentário