2014-03-28 6 views
17

Ich machte einen Docker-Container, der ziemlich groß ist. Wenn ich den Container festlege, um ein Image zu erstellen, ist das Image ungefähr 7,8 GB groß. Aber wenn ich den Container export (nicht save das Bild!) Zu einem Tarball importiere und es neu importiere, ist das Image nur 3 GB groß. Natürlich ist die Geschichte verloren, aber das ist OK für mich, da das Image meiner Meinung nach "fertig" und bereit für den Einsatz ist.Wie man ein Docker-Bild abflacht?

Wie kann ich ein Bild/Container reduzieren, ohne es auf die Festplatte zu exportieren und erneut zu importieren? Und: Ist es eine kluge Idee, das zu tun oder fehlt mir ein wichtiger Punkt?

+1

bauen Sie mit der '' '--rm''' Option ? Dies entfernt Zwischenbilder. Oder habe ich die Frage falsch verstanden? – shabbychef

+1

Es gibt einige andere Tricks, um das Bild zu verkleinern: Rufen Sie eine Reihe von Installationsbefehlen in einem '' 'RUN''' auf, entfernen Sie nicht benötigte Ubuntu-Pakete, _etc._ Siehe https://github.com/dckc/ipython-docker/blob/master/Dockerfile für ein gutes Beispiel. – shabbychef

Antwort

15

Ab Docker 1.13 können Sie das Flag --squash verwenden.


Vor Version 1.13:

Meines Wissens können Sie die Docker api nicht verwenden. docker export und docker import sind für dieses Szenario gedacht, wie Sie selbst schon erwähnen.

Wenn Sie nicht auf die Festplatte speichern möchten, könnten Sie wahrscheinlich den Ausgabestrom des Exports in den Eingabestream des Imports leiten. Ich habe nicht getestet, aber

docker export red_panda | docker import - exampleimagelocal:new 
+0

Ich habe das gerade mit "Docker Version 1.1.1, Build bd609d2" gemacht und das resultierende Bild war nicht viel kleiner. Es war tatsächlich ein bisschen größer. Aber die Geschichte war für das neue Bild weg. – VolkerK

+0

Funktioniert gut mit Docker 17.03.0-CE. Ab 33GB Bildgröße wurde auf 19GB reduziert –

8

Jetzt, da Docker die mehrstufigen Builds in 17.05 veröffentlicht hat, können Sie yo neu formatieren ur Build wie folgt aussehen:

FROM buildimage as build 
# your existing build steps here 
FROM scratch 
COPY --from=build// 
CMD ["/your/start/script"] 

Das Ergebnis Ihrer Bauumgebung Schichten auf dem Build-Server zwischengespeichert werden wird, sondern nur eine abgeflachte Kopie wird in dem resultierenden Bild vorhanden sind, die Sie markieren, und drücken Sie.

Hinweis, Sie würden dies normalerweise neu formulieren, um eine komplexe Build-Umgebung zu haben und nur über einige Verzeichnisse zu kopieren.Hier ist ein Beispiel mit Go ein einziges binäres Bild aus dem Quellcode und einem einzigen Build-Befehl zu machen, ohne Go Installation auf dem Host und außerhalb von Docker Kompilieren:

$ cat Dockerfile 
ARG GOLANG_VER=1.8 
FROM golang:${GOLANG_VER} as builder 
WORKDIR /go/src/app 
COPY . . 
RUN go-wrapper download 
RUN go-wrapper install 

FROM scratch 
COPY --from=builder /go/bin/app /app 
CMD ["/app"] 

Die Go-Datei ist eine einfache Hallo Welt:

$ cat hello.go 
package main 

import "fmt" 

func main() { 
     fmt.Printf("Hello, world.\n") 
} 

der Build schafft beide Umgebungen, die Build-Umgebung und die Kratzer ein und dann markiert die Kratzer ein:

$ docker build -t test-multi-hello .                                
Sending build context to Docker daemon 4.096kB 
Step 1/9 : ARG GOLANG_VER=1.8 
---> 
Step 2/9 : FROM golang:${GOLANG_VER} as builder 
---> a0c61f0b0796 
Step 3/9 : WORKDIR /go/src/app 
---> Using cache 
---> af5177aae437 
Step 4/9 : COPY . . 
---> Using cache 
---> 976490d44468 
Step 5/9 : RUN go-wrapper download 
---> Using cache 
---> e31ac3ce83c3 
Step 6/9 : RUN go-wrapper install 
---> Using cache 
---> 2630f482fe78 
Step 7/9 : FROM scratch 
---> 
Step 8/9 : COPY --from=builder /go/bin/app /app 
---> Using cache 
---> 5645db256412 
Step 9/9 : CMD /app 
---> Using cache 
---> 8d428d6f7113 
Successfully built 8d428d6f7113 
Successfully tagged test-multi-hello:latest 

auf den Bildern sucht, wird nur die einzige bi nary wird in dem Bild verschifft, während die Build-Umgebung über 700 MB ist:

$ docker images | grep 2630f482fe78 
<none>    <none>    2630f482fe78  6 days ago   700MB 

$ docker images | grep 8d428d6f7113 
test-multi-hello  latest    8d428d6f7113  6 days ago   1.56MB 

Und ja, es läuft:

$ docker run --rm test-multi-hello 
Hello, world. 
+0

Dies sollte die akzeptierte Antwort zu dieser Zeit sein .. Es ist sehr effektiv und flexibel! –