2021-04-09 08:42:54 +0200 +0200

Prskavčí blog

Apr 21, 2017

Docker - multi stage build

Tato novinka je dostupná v poslední verzi Dockeru 17.05, musíte mít Edge edici a se zapnutými experimentálním funkcemi, ale objeví se to v další stabilní verzi. Je pro jistotu tady je výpis z mého docker version.

$ docker version
Client:
 Version:      17.05.0-ce-rc1
 API version:  1.29
 Go version:   go1.7.5
 Git commit:   2878a85
 Built:        Tue Apr 11 20:55:05 2017
 OS/Arch:      darwin/amd64

Server:
 Version:      17.05.0-ce-rc1
 API version:  1.29 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   2878a85
 Built:        Tue Apr 11 20:55:05 2017
 OS/Arch:      linux/amd64
 Experimental: true

Multi stage

O co vlastně jde v tom multi stage. Pokud potřebujete vyrobit image pro aplikaci, která má artefakty (C/C++, Go, Java, etc.) tak potřebujete jen malou část těch závislostí pro běh v produkci, ale při výrobě těchto artefaktů musíte nainstalovat hodně a většinou ne malých závislostí. Řešilo se to patternem builder za pomocí dvou Dockerfile souborů, ale teď existuje jednodušší řešení.

Řešení v jednom souboru kde máte dvě sekce, každá začíná deklarací FROM. Tady je ukázka pro Go.

FROM golang:1.8 as builder

ENV GLIDE_VERSION 0.10.2
ENV APP_VERSION 1.0.2

ADD https://github.com/Masterminds/glide/releases/download/${GLIDE_VERSION}/glide-${GLIDE_VERSION}-linux-amd64.tar.gz /tmp/glide-${GLIDE_VERSION}-linux-amd64.tar.gz

RUN cd /tmp && \
    tar -zxvf /tmp/glide-${GLIDE_VERSION}-linux-amd64.tar.gz && \
    cp /tmp/linux-amd64/glide /usr/local/bin/glide && \
    chmod 755 /usr/local/bin/glide && \
    rm /tmp/glide-${GLIDE_VERSION}-linux-amd64.tar.gz && rm -rf /tmp/linux-amd64/

COPY . /go/src/github.com/apiaryio/heroku-datadog-drain-go

RUN cd /go/src/github.com/apiaryio/heroku-datadog-drain-go && \
    glide install && \
    go install

FROM scratch
COPY --from=builder /go/bin/heroku-datadog-drain-go .
CMD ["./heroku-datadog-drain-go"]

V první části se použije image golang a nainstaluje se glide (package manager) a vyrobí se binární soubor, který potom v druhé část (FROM scratch) se použije a pomocí COPY --from=builder se překopíruje artefakt z jednoho image do druhého. Pokud si image v první sekci nepojmenujete tak použijte číselné označení COPY --from=0.

Výsledné image potom vypadají takto:

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
drain               latest              7a7abced7a9d        6 seconds ago       10MB
<none>              <none>              edabce509d75        7 seconds ago       752MB
golang              1.8                 c0ccf5f2c036        13 days ago         703MB

Máte dva image jeden pro produkci a druhý můžete klidne smazat.

Závěr

Tato inovace zjednodušší život mnoha lidem a je to super. Pokud si to chcete vyzkoušet můžete na webu v bez nutnosti instalovat si poslední Docker.