webentwicklung-frage-antwort-db.com.de

Wie fügen Sie Elemente zu .dockerignore hinzu?

Ich kann nicht viele Beispiele finden, wie eine .dockerignore-Datei aussehen sollte. 

Bei der Installation einiger Pakete in einem Docker-Container mithilfe von Marionette wird das Image von 600 MB bis 3 GB explodiert. Ich versuche eine .dockerignore-Datei zu verwenden, um die Größe auf ein Minimum zu beschränken

$ cat Dockerfile  
FROM centos:centos6

#Work around selinux problem on cent images
RUN yum install -y --enablerepo=centosplus libselinux-devel

RUN yum install -y wget git tar openssh-server; yum -y clean all

Add Puppetfile / 
RUN librarian-puppet install
RUN puppet apply --modulepath=/modules -e "class { 'buildslave': jenkins_slave => true,}"
RUN librarian-puppet clean

Wenn ich docker images --tree starte, kann ich sehen, dass das Bild sofort um einige GB wächst

$ docker images --tree
                ├─e289570b5555 Virtual Size: 387.7 MB
                │ └─a7646acf90d0 Virtual Size: 442.5 MB
                │   └─d7bc6e1fbe43 Virtual Size: 442.5 MB
                │     └─772e6b204e3b Virtual Size: 627.5 MB
                │       └─599a7b5226f4 Virtual Size: 627.5 MB
                │         └─9fbffccda8bd Virtual Size: 2.943 GB
                │           └─ee46af013f6b Virtual Size: 2.943 GB
                │             └─3e4fe065fd07 Virtual Size: 2.943 GB
                │               └─de9ec3eba39e Virtual Size: 2.943 GB
                │                 └─31cba2716a12 Virtual Size: 2.943 GB
                │                   └─52cbc742d3c4 Virtual Size: 2.943 GB
                │                     └─9a857380258c Virtual Size: 2.943 GB
                │                       └─c6d87a343807 Virtual Size: 2.964 GB
                │                         └─f664124e0080 Virtual Size: 2.964 GB
                │                           └─e6cc212038b9 Virtual Size: 2.964 GB Tags: foo/jenkins-centos6-buildslave:latest

Ich glaube, der Grund dafür, dass das Bild so groß wird, liegt darin, dass librarian-puppet ein Marionettenmodul nach /modules klont, was den Build-Cache zerstört

Ich habe die folgenden .dockerignore-Dateien ohne Erfolg ausprobiert.

$ cat .dockerignore
/modules
/modules/
/modules/*

Ist dies die richtige Syntax für eine .dockerignore-Datei?
Gibt es andere Möglichkeiten, um zu verhindern, dass diese Behälter so groß werden? 

Zusätzliche Information:

http://kartar.net/2013/12/building-puppet-apps-inside-docker/
http://danielmartins.ninja/posts/a-week-of-docker.html

21
spuder

.dockerignore soll verhindern, dass Dateien zu dem ursprünglichen Build-Kontext hinzugefügt werden, der an den Docker-Daemon gesendet wird, wenn Sie docker build ausführen. Er erstellt keine globale Regel, die das Erstellen von Dateien in allen von einer Dockerfile generierten Bildern ausschließt.

Beachten Sie, dass jede RUN-Anweisung ein neues Bild generiert, wobei das übergeordnete Element dieses Bildes das Bild ist, das von der darüber liegenden Dockerfile-Anweisung generiert wird. Versuchen Sie, Ihre RUN-Anweisungen in einer einzigen Anweisung zusammenzufassen, um die Bildgröße zu reduzieren:

RUN librarian-puppet install &&\
 puppet apply --modulepath=/modules -e "class { 'buildslave': jenkins_slave => true,}" &&\
 librarian-puppet clean
27
Abe Voelker

Das Format von .dockerignore sollte dem Format von .gitignore entsprechen. Siehe eine Beispieldatei und die Docker Dokumentation .

Die Datei sollte eine Liste von Ausschlussmustern (relativ zum Pfad der .dockerignore-Datei) sein, die durch eine neue Zeile getrennt sind. 

Sie sollten also den folgenden .dockerignore ausprobieren:

modules/*

Der / am Anfang könnte der Fehler gewesen sein, da er nur für das Stammverzeichnis der Datei gültig ist (nicht jedoch für Unterverzeichnisse, sodass die rekursive Version ohne / stattdessen eine bessere Aufgabe erfüllt).

18

Weder:

modules/*

noch

modules

würde nicht funktionieren für mich, Docker verschmutzte das Bild mit unnötigen Dateien, bis ich es so eingestellt habe:

**/modules

funktioniert auch mit:

**/modules/*.py
7
Kostyantyn

Die Datei .dockerignore Ähnelt der Syntax .gitignore. Hier sind einige Beispielregeln:

# Ignore a file or directory in the context root named "modules"
modules

# Ignore any files or directories within the subdirectory named "modules" 
# in the context root
modules/*

# Ignore any files or directories in the context root beginning with "modules"
modules*

# Ignore any files or directories one level down from the context root named
# "modules"
*/modules

# Ignore any files or directories at any level, including the context root, 
# named modules
**/modules

# Ignore every file in the entire build context (see next rule for how this 
# could be used)
*

# Re-include the file or directory named "src" that may have been previously
# excluded. Note that you cannot re-include files in subdirectories that have 
# been previously excluded at a higher level
!src

Beachten Sie, dass "Erstellungskontext" das Verzeichnis ist, das Sie am Ende Ihres Erstellungsbefehls übergeben, normalerweise ein ., Um das aktuelle Verzeichnis anzugeben. Dieses Verzeichnis wird vom Docker-Client aus gepackt, mit Ausnahme aller Dateien, die Sie mit .dockerignore Ignoriert und an den Docker-Daemon gesendet haben, um die Erstellung durchzuführen. Selbst wenn sich der Dämon auf demselben Host wie Ihr Client befindet, funktioniert der Build nur in diesem Kontext und nicht direkt in den Ordnern.

Es gibt nur ein einziges .dockerignore Für einen Build und es muss sich im Stammverzeichnis des Build-Kontexts befinden. Es funktioniert nicht, wenn es sich in Ihrem Ausgangsverzeichnis befindet (vorausgesetzt, Sie erstellen aus einem Unterverzeichnis), und es funktioniert nicht aus einem Unterverzeichnis Ihres Erstellungskontexts.

Um zu testen, was sich in Ihrem aktuellen Build-Kontext befindet und um sicherzustellen, dass sich Ihre .dockerignore - Datei korrekt verhält, können Sie Folgendes kopieren/einfügen (dies setzt voraus, dass Sie kein Bild mit dem Namen test-context Haben) überschrieben und dann gelöscht, wenn Sie dies tun):

# create an image that includes the entire build context
docker build -t test-context -f - . <<EOF
FROM busybox
COPY . /context
WORKDIR /context
CMD find .
EOF

# run the image which executes the find command
docker container run --rm test-context

# cleanup the built image
docker image rm test-context
4
BMitch

Eine andere Möglichkeit, ein kleineres Bild zu erstellen, besteht darin, die Bibliothekar-Marionette im Host auszuführen , nicht im Docker, damit Sie nicht mit Bibliothekar, Ruby, Edelsteinen, ... im Bild installiert werden .

Ich endete mit einem 622MB Image für Jenkins Slave mit Puppet und einem 480MB Image ohne Puppet .

3
csanchez

http://docs.docker.com/articles/dockerfile_best-practices/

Es scheint mir, dass Ihr Ansatz rückwärts ist (stimmt mit @csanchez überein), und dass Sie Ihren Docker-Container aus einer Marionette generieren sollten und keine Marionette in dem Container ausführen ...

Außerdem sollten Sie && die install/apply/clean-Zeilen zusammenstellen ... Jeder Docker-Befehl erstellt ein inkrementelles Image ... Wenn temporäre/Ressourcendateien Teil der centos yum-Befehle sind, sollten Sie dasselbe tun.

FROM centos:centos6

# Add your needed files first
# maybe you could use a baseimage and make this a volume mount point?
Add Puppetfile / 

# combine multiple commands with cleanup of cache/temporary
# space in the same run sequence to reduce wasted diff image space.

#Work around selinux problem on cent images
RUN yum install -y --enablerepo=centosplus libselinux-devel && \
    yum install -y wget git tar openssh-server; yum -y clean all && \
    librarian-puppet install && \
    puppet apply --modulepath=/modules -e "class { 'buildslave': jenkins_slave => true,}" && \
    librarian-puppet clean

Ich würde WIRKLICH vorschlagen, SELINUX in einem Container zu meiden, es gibt Ihnen nichts in einem Container. Ganz zu schweigen davon, dass es je nach dem, was Sie erstellen möchten, kleinere Orte gibt, von denen aus Sie beginnen könnten als centos6. Ich glaube, Ubuntu ist kleiner, Debian: noch kleiner oder sogar alpin für einen winzigen Startpunkt.

Es ist erwähnenswert, dass Ihre Dateigröße, wenn Sie ein Dateisystem verwenden, das virtuelle Mounts unterstützt, dasselbe Basisimage für mehrere Instanzen wiederverwenden kann, so dass es nicht größer wird more

2
Tracker1

Die Optimierung der Größe des Container-Images ist das Hauptziel von .dockerignore, da es einem ähnlichen Zweck wie .gitignore dient, da es die Latenzzeit und Reaktionszeit beim Bereitstellen von Services verringert. Dies gilt für die Bereitstellungsautomatisierung wie Puppet, SaltStack oder Ansible. Der Zeitstempel, der für die Bereitstellung von Services definiert wurde, ist möglicherweise aufgrund eines größeren Images und einer geringen Netzwerkbandbreite fehlgeschlagen. .Dockerignore hilft also, die Größe des Bildes so klein wie möglich zu machen. 

Sie können es in das build-Kontextverzeichnis einfügen, das wir am Ende eines Docker-Build-Befehls angeben. Die Datei folgt glob pattern für Dateien und Verzeichnisse, um diese vom endgültigen Build-Image auszuschließen.

Angenommen, ich habe ein Verzeichnis .img/ in meinem Build-Kontext, und ich möchte es beim Erstellen des Images ausschließen. Ich füge einfach die folgende Zeile in die .dockerignore-Datei ein:

.img

Und wenn ich alle Dateien ausschließen möchte, beginnt mit. dann einfach die Zeile hinzufügen,

.*

(Anmerkung: Verwechseln Sie nicht das Unix-Glob-Muster unterscheidet sich von regulären Ausdrücken.)

Außerdem werde ich einige weitere Dateien aus meinem Build-Kontext ausschließen.

.*
docs
my-stack.dab
docker-compose.overrride.yml
test*
*.md
!README.md

Hier schließt die Zeile * .md alle Markdown-Dateien aus (ich habe viele Markdown-Dateien in meinem Projekt). Ich möchte jedoch README.md und keine anderen Markdown-Dateien einschließen. Als letzte Zeile in oben haben wir README.md mit hinzugefügt! oder ausschließen, während alle anderen Markdown-Dateien ausgeschlossen werden. 

Auf diese Weise können wir mit .dockerignore den Aufwand für Ihr Build-Image reduzieren und die Bildgröße reduzieren.

0
mohan08p

Ich denke, die beste Lösung für Ihren Anwendungsfall ist die Verwendung eines mehrstufigen Builds in Ihrer Docker-Datei. Ihre Docker-Datei muss sich in einem leeren Verzeichnis befinden, und Sie führen Puppet in einem Einwegbehälter aus.

Über den obigen Link:

Bei mehrstufigen Builds verwenden Sie mehrere FROM-Anweisungen in Ihrer Docker-Datei. Jeder FROM-Befehl kann eine andere Basis verwenden, und jeder von ihnen beginnt eine neue Phase des Builds. Sie können Artefakte selektiv von einer Stufe zur nächsten kopieren und dabei alles zurücklassen, was Sie im endgültigen Bild nicht möchten.

0
neves