Erstellen Sie den Kontext für das Docker-Image sehr groß


140

Ich habe auf meinem Host-Computer verschiedene Verzeichnisse erstellt, um mehr über Docker zu erfahren, damit meine Docker-Dateien organisiert bleiben. Meine Docker-Datei, die ich gerade ausgeführt habe, sieht folgendermaßen aus:

FROM crystal/centos
MAINTAINER crystal

ADD ./rpms/test.rpm ./rpms/ 
RUN yum -y --nogpgcheck localinstall /rpms/test.rpm 

Meine tatsächliche Drehzahl beträgt nur 1 GB. Wenn ich dies versuche sudo docker build -t="crystal/test" ., erhalte ich einen Build-Kontext an den Docker-Daemon mit 3,5 GB. Gibt es noch etwas, das mir nicht bekannt ist, wenn Sie weiterhin Docker-Images erstellen? Sammelt sich mein Speicher an, wenn ich mehr Bilder in meinen anderen Verzeichnissen auf meinem Host-Computer erstelle?


2
Der Erstellungskontext sind alle Dateien / Verzeichnisse im aktuellen Verzeichnis.
Nabin

Bewahren Sie in diesem Verzeichnis nur Dateien auf, die Sie für den Build benötigen. Das heißt, die Docker-Datei und alle lokalen Dateien / Verzeichnisse, die dem Build-Image in der Docker-Datei kopiert / hinzugefügt wurden. Nutzen Sie auch.dockerignore
Vishrant

Antworten:


264

Der Docker-Client sendet den gesamten "Build-Kontext" an den Docker-Daemon. Dieser Build-Kontext (standardmäßig) ist das gesamte Verzeichnis, in dem er sich Dockerfilebefindet (also der gesamte rpmsBaum).

Sie können eine .dockerignoreDatei einrichten, damit Docker einige Dateien ignoriert. Vielleicht möchten Sie damit experimentieren.

Alternativ können Sie Ihren rpmsOrdner eine Verzeichnisebene über Ihren Ordner verschieben Dockerfileund nur einen Symlink test.rpmin das DockerfileVerzeichnis des Ordners erstellen .


Wie viele Benutzer in den Kommentaren betonten , muss man den .gitOrdner zu dem hinzufügen , der.dockerignore die Ursache für einen Unterschied von 150 MB -> 5 GB in meinem Fall war.


4
Leider scheint Symlinking in diesem Fall nicht möglich zu sein, da der ADDBefehl während eines Builds keinen Sym- Links folgt. Siehe: github.com/docker/docker/issues/1676
JimmidyJoo

5
Lebensretter! Rails - Entwickler: Sicherstellen , dass hinzufügen tmp logzu .dockerignore+ anderen benutzerdefinierten diejenigen
equivalent8

7
Vergessen Sie nicht, den .git-Ordner zur .dockerignore-Datei hinzuzufügen (vorausgesetzt, Sie verwenden git)
dsncode

8
Ja, der .gitOrdner ist standardmäßig enthalten - das hat mich definitiv erwischt.
Paul Suart

1
Was genau ist der "Build-Kontext"? Ich habe versucht, mit dem Befehl docker build RUN nach diesen Dateien zu suchen, aber ich sehe die Dateien in meinem Dockerfile-Ordner im Docker-Dateisystem nicht (während der Erstellungszeit). Kann mir bitte jemand ein einfaches Beispiel geben, wie nützlich der Erstellungskontext ist?
Patrick

52

Update 2019

Ab Docker v18.06 besteht die Möglichkeit, einen neuen Image Builder namens Build Kit zu verwenden .

Es ist im Lieferumfang des Docker enthalten und muss nicht installiert werden. Es ist abwärtskompatibel mit der DockerfileSyntax, ohne dass die geändert werden muss Dockerfile.

Legacy Docker Build gegen New Docker BuildKit

Hier ist ein Beispiel für das Erstellen eines Images mit einer riesigen nicht verwendeten Datei im Build-Verzeichnis:

Legacy Docker Build:

$ time docker image build --no-cache .
Sending build context to Docker daemon  4.315GB
[...]
Successfully built c9ec5d33e12e

real    0m51.035s
user    0m7.189s
sys 0m10.712s

Neues Docker BuildKit:

$ time DOCKER_BUILDKIT=1 docker image build --no-cache .
[+] Building 0.1s (5/5) FINISHED                                                
 => [internal] load build definition from Dockerfile                       0.0s
 => => transferring dockerfile: 37B                                        0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
[...]
 => => writing image sha256:ba5bca3a525ac97573b2e1d3cb936ad50cf8129eedfa9  0.0s

real    0m0.166s
user    0m0.034s
sys 0m0.026s

Die einzige Änderung ist die DOCKER_BUILDKIT=1Umgebungsvariable, der Zeitunterschied ist enorm.

.dockerignore Datei

Bitte beachten Sie, dass die .dockerignoreDatei weiterhin gültig und nützlich ist. Einige DockerfileBefehle wie COPY . .berücksichtigen weiterhin die .dockerignoreRegeln. DockerfileDie Seitendateien im Build-Verzeichnis (auf die im nicht verwiesen wird ) werden vom BuildKit jedoch nicht mehr als "Build-Kontext" kopiert.


1
Es ist wichtig zu beachten, dass DOCKER_BUILDKIT derzeit für Windows-Container nicht unterstützt wird. (Nur Linux, unter Einschränkungen aufgeführt: docs.docker.com/develop/develop-images/build_enhancements )
Vaccano

17

Ich habe es behoben, indem ich meine Docker-Datei und docker-compose.yml in einen Unterordner verschoben habe, und es hat großartig funktioniert. Anscheinend sendet Docker den aktuellen Ordner an den Daemon und mein Ordner war 9 Gigs.


4
Diese Methode gibt den verbotenen Pfad an: Gibt es außerhalb des Build-Kontextfehlers eine Lösung für dieses Problem, wenn eine Datei aus einem übergeordneten Verzeichnis kopiert wird?
Kitwradr

8

Wenn Sie eine .dockerignoreDatei haben und der Build-Kontext immer noch groß ist, können Sie mit The Silver Searcher überprüfen, was an den Docker-Build-Kontext gesendet wird :

ag --path-to-ignore .dockerignore --files-with-matches

Beachten Sie, dass einige **Muster möglicherweise nicht richtig funktionieren.

Weitere Kommentare finden Sie in dieser Github-Ausgabe: https://github.com/moby/moby/issues/16056


4

In meinem Fall war das, als ich mit falschen -fArgumenten ausführte - ohne Pfad zum Verzeichnis, in dem sich Dockerfile befand

docker build --no-cache -t nginx5 -f /home/DF/Dockerfile /home/DF/ - richtig

docker build --no-cache -t nginx5 -f /home/DF/Dockerfile - falsch


1

Wenn Sie die vollständige Kontrolle über Ihren Build-Kontext haben möchten, können Sie den Container auch vollständig ohne Kontext und COPYrelevante Daten in den Container erstellen.

docker build - < Dockerfile

Ein Nachteil davon wäre, dass Sie mit diesem Ansatz nur ADDDinge in der Docker-Datei verwenden können, die auf eine Remote-URL verweisen, und keine Dateien von Ihrem lokalen Host.

Siehe https://docs.docker.com/engine/reference/commandline/build/#build-with--


0

Ich hatte das gleiche Problem wie FreeStyler. Ich habe jedoch aus einem Verzeichnis erstellt, das aus meinem Kontext stammt. Die Argumente -f waren also korrekt, der Kontext war falsch.

project 
|
-------docker-dir 

Aus dem Docker-Verzeichnis zu bauen, war das Folgende in Ordnung

docker build -t br_base:0.1 . 

Beim Erstellen aus dem Dock-Verzeichnis hat sich der Build-Kontext geändert. Daher musste ich den Kontext im Befehl ändern. Der Kontext wird durch das '.' im obigen Befehl.

Der neue Befehl aus dem Projektverzeichnis sollte sein

docker build -t br_base:0.1 ./base

Der Kontext hier ist durch die './base' gegeben.


0

Wenn Sie ein Image erstellen und den Build-Kontext für das Senden von Nachrichten an den Docker-Daemon erhalten, dessen Kopieren Protokollzeit benötigt,

Fügen Sie dann die .dockerignore-Datei hinzu . Es sollte die Dateien oder das Verzeichnis enthalten, die nicht kopiert werden müssen.


0

Für NodeJS Application, eine In - .dockerignoreDatei Ihres Root - Projektverzeichnis und in der .dockerignoreDatei die folgenden hinzufügen

node_modules
dist
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.