business cargo cargo container city

Como fazer uma imagem Docker com multi stage build

Estando todos vivendo numa era onde computação em nuvem vem sendo cada vez mais adotada, saber trabalhar com containers acaba se torna praticamente uma obrigação.

Por isso, nesse post, vamos ver como criar uma imagem Docker otimizada com multi stage build para aplicações escritas em Golang.

Antes de começar escrever nosso Dockerfile, vamos criar um arquivo main.go e escrever uma pequena API para retornar o famoso “Olá Mundo”.

package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(rw, "Olá Mundo\\n")
	})

	log.Fatal(http.ListenAndServe(":8000", nil))
}

Agora que já temos essa SUPER API, vamos iniciar nosso Dockerfile pelo stage de build. Para isso, aconselho utilizar a imagem oficial do golang como imagem base.

# stage de build
FROM golang:1.19 AS build

Repare que logo após o nome e versão da imagem, criamos um alias para esse stage utilizando um AS build.

Np próximo passo, vamos criar um WORKDIR e copiar todos os arquivos do projeto.

# stage de build
FROM golang:1.19 AS build

WORKDIR /app

COPY . /app

Por último, vamos fazer o build da aplicação.

# stage de build
FROM golang:1.19 AS build

WORKDIR /app

COPY . /app

RUN CGO_ENABLED=0 GOOS=linux go build -o api main.go

Note que adicionamos as flags CGO_ENABLED=0 para desabilitar o CGO, e GOOS=linux para que o resultado final seja um executável para linux.

Isso é necessário pois, como o Docker executa os containers utilizando parte da arquitetura do OS em que está rodando, caso você esteja utilizando Mac ou Windows e não passe a flag GOOS=linux, a imagem não irá funcionar no próximo stage, onde vamos usar o linux scratch como imagem base.

E por falar em próximo stage, vamos iniciá-lo adicionando a imagem base mencionada e criar um WORKDIR.

# stage de build
FROM golang:1.19 AS build

WORKDIR /app

COPY . /app

RUN CGO_ENABLED=0 GOOS=linux go build -o api main.go

# stage imagem final
FROM scratch

WORKDIR /app

Agora vem a parte mais importante. Copiar o binário do stage anterior para esse.

Para isso, vamos usar o comando COPY em conjunto com a flag --from, que serve para referenciar o local/stage onde buscar o arquivo.

# stage de build
FROM golang:1.19 AS build

WORKDIR /app

COPY . /app

RUN CGO_ENABLED=0 GOOS=linux go build -o api main.go

# stage imagem final
FROM scratch

WORKDIR /app

COPY --from=build /app/api ./

Para finalizar, vamos expor a porta 8000 e executar o binário que foi copiado.

# stage de build
FROM golang:1.19 AS build

WORKDIR /app

COPY . /app

RUN CGO_ENABLED=0 GOOS=linux go build -o api main.go

# stage imagem final
FROM scratch

WORKDIR /app

COPY --from=build /app/api ./

EXPOSE 8000

CMD [ "./api" ]

Agora é só fazer o build da image docker e utilizá-la.

Deixem suas dúvidas nos comentários.

Até a próxima!


Se inscreva na nossa newsletter

* indicates required

Deixe uma resposta