J’ai posté, il y a quelques temps, ce billet sur la mise en oeuvre d’une API Rest Golang avec MongoDB, où j’ai utilisé le multi-stage build de Docker. Et la semaine dernière, j’ai donné une conférence lors du Meetup Golang Bordeaux sur le thème Go déploiement avec Docker, je vais partager ci-dessous les informations de cette intervention.
Je repars de mon exemple d’API REST en Golang avec MongoDB et je vais changer l’image de référence, dans les phases de build des images Docker et mesurer la taille résultante de l’image Docker.
Je vais successivement contruire mon image en invoquant les distributions suivantes :
Ce script va me construire les différents images Docker :
#!/bin/bash
for filename in Dockerfile.*; do
docker build -t itwars/rest-"${filename##*.}" -f "$filename" .
done
Les tailles d’images Docker sont les suivantes :
testor@bdx:~/go/stack-rest-api-go-mongo\ Ω docker image ls
REPOSITORY SIZE
itwars/rest-golang 802MB
itwars/rest-centos 207MB
itwars/rest-debian 109MB
itwars/rest-ubuntu 89.4MB
itwars/rest-alpine 12.4MB
itwars/rest-scratch 8.22MB
itwars/rest-scratch-upx 1.76MB
Voici l’ensemble des Dockerfiles :
FROM golang
WORKDIR /go/src/github.com/user/app
COPY . .
RUN set -x && \
go get -d -v . && \
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM golang
WORKDIR /root/
COPY --from=0 /go/src/github.com/user/app .
EXPOSE 3000
CMD ["./app"]
FROM golang
WORKDIR /go/src/github.com/user/app
COPY . .
RUN set -x && \
go get -d -v . && \
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM centos
WORKDIR /root/
COPY --from=0 /go/src/github.com/user/app .
EXPOSE 3000
CMD ["./app"]
FROM golang
WORKDIR /go/src/github.com/user/app
COPY . .
RUN set -x && \
go get -d -v . && \
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM debian
WORKDIR /root/
COPY --from=0 /go/src/github.com/user/app .
EXPOSE 3000
CMD ["./app"]
FROM golang
WORKDIR /go/src/github.com/user/app
COPY . .
RUN set -x && \
go get -d -v . && \
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM ubuntu
WORKDIR /root/
COPY --from=0 /go/src/github.com/user/app .
EXPOSE 3000
CMD ["./app"]
FROM golang
WORKDIR /go/src/github.com/user/app
COPY . .
RUN set -x && \
go get -d -v . && \
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine
WORKDIR /root/
COPY --from=0 /go/src/github.com/user/app .
EXPOSE 3000
CMD ["./app"]
FROM golang
WORKDIR /go/src/github.com/user/app
COPY . .
RUN set -x && \
go get -d -v . && \
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM scratch
WORKDIR /root/
COPY --from=0 /go/src/github.com/user/app .
EXPOSE 3000
CMD ["./app"]
L’outil upx the Ultimate Packer for eXecutables permet de créer un fichier exécutable compressé, ainsi l’image Docker Golang fait moins de 1.8Mo.
FROM golang
WORKDIR /go/src/github.com/user/app
COPY . .
ADD https://github.com/upx/upx/releases/download/v3.94/upx-3.94-amd64_linux.tar.xz /usr/local
RUN set -x && \
apt update && \
apt install -y xz-utils && \
xz -d -c /usr/local/upx-3.94-amd64_linux.tar.xz | \
tar -xOf - upx-3.94-amd64_linux/upx > /bin/upx && \
chmod a+x /bin/upx && \
go get -d -v . && \
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . && \
strip --strip-unneeded app && \
upx app
FROM scratch
WORKDIR /root/
COPY --from=0 /go/src/github.com/user/app .
EXPOSE 3000
CMD ["./app"]
Comme on peut le constater, la taille des containers Docker varient dans des proportions importantes de 800Mo à 2Mo !