Docker multi stage builds
Dica publicada em Linux / Docker
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
E seguida no mesmo diretório criaremos o famoso "hello world" em golang:
vim meuapp.go
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
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
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
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.
Pré-requisitos:
- Docker - https://www.docker.com/get-started
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
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 810MBNote 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
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.57MBPerceba 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.
É útil que é uma loucura. Vai servir.
___________________________________
Conhecimento não se Leva para o Túmulo.