Japanische Übersetzung von Dockerfile-Referenz.
Docker kann das Image automatisch erstellen, indem es die Anweisungen aus der Docker-Datei liest. Die Docker-Datei ist ein Textdokument, das die Befehle zum Erstellen eines Bildes beschreibt. Wird vom Benutzer über die Befehlszeile aufgerufen und verwendet. Mit dem Docker-Build (https://qiita.com/JhonnyBravo/items/87976fe9de47ed58b8b1) können Benutzer automatische Builds erstellen, die mehrere Befehlszeilenanweisungen nacheinander ausführen.
Diese Seite beschreibt die Befehle, die Sie in Ihrer Docker-Datei verwenden können. Lesen Sie nach dem Lesen dieser Seite unter Dockerfile Best Practices für eine tipporientierte Anleitung.
Der Befehl Docker Build erstellt ein Image aus einer Docker-Datei und einem Kontext. Der Build-Kontext besteht aus einer Reihe von Dateien im PATH oder in der URL am angegebenen Speicherort. PATH ist ein Verzeichnis in Ihrem lokalen Dateisystem. Die URL ist der Speicherort des Git-Repositorys.
Kontexte werden rekursiv verarbeitet. Daher enthält der PATH Unterverzeichnisse und die URL das Repository und seine Submodule. Das folgende Beispiel zeigt einen Build-Befehl, der das aktuelle Verzeichnis als Kontext verwendet.
$ docker build .
Sending build context to Docker daemon 6.51 MB
...
Der Build wird vom Docker-Daemon ausgeführt, nicht von der CLI. Der Build-Prozess sendet zunächst den gesamten Kontext (rekursiv) an den Daemon. In den meisten Fällen empfiehlt es sich, mit einem leeren Verzeichnis als Kontext zu beginnen und die Docker-Datei in diesem Verzeichnis zu belassen. Fügen Sie nur die Dateien hinzu, die zum Erstellen der Docker-Datei erforderlich sind.
** Warnung ** Verwenden Sie nicht das Stammverzeichnis
/
als PATH. Der gesamte Inhalt der Festplatte wird beim Ausführen des Builds an den Docker-Daemon übertragen.
Wenn Sie eine Datei in einem Build-Kontext verwenden, verweist Dockerfile auf die Datei, die durch eine Anweisung wie die Anweisung "COPY" angegeben wird.
Fügen Sie zur Verbesserung der Build-Leistung die Datei ".dockerignore" zum Kontextverzeichnis hinzu, um die Dateien und Verzeichnisse auszuschließen.
In der Dokumentation auf dieser Seite finden Sie Anweisungen zum Erstellen einer .dockerignore
-Datei.
Konventionell wird die Docker-Datei an der Wurzel des Kontexts platziert. Sie können das Flag "-f" in Docker-Build verwenden, um an einer beliebigen Stelle im Dateisystem eine "Docker-Datei" anzugeben. ..
$ docker build -f /path/to/a/Dockerfile .
Sie können ein Repository und Tags angeben, um das neue Image zu speichern, wenn der Build erfolgreich ist.
$ docker build -t shykes/myapp .
Um ein Image nach dem Erstellen mehreren Repositorys zuzuordnen, fügen Sie beim Ausführen des Befehls build mehrere -t
-Parameter hinzu.
$ docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .
Der Docker-Dämon führt eine Vorvalidierung der Docker-Datei durch, bevor die Anweisungen in der Docker-Datei ausgeführt werden, und gibt einen Fehler zurück, wenn die Syntax falsch ist.
$ docker build -t test/myapp .
Sending build context to Docker daemon 2.048 kB
Error response from daemon: Unknown instruction: RUNCMD
Der Docker-Dämon führt die Anweisungen in der Docker-Datei einzeln aus, schreibt die Ergebnisse jeder Anweisung nach Bedarf in ein neues Bild und druckt schließlich die ID des neuen Bildes. Der Docker-Daemon bereinigt automatisch den von Ihnen übermittelten Kontext.
Beachten Sie, dass jede Anweisung unabhängig ausgeführt wird und ein neues Bild erstellt.
Daher hat RUN cd / tmp
keinen Einfluss auf die folgenden Anweisungen.
Wann immer möglich, verwendet Docker Zwischenbilder (Caches) erneut, um den Docker-Erstellungsprozess erheblich zu beschleunigen. Die Wiederverwendung von Zwischenbildern wird durch die Meldung "Cache verwenden" in der Konsolenausgabe angezeigt. (Weitere Informationen finden Sie im Dockerfile Best Practices Guide (https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/).)
$ docker build -t svendowideit/ambassador .
Sending build context to Docker daemon 15.36 kB
Step 1/4 : FROM alpine:3.2
---> 31f630c65071
Step 2/4 : MAINTAINER [email protected]
---> Using cache
---> 2a1c91448f5f
Step 3/4 : RUN apk update && apk add socat && rm -r /var/cache/
---> Using cache
---> 21ed6e7fbb73
Step 4/4 : CMD env | grep _TCP= | (sed 's/.*_PORT_\([0-9]*\)_TCP=tcp:\/\/\(.*\):\(.*\)/socat -t 100000000 TCP4-LISTEN:\1,fork,reuseaddr TCP4:\2:\3 \&/' && echo wait) | sh
---> Using cache
---> 7ea8aef582cc
Successfully built 7ea8aef582cc
Der Build-Cache wird nur aus dem lokalen Image verwendet, das die übergeordnete Kette enthält.
Dies bedeutet, dass das Image von einem vorherigen Build erstellt wurde oder die gesamte Image-Kette mit "Docker Load" geladen wurde.
Wenn Sie den Build-Cache für ein bestimmtes Image verwenden möchten, können Sie ihn mit der Option --cache-from
angeben.
Das durch --cache-from
angegebene Bild muss keine übergeordnete Kette haben und kann aus anderen Registern abgerufen werden.
Sobald der Build abgeschlossen ist, können Sie überlegen, wie Sie das Repository in die Registrierung verschieben können.
BuildKit
Docker Version 18.09 und höher unterstützt ein neues Backend für die Ausführung der Builds, die vom Projekt moby / buildkit bereitgestellt werden. Das BuildKit-Backend bietet gegenüber älteren Implementierungen viele Vorteile. Zum Beispiel kann BuildKit:
Um das BuildKit-Backend verwenden zu können, müssen Sie die Umgebungsvariable DOCKER_BUILDKIT = 1
in der CLI festlegen, bevor Sie [Docker Build] aufrufen (https://qiita.com/JhonnyBravo/items/87976fe9de47ed58b8b1).
In der Dokumentation zum BuildKit-Repository (https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md) finden Sie Informationen zur experimentellen Dockerfile-Syntax, die mit BuildKit-basierten Builds verwendet werden kann. Bitte.
Format
Das Format der Docker-Datei lautet:
# Comment
INSTRUCTION arguments
Die Anweisungen unterscheiden nicht zwischen Groß- und Kleinschreibung. Es ist jedoch üblich, es groß zu schreiben, um es von seinen Argumenten zu unterscheiden.
Docker führt die Anweisungen in der Docker-Datei nacheinander aus.
Die Docker-Datei muss mit der Anweisung FROM
beginnen.
Dies kann nach Parser-Anweisungen, Kommentaren und dem globalen Bereich "ARG" erfolgen.
Die Anweisung FROM
gibt das übergeordnete Image an, aus dem es erstellt wurde.
Dem "FROM" kann nur eine oder mehrere "ARG" -Anweisungen vorangestellt werden, die die in der Zeile "FROM" der Docker-Datei verwendeten Argumente deklarieren.
Docker behandelt Zeilen, die mit "#" beginnen, als Kommentare, es sei denn, die Zeile ist eine gültige Parser-Direktive.
#
Markierungen an anderer Stelle in der Zeile werden als Argumente behandelt.
Dies ermöglicht Aussagen wie:
# Comment
RUN echo 'we are running some # of cool things'
Die Kommentarzeile wird entfernt, bevor die Dockerfile-Anweisung ausgeführt wird. Das heißt, die Kommentare im folgenden Beispiel werden nicht von der Shell verarbeitet, die den Befehl "echo" ausführt. Beide folgenden Beispiele sind äquivalent.
RUN echo hello \
# comment
world
RUN echo hello \
world
Zeilenfortsetzungszeichen werden in Kommentaren nicht unterstützt.
** Hinweise zu Leerzeichen **
Aus Gründen der Abwärtskompatibilität werden führende Leerzeichen vor Kommentaren (
#
) und Anweisungen (z. B.RUN
) ignoriert, aber nicht empfohlen. In diesen Fällen bleiben die führenden Leerzeichen nicht erhalten, daher ist das folgende Beispiel gleichwertig.
# this is a comment-line RUN echo hello RUN echo world
# this is a comment-line RUN echo hello RUN echo world
Leerzeichen in Anweisungsargumenten, wie z. B. Befehle nach "RUN", bleiben jedoch erhalten. Im folgenden Beispiel wird "Hallo Welt" am Anfang mit einem Leerzeichen ausgegeben.
RUN echo "\ hello\ world"
Parser-Anweisungen sind optional und wirken sich darauf aus, wie nachfolgende Zeilen in der Docker-Datei verarbeitet werden.
Parser-Direktiven fügen dem Build keine Ebenen hinzu und werden nicht als Build-Schritte angezeigt.
Parser-Direktiven werden als spezielle Art von Kommentar in der Form # directive = value
geschrieben.
Eine Direktive kann nur einmal verwendet werden.
Wenn ein Kommentar, eine leere Zeile oder eine Builder-Anweisung verarbeitet wird, sucht Docker nicht mehr nach Parser-Anweisungen. Es behandelt das, was als Parser-Direktive geschrieben wurde, als Kommentar und versucht nicht zu überprüfen, ob es sich möglicherweise um eine Parser-Direktive handelt. Daher müssen sich alle Parser-Anweisungen oben in der Docker-Datei befinden.
Parser-Direktiven unterscheiden nicht zwischen Groß- und Kleinschreibung. Konventionell sollte es jedoch niedriger sein. Konventionell können Sie nach der Parser-Direktive auch eine Leerzeile einfügen. Zeilenfortsetzungszeichen werden in Parser-Anweisungen nicht unterstützt.
Aufgrund dieser Regeln sind alle folgenden Beispiele ungültig:
Ungültig wegen Fortsetzung der Leitung
# direc \
tive=value
Ungültig, da es zweimal angezeigt wird
# directive=value1
# directive=value2
FROM ImageName
Es wird als Kommentar behandelt, da es nach den Anweisungen des Builders angezeigt wird.
FROM ImageName
# directive=value
Es wird als Kommentar behandelt, da es nach einem Kommentar angezeigt wird, der keine Parser-Direktive ist.
# About my dockerfile
# directive=value
FROM ImageName
unknowndirective
wird als Kommentar behandelt, da er nicht erkannt wird.
Außerdem wird "bekanntes Verzeichnis" als Kommentar behandelt, da es nach einem Kommentar erscheint, der keine Parser-Direktive ist.
# unknowndirective=value
# knowndirective=value
Die Parser-Direktive erlaubt Leerzeichen ohne Unterbrechungen. Daher werden die folgenden Zeilen alle gleich behandelt.
#directive=value
# directive =value
# directive= value
# directive = value
# dIrEcTiVe=value
Die folgenden Parser-Anweisungen werden unterstützt.
syntax
# syntax=[remote image reference]
Beispiel
# syntax=docker/dockerfile
# syntax=docker/dockerfile:1.0
# syntax=docker.io/docker/dockerfile:1
# syntax=docker/dockerfile:1.0.0-experimental
# syntax=example.com/user/repo:tag@sha256:abcdef...
Diese Funktion ist nur aktiviert, wenn das BuildKit-Backend verwendet wird.
Die Direktive Syntax
definiert den Speicherort des Dockerfile-Builders, der zum Erstellen der aktuellen Dockerfile verwendet wird.
Mit dem BuildKit-Backend können Sie nahtlos eine externe Implementierung des Builders verwenden, die als Docker-Image verteilt ist und in einer Container-Sandbox-Umgebung ausgeführt wird.
Mit der benutzerdefinierten Dockerfile-Implementierung können Sie:
Docker verteilt die offizielle Version des Images, mit der eine Docker-Datei im Docker / Docker-Datei-Repository von DockerHub erstellt werden kann. Es gibt zwei Kanäle, auf denen neue Bilder veröffentlicht werden: stabil und experimentell.
Stabile Kanäle folgen der semantischen Versionierung.
Beispiel:
Der experimentelle Kanal verwendet bei der Veröffentlichung eine inkrementelle Versionsverwaltung mit Haupt- und Nebenkomponenten aus dem stabilen Kanal.
Beispiel:
Sie müssen den Kanal auswählen, der Ihren Anforderungen entspricht. Wenn Sie nur Fehler beheben müssen, müssen Sie Docker / Dockerfile: 1.0 verwenden. Wenn Sie experimentelle Funktionen nutzen möchten, müssen Sie den experimentellen Kanal verwenden. Wenn Sie den experimentellen Kanal verwenden, empfehlen wir die Verwendung der unveränderlichen Vollversionsvariante, da neue Versionen möglicherweise nicht abwärtskompatibel sind.
In der Beschreibung des Quell-Repositorys (https://github.com/moby/buildkit/blob/master/README.md) finden Sie Informationen zu Master-Builds und nächtlichen Feature-Releases.
escape
# escape=\ (backslash)
Oder
# escape=` (backtick)
Escape-Anweisungen legen die Zeichen fest, mit denen die Zeichen in der Docker-Datei maskiert werden. Wenn nicht angegeben, lautet das Standard-Escapezeichen "` \ ``.
Escape-Zeichen werden sowohl zum Escape-Zeichen in einer Zeile als auch zum Escape-Zeilenumbruch verwendet.
Dadurch kann der Dockerfile-Befehl mehrere Zeilen umfassen.
Beachten Sie, dass das Escapezeichen nicht mit dem Befehl RUN
ausgeführt wird, außer am Ende der Zeile, unabhängig davon, ob die Parser-Direktive Escape
in der Docker-Datei enthalten ist.
Das Setzen des Escapezeichens auf "` "ist unter Windows besonders nützlich.
Hier ist \
das Verzeichnispfadtrennzeichen.
"` "Stimmt mit Windows PowerShell überein.
Betrachten Sie das folgende Beispiel, das unter Windows nicht trivial fehlschlägt.
Das zweite \
am Ende der zweiten Zeile wird eher als Zeilenumbruch als als Ziel der Flucht aus dem ersten \
interpretiert.
In ähnlicher Weise wird das \
am Ende der dritten Zeile als Fortsetzung der Zeile behandelt, wenn es tatsächlich als Anweisung behandelt wurde.
Das Ergebnis dieser Docker-Datei ist, dass die zweite und dritte Zeile als eine einzige Anweisung betrachtet werden.
FROM microsoft/nanoserver
COPY testfile.txt c:\\
RUN dir c:\
Ausführungsergebnis:
PS C:\John> docker build -t cmd .
Sending build context to Docker daemon 3.072 kB
Step 1/2 : FROM microsoft/nanoserver
---> 22738ff49c6d
Step 2/2 : COPY testfile.txt c:\RUN dir c:
GetFileAttributesEx c:RUN: The system cannot find the file specified.
PS C:\John>
Eine der obigen Lösungen besteht darin, /
als Ziel sowohl für den COPY
-Befehl als auch für das dir
zu verwenden.
Diese Syntax ist jedoch verwirrend, da sie in Windows-Pfaden nicht natürlich ist.
Im schlimmsten Fall unterstützen nicht alle Windows-Befehle /
als Pfadtrennzeichen, wodurch es fehleranfällig wird.
Durch Hinzufügen der Parser-Direktive "Escape" wird die folgende Docker-Datei wie erwartet unter Verwendung der natürlichen Plattformsemantik im Windows-Dateipfad erfolgreich ausgeführt.
# escape=`
FROM microsoft/nanoserver
COPY testfile.txt c:\
RUN dir c:\
Ausführungsergebnis:
PS C:\John> docker build -t succeeds --no-cache=true .
Sending build context to Docker daemon 3.072 kB
Step 1/3 : FROM microsoft/nanoserver
---> 22738ff49c6d
Step 2/3 : COPY testfile.txt c:\
---> 96655de338de
Removing intermediate container 4db9acbb1682
Step 3/3 : RUN dir c:\
---> Running in a2c157f842f5
Volume in drive C has no label.
Volume Serial Number is 7E6D-E0F7
Directory of c:\
10/05/2016 05:04 PM 1,894 License.txt
10/05/2016 02:22 PM <DIR> Program Files
10/05/2016 02:14 PM <DIR> Program Files (x86)
10/28/2016 11:18 AM 62 testfile.txt
10/28/2016 11:20 AM <DIR> Users
10/28/2016 11:20 AM <DIR> Windows
2 File(s) 1,956 bytes
4 Dir(s) 21,259,096,064 bytes free
---> 01c7f3bef04f
Removing intermediate container a2c157f842f5
Successfully built 01c7f3bef04f
PS C:\John>
Umgebungsvariablen (in der ENV-Anweisung deklariert) können in bestimmten Anweisungen auch als Variablen verwendet werden, die von der Docker-Datei interpretiert werden. Escapes werden auch so verarbeitet, dass sie die variable Syntax unverändert in die Anweisung aufnehmen.
Umgebungsvariablen werden in der Docker-Datei entweder als "$ variable_name" oder "$ {variable_name}" dargestellt. Sie werden gleich behandelt, und die Syntax für geschweifte Klammern wird normalerweise verwendet, um das Problem nicht leerer Variablennamen wie "$ {foo} _bar" zu lösen.
Die Syntax $ {variable_name}
unterstützt auch einige der unten angegebenen Standard-Bash-Modifikatoren.
$ {variable: -word}
gibt an, dass das Ergebnis dieser Wert ist, wenn eine Variable gesetzt ist.
Wenn die Variable nicht gesetzt ist, ist word
das Ergebnis.$ {variable: + word}
gibt an, dass word
resultiert, wenn die Variable gesetzt ist, andernfalls ist das Ergebnis eine leere Zeichenfolge.In allen Fällen kann word
eine beliebige Zeichenfolge sein, die zusätzliche Umgebungsvariablen enthält.
Escape ist möglich, indem der Variablen \
vorangestellt wird.
Zum Beispiel wird \ $ foo
oder \ $ {foo}
in $ foo
und $ {foo}
konvertiert.
Beispiel (die analysierte Darstellung erscheint nach #
):
FROM busybox
ENV FOO=/bar
WORKDIR ${FOO} # WORKDIR /bar
ADD . $FOO # ADD . /bar
COPY \$FOO /quux # COPY $FOO /quux
Umgebungsvariablen werden durch die unten in der Docker-Datei gezeigten Anweisungen unterstützt.
Beim Ersetzen von Umgebungsvariablen wird für jede Variable im gesamten Befehl der gleiche Wert verwendet. Mit anderen Worten, in diesem Beispiel:
ENV abc=hello
ENV abc=bye def=$abc
ENV ghi=$abc
Das Ergebnis ist ein def
mit dem Wert hello
anstelle eines bye
.
Ghi
ist jedoch nicht Teil derselben Anweisung, die abc
auf bye
gesetzt hat, daher hat es den Wert bye
.
Die Docker-CLI sucht im Stammverzeichnis des Kontexts nach einer Datei mit dem Namen ".dockerignore", bevor der Kontext an den Docker-Daemon gesendet wird. Wenn diese Datei vorhanden ist, ändert die CLI den Kontext, um Dateien und Verzeichnisse auszuschließen, die dem darin enthaltenen Muster entsprechen. Dadurch wird vermieden, dass unnötigerweise große oder vertrauliche Dateien oder Verzeichnisse an den Dämon gesendet oder mit "HINZUFÜGEN" oder "KOPIEREN" zum Bild hinzugefügt werden.
Die CLI interpretiert die Datei ".dockerignore" als eine durch Zeilenumbrüche getrennte Liste von Mustern, die Unix-Shell-Dateihandschuhen ähneln.
Für Sortierungszwecke wird das Stammverzeichnis des Kontexts sowohl als Arbeitsverzeichnis als auch als Stammverzeichnis betrachtet.
Zum Beispiel sind die Muster / foo / bar
und foo / bar
beide bar` im Stammverzeichnis des Git-Repositorys im
foo-Unterverzeichnis oder der URL von
PATH``. Schließen Sie Dateien oder Verzeichnisse mit dem Namen `aus.
Keiner schließt den anderen aus.
Wenn eine Zeile in der Datei ".dockerignore" in der ersten Spalte mit "#" beginnt, wird diese Zeile als Kommentar betrachtet und ignoriert, bevor sie von der CLI interpretiert wird.
Hier ist ein Beispiel für das Schreiben einer .dockerignore
-Datei:
# comment
*/temp*
*/*/temp*
temp?
Diese Datei verursacht das folgende Build-Verhalten:
Regel | Bewegung |
---|---|
# comment |
Ignoriere es. |
*/temp* |
Ein direktes Unterverzeichnis der Wurzel mit dem Namentemp Schließen Sie Dateien und Verzeichnisse aus, die mit beginnen. Zum Beispiel eine einfache Datei/somedir/temporary.txt Ist ausgeschlossen und das Verzeichnis/somedir/temp Ist auch ausgeschlossen. |
*/*/temp* |
Aus einem Unterverzeichnis zwei Ebenen unterhalb der Wurzeltemp Schließen Sie Dateien und Verzeichnisse aus, die mit beginnen. Zum Beispiel/somedir/subdir/temporary.txt Ist ausgeschlossen. |
temp? |
Der Name ist temp+Schließt Dateien und Verzeichnisse im Stammverzeichnis aus, die aus einem einzelnen Zeichen bestehen. Zum Beispiel/tempa Wann/tempb Ist ausgeschlossen. |
Der Abgleich erfolgt nach der Regel "Dateipfad.Match" von Go.
Der Vorverarbeitungsschritt verwendet Go's filepath.Clean
, um führende und nachfolgende Leerzeichen zu entfernen, und entfernt .
und ..
Elemente.
Leerzeilen werden nach der Vorverarbeitung ignoriert.
Zusätzlich zur Go-Regel filepath.Match
unterstützt Docker auch die spezielle Platzhalterzeichenfolge **
, die mit einer beliebigen Anzahl von Verzeichnissen (einschließlich Nullen) übereinstimmt.
Zum Beispiel schließt ** / *. Go
alle Dateien aus, die mit .go
enden, in allen Verzeichnissen, die das Stammverzeichnis des Build-Kontexts enthalten.
Sie können Ausschlussausnahmen mit Zeilen erstellen, die mit !
(Ausrufezeichen) beginnen.
Das Folgende ist ein Beispiel für eine ".dockerignore" -Datei, die diesen Mechanismus verwendet.
*.md
!README.md
Alle Markdown-Dateien mit Ausnahme von "README.md" sind vom Kontext ausgeschlossen.
Die Platzierung der Ausnahmeregel !
Beeinflusst deren Verhalten.
Die letzte Zeile von ".dockerignore", die mit einer bestimmten Datei übereinstimmt, bestimmt, ob diese Datei eingeschlossen oder ausgeschlossen ist.
Betrachten Sie das folgende Beispiel.
*.md
!README*.md
README-secret.md
Markdown-Dateien sind nicht im Kontext enthalten, außer "README" -Dateien außer "README-secret.md".
Betrachten Sie nun dieses Beispiel.
*.md
README-secret.md
!README*.md
Enthält alle README-Dateien.
Die mittlere Zeile hat keine Auswirkung, da ! README * .md
mit README-secret.md
übereinstimmt und am Ende steht.
Sie können auch die Datei ".dockerignore" verwenden, um die Dateien "Dockerfile" und ".dockerignore" auszuschließen. Diese Dateien werden weiterhin an den Dämon gesendet, da sie zum Ausführen des Jobs erforderlich sind. Die Anweisungen "HINZUFÜGEN" und "KOPIEREN" kopieren sie jedoch nicht in das Bild.
Schließlich ist es eine gute Idee, die Dateien anzugeben, die Sie in den Kontext aufnehmen möchten, nicht die Dateien, die Sie ausschließen möchten. Um dies zu erreichen, geben Sie als erstes Muster "*" an, gefolgt von einem oder mehreren "!" - Ausnahmemustern.
** Achtung **
Aus historischen Gründen wird das Muster
.
ignoriert.
FROM
FROM [--platform=<platform>] <image> [AS <name>]
Oder
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
Oder
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
Der Befehl FROM
initialisiert eine neue Erstellungsphase und legt das Basis-Image für nachfolgende Befehle fest.
Daher muss eine gültige Docker-Datei mit der Anweisung FROM
beginnen.
Das Bild kann ein beliebiges gültiges Bild sein.
Es ist besonders einfach, das Bild aus einem öffentlichen Repository abzurufen.
ARG
ist die einzige Anweisung, die FROM
in der Docker-Datei vorangestellt werden kann.
Siehe Grundlegendes zur Interaktion zwischen ARG
und FROM
(Grundlegendes zur Interaktion zwischen # arg- und -from-). FROM
kann mehrmals in einer einzelnen Docker-Datei angezeigt werden, um mehrere Images zu erstellen, oder eine Build-Phase als Abhängigkeit von einer anderen verwenden.
Notieren Sie sich einfach die letzte von commit
ausgegebene Bild-ID vor der neuen Anweisung FROM
.
Jeder FROM-Befehl löscht alle Zustände, die durch den vorherigen Befehl erzeugt wurden. FROM
und COPY --from = <Name>
verwendet werden, um auf das zu diesem Zeitpunkt erstellte Bild zu verweisen.Sie können das optionale Flag "--platform" verwenden, um die Plattform des Bildes anzugeben, wenn "FROM" auf ein Bild mit mehreren Plattformen verweist.
Zum Beispiel linux / amd64
, linux / arm64
oder windows / amd64
.
Standardmäßig wird die Zielplattform der Build-Anforderung verwendet.
Sie können globale Build-Argumente für den Wert dieses Flags verwenden.
Sie können beispielsweise das automatische Plattformargument verwenden, um eine Stufe auf eine native Build-Plattform zu zwingen und sie zum Cross-Kompilieren auf eine Zielplattform innerhalb der Stufe zu verwenden.
( --platform=$BUILDPLATFORM
)
ARG
und FROM
Der Befehl FROM
unterstützt Variablen, die durch den Befehl ARG
deklariert wurden, der vor dem ersten FROM
auftritt.
ARG CODE_VERSION=latest
FROM base:${CODE_VERSION}
CMD /code/run-app
FROM extras:${CODE_VERSION}
CMD /code/run-extras
Das vor dem "FROM" deklarierte "ARG" befindet sich außerhalb der Erstellungsphase und kann nicht in Anweisungen nach dem "FROM" verwendet werden. Um den Standardwert von "ARG" zu verwenden, der vor dem ersten "FROM" deklariert wurde, verwenden Sie die Anweisung "ARG" ohne Wert in der Erstellungsphase.
ARG VERSION=latest
FROM busybox:$VERSION
ARG VERSION
RUN echo $VERSION > image_version
RUN
RUN
hat zwei Formen:
RUN <Befehl>
(Shell-Format. Befehle werden auf der Shell ausgeführt.
Die Standard-Shell für Linux ist / bin / sh -c
.
Die Standard-Shell für Windows ist "cmd / S / C"RUN ["ausführbare Datei", "param1", "param2"]
( exec
Format)Der Befehl RUN
führt den Befehl auf einer neuen Ebene im aktuellen Bild aus und schreibt das Ergebnis fest.
Das Bild mit dem festgeschriebenen Ergebnis wird im nächsten Schritt in der Docker-Datei verwendet.
Das Hierarchisieren der Anweisung "RUN" und das Generieren von Commits entspricht dem Kernkonzept von Docker für billige Commits und der Möglichkeit, Container an jedem Punkt im Bildverlauf zu erstellen, z. B. bei der Quellcodeverwaltung.
Sie können das Format exec
verwenden, um ein Ändern der Shell-Zeichenfolge zu vermeiden oder um den Befehl RUN
mit einem Basis-Image auszuführen, das nicht die angegebene ausführbare Shell-Datei enthält.
Die Standard-Shell im Shell-Format kann mit dem Befehl SHELL
geändert werden.
In Shell-Form können Sie \
(Backslash) verwenden, um eine einzelne RUN
-Anweisung in der nächsten Zeile fortzusetzen.
Betrachten Sie beispielsweise die folgenden zwei Zeilen:
RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'
Zusammen entsprechen sie der folgenden Zeile:
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
Um eine andere Shell als / bin / sh
zu verwenden, verwenden Sie das Format exec
, das die gewünschte Shell übergibt. Zum Beispiel:
RUN ["/bin/bash", "-c", "echo hello"]
** Achtung **
Das Format
exec
wird als JSON-Array analysiert. Das heißt, Sie müssen doppelte Anführungszeichen (`` ") vor und nach dem Wort verwenden, keine einfachen Anführungszeichen (
'
).
Im Gegensatz zum Shell-Format ruft das exec
-Format die Befehlsshell nicht auf.
Dies bedeutet, dass keine normale Shell-Verarbeitung stattfindet.
Zum Beispiel ersetzt RUN ["echo", "$ HOME"]
`$ HOMEnicht durch Variablen. Wenn das Schälen erforderlich ist, verwenden Sie das Shell-Format oder führen Sie die Shell direkt aus. Beispiel:
RUN ["sh", "-c", "echo $ HOME"] . Wenn Sie die Shell direkt im
exec``-Format ausführen, wie im Shell-Format, ist es die Shell, nicht der Docker, die die Umgebungsvariablen erweitert.
** Achtung **
Im JSON-Format müssen Backslashes maskiert werden. Dies ist besonders relevant für Windows, wo der Backslash das Pfadtrennzeichen ist. Die folgende Zeile wird als Shell-Format behandelt, da sie nicht gültig ist und auf unerwartete Weise fehlschlägt:
RUN ["c:\windows\system32\tasklist.exe"]
Die korrekte Syntax für dieses Beispiel lautet:
RUN ["c:\\windows\\system32\\tasklist.exe"]
Der Cache von "RUN" -Anweisungen wird beim nächsten Build nicht automatisch deaktiviert.
Der Cache mit Anweisungen wie "RUN apt-get dist-upgrade -y" wird im nächsten Build wiederverwendet.
Der Cache für die Anweisung RUN
kann mit dem Flag --no-cache
deaktiviert werden (z. B. Docker Build --no-cache
).
Weitere Informationen finden Sie im Dockerfile Best Practices Guide (https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/).
Der Cache der Anweisung RUN
kann durch die Anweisungen ADD
und COPY
überschrieben werden.
RUN
) dirperm1
finden Sie auf der aufs-Manpage (https://github.com/sfjro/aufs3-linux/tree/aufs3.18/Documentation/filesystems/aufs).
Wenn Ihr System dirperm1
nicht unterstützt, bietet Issue 783 (https://github.com/docker/docker/issues/783) eine Problemumgehung.CMD
Die CMD
Anweisung hat drei Formen:
CMD ["ausführbare Datei", "param1", "param2"]
( exec
Format. Dies ist das empfohlene Format)CMD ["param1", "param2"]
(Wird als Standardparameter für ENTRYPOINT
verwendet) CMD-Befehl param1 param2
(Shell-Format)In einer Docker-Datei kann es nur eine CMD-Anweisung geben. Wenn Sie mehrere "CMDs" auflisten, ist nur das letzte "CMD" gültig.
Der Hauptzweck von "CMD" besteht darin, ein Standardverhalten für das Ausführen von Containern bereitzustellen. Diese Standardverhalten können "ausführbar" sein oder "ausführbar" weglassen. Wenn Sie die ausführbare Datei weglassen, müssen Sie auch die Anweisung ENTRYPOINT angeben.
Wenn Sie "CMD" verwenden, um die Standardargumente für die Anweisung "ENTRYPOINT" bereitzustellen, müssen Sie sowohl die Anweisungen "CMD" als auch "ENTRYPOINT" im JSON-Array-Format angeben. ..
** Achtung **
Das Format
exec
wird als JSON-Array analysiert. Das heißt, Sie müssen vor und nach dem Wort doppelte Anführungszeichen (`` ") verwenden, keine einfachen Anführungszeichen (
'
).
Im Gegensatz zum Shell-Format ruft das exec
-Format die Befehlsshell nicht auf.
Dies bedeutet, dass keine normale Shell-Verarbeitung stattfindet.
Zum Beispiel führt CMD ["echo", "$ HOME"]
keine Variablensubstitution durch $ HOME
durch.
Wenn das Schälen erforderlich ist, verwenden Sie das Shell-Format oder führen Sie die Shell direkt aus.
Beispiel: CMD ["sh", "-c", "echo $ HOME"]
Wenn Sie die Shell direkt im exec
-Format ausführen, wie im Shell-Format, ist es die Shell, nicht der Docker, die die Umgebungsvariablen erweitert.
Bei Verwendung im Shell- oder exec
-Format legt der Befehl CMD
den Befehl fest, der ausgeführt werden soll, wenn das Image ausgeführt wird.
Bei Verwendung der Shell-Form von CMD
wird <Befehl>
mit / bin / sh -c
ausgeführt:
FROM ubuntu
CMD echo "This is a test." | wc -
Wenn Sie "
FROM ubuntu
CMD ["/usr/bin/wc","--help"]
Wenn Sie möchten, dass der Container jedes Mal dieselbe "ausführbare Datei" ausführt, sollten Sie die Verwendung von "ENTRYPOINT" in Kombination mit "CMD" in Betracht ziehen.
Siehe ENTRYPOINT
.
Wenn der Benutzer ein Argument für die Docker-Ausführung angibt (https://qiita.com/JhonnyBravo/items/eee5a91682f1d7c72f6e), wird der durch "CMD" angegebene Standardwert überschrieben.
** Achtung **
Verwechseln Sie
RUN
nicht mitCMD
.RUN
führt den Befehl tatsächlich aus und schreibt das Ergebnis fest.CMD
führt zur Erstellungszeit nichts aus, sondern gibt den Befehl an, den das Image ausführen soll.
LABEL
LABEL <key>=<value> <key>=<value> <key>=<value> ...
Die Anweisung LABEL
fügt dem Bild Metadaten hinzu.
LABEL
ist ein Schlüssel / Wert-Paar.
Um Leerzeichen in den Wert von LABEL
aufzunehmen, verwenden Sie Anführungszeichen und Backslashes wie beim Parsen von Befehlszeilen.
Anwendungsbeispiel:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
Bilder können mehrere Beschriftungen haben. Sie können mehrere Beschriftungen in einer Zeile angeben. Vor Docker 1.10 wurde dadurch das endgültige Bild verkleinert, was nicht mehr der Fall ist. Sie können auch mehrere Beschriftungen mit einer einzigen Anweisung auf zwei Arten angeben:
LABEL multi.label1="value1" multi.label2="value2" other="value3"
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
Beschriftungen, die im Basisbild oder im übergeordneten Bild enthalten sind (das Bild in der Zeile "FROM"), werden vom untergeordneten Bild geerbt. Wenn die Bezeichnung bereits vorhanden ist, die Werte jedoch unterschiedlich sind, überschreibt der zuletzt angewendete Wert den zuvor festgelegten Wert.
Verwenden Sie den Befehl Docker Image Inspect
, um die Beschriftung des Bildes anzuzeigen.
Mit der Option --format
können nur Beschriftungen angezeigt werden.
docker image inspect --format='' myimage
{
"com.example.vendor": "ACME Incorporated",
"com.example.label-with-value": "foo",
"version": "1.0",
"description": "This text illustrates that label-values can span multiple lines.",
"multi.label1": "value1",
"multi.label2": "value2",
"other": "value3"
}
MAINTAINER <name>
Die Anweisung MAINTAINER
legt das Feld Author
des generierten Bildes fest.
Die Anweisung "LABEL" bietet Ihnen viel mehr Flexibilität als die Anweisung "MAINTAINER" zum Festlegen der erforderlichen Metadaten.
Verwenden Sie stattdessen "LABEL".
Sie können es einfach anzeigen, indem Sie beispielsweise "Docker Inspect" verwenden.
So legen Sie die Beschriftung für das Feld "MAINTAINER" fest:
LABEL maintainer="[email protected]"
Dies wird von "Docker Inspect" zusammen mit anderen Etiketten angezeigt.
EXPOSE
EXPOSE <port> [<port>/<protocol>...]
Die Anweisung EXPOSE
benachrichtigt Docker, dass es den Netzwerkport überwacht, der bei der Ausführung des Containers angegeben wurde.
Sie können angeben, ob der Port TCP oder UDP überwacht.
Wenn kein Protokoll angegeben ist, ist der Standardwert TCP.
Die Anweisung EXPOSE
macht den Port nicht wirklich verfügbar.
Es fungiert als eine Art Dokument zwischen der Person, die das Bild erstellt, und der Person, die den Container ausführt, und soll den Port freigeben.
Verwenden Sie das Flag -p
in Docker-Lauf, um einen oder mehrere Ports zu erstellen, um die Ports beim Ausführen des Containers tatsächlich verfügbar zu machen. Veröffentlichen und verknüpfen Sie oder verwenden Sie das -P
-Flag, um alle exponierten Ports freizulegen und sie an höhere Ports zu binden.
Standardmäßig setzt EXPOSE
TCP voraus,
Sie können auch UDP angeben.
EXPOSE 80/udp
Schreiben Sie die folgenden zwei Zeilen, um sowohl in TCP als auch in UDP zu veröffentlichen:
EXPOSE 80/tcp
EXPOSE 80/udp
In diesem Fall macht die Verwendung von -P
in Docker-Lauf den Port einmal für TCP und einmal für UDP verfügbar.
Beachten Sie, dass -P
einen temporären übergeordneten Host-Port auf dem Host verwendet, sodass die Ports für TCP und UDP nicht identisch sind.
Sie können sie zur Laufzeit mit dem Flag "-p" überschreiben, unabhängig von der Einstellung "EXPOSE".
Beispiel:
docker run -p 80:80/tcp -p 80:80/udp ...
Siehe Verwenden des Flags -P
zum Konfigurieren der Portumleitung auf dem Hostsystem.
Der Befehl docker network
unterstützt das Erstellen eines Netzwerks für die Kommunikation zwischen Containern, ohne dass ein bestimmter Port verfügbar gemacht oder veröffentlicht werden muss.
Dies liegt daran, dass die mit dem Netzwerk verbundenen Container über einen beliebigen Port miteinander kommunizieren können.
Weitere Informationen finden Sie unter "Übersicht über die Docker-Netzwerkfunktionen" (https://docs.docker.com/engine/userguide/networking/).
ENV
ENV <key>=<value> ...
Der Befehl ENV
setzt die Umgebungsvariable <key>
auf den Wert <value>
.
Dieser Wert befindet sich in der Umgebung aller nachfolgenden Anweisungen in der Erstellungsphase und kann häufig inline ersetzt werden.
Der Wert wird für andere Umgebungsvariablen interpretiert und entfernt, wenn die Anführungszeichen nicht maskiert werden.
Wie beim Parsen von Befehlszeilen können Sie Anführungszeichen und umgekehrte Schrägstriche verwenden, um Leerzeichen in den Wert aufzunehmen.
Beispiel:
ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy
Mit der Anweisung ENV
können Sie mehrere <key> = <value> ...
Variablen gleichzeitig setzen.
Im folgenden Beispiel liefert das endgültige Bild das gleiche Endergebnis.
ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \
MY_CAT=fluffy
Umgebungsvariablen, die mit "ENV" festgelegt wurden, bleiben erhalten, wenn der Container aus dem resultierenden Bild ausgeführt wird.
Sie können "Docker Inspect" verwenden, um den Wert anzuzeigen, und "Docker Run --env
Das Fortbestehen von Umgebungsvariablen kann zu unerwarteten Nebenwirkungen führen. Wenn Sie beispielsweise "ENV DEBIAN_FRONTEND = noninteractive" setzen, ändert sich das Verhalten von "apt-get" und die Benutzer des Bildes können verwirrt werden.
Wenn die Umgebungsvariablen nur während der Erstellung und nicht im endgültigen Image benötigt werden, sollten Sie stattdessen den Wert für einen einzelnen Befehl festlegen.
RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ...
Oder verwenden Sie "ARG", das im endgültigen Bild nicht erhalten bleibt.
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y ...
** Alternative Notation **
Die Anweisung> ENV
kann die alternative Syntax ENV <key> <Wert>
verwenden und `` weglassen.
ENV MY_VAR my-value
ENV ONE TWO= THREE=world
ADD
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
Mit dieser Syntax können nicht mehrere Umgebungsvariablen in einer einzigen ENV-Anweisung festgelegt werden, was verwirrend sein kann. > Setzen Sie eine einzelne Umgebungsvariable
ONE
mit dem Wert"TWO = THREE = world"
, zum Beispiel: > Alternative Syntax wird aus Gründen der Abwärtskompatibilität unterstützt, ist jedoch aus den oben genannten Gründen veraltet und wird möglicherweise in einer zukünftigen Version entfernt.ADD
hat zwei Formen: Pfade, die Leerzeichen enthalten, erfordern die letztere Form. > ** Achtung **Die Funktion "--chown" wird nur in der Docker-Datei unterstützt, die zum Erstellen des Linux-Containers verwendet wird, nicht im Windows-Container. Da das Konzept des Benutzer- und Gruppeneigentums nicht zwischen Linux und Windows übersetzt wird, verwenden Sie
/ etc / passwd
und/ etc / group
, um Benutzer- und Gruppennamen in IDs zu konvertieren. Bei Verwendung ist diese Funktion nur dann funktionsfähig, wenn es sich um einen Linux-Betriebssystem-basierten Container handelt.
Die Anweisung ADD
kopiert die URL einer neuen Datei, eines neuen Verzeichnisses oder einer neuen Remote-Datei aus <src>
und fügt sie dem Dateisystem des Bildes mit dem Pfad <dest>
hinzu.
Sie können mehrere <src>
Ressourcen angeben. Wenn es sich jedoch um Dateien oder Verzeichnisse handelt, wird der Pfad im Build-Kontext als relativ zur Quelle interpretiert.
Jedes <src>
kann Platzhalter enthalten und der Abgleich erfolgt mit der Regel filepath.Match
von Go.
So fügen Sie beispielsweise alle Dateien hinzu, die mit hom
beginnen:
ADD hom* /mydir/
Im folgenden Beispiel wird ?
Durch ein einzelnes Zeichen ersetzt, z. B. home.txt
.
ADD hom?.txt /mydir/
<dest>
ist ein absoluter Pfad oder ein relativer Pfad aus Sicht von WORKDIR
, und die Quelle wird in den Zielcontainer kopiert.
Im folgenden Beispiel wird ein relativer Pfad verwendet, um test.txt
zu <WORKDIR> / relativeDir /
hinzuzufügen:
ADD test.txt relativeDir/
In diesem Beispiel wird ein absoluter Pfad verwendet, um test.txt
zu / abstractDir /
hinzuzufügen.
ADD test.txt /absoluteDir/
Wenn Sie Dateien oder Verzeichnisse hinzufügen, die Sonderzeichen enthalten (z. B. [
oder ]
), müssen Sie diese Pfade gemäß den Go-Sprachregeln maskieren, damit sie nicht als übereinstimmende Muster behandelt werden. Es gibt.
Verwenden Sie beispielsweise Folgendes, um eine Datei mit dem Namen "arr [0] .txt" hinzuzufügen:
ADD arr[[]0].txt /mydir/
Bei allen neuen Dateien, es sei denn, das optionale Flag "--chown" gibt einen bestimmten Benutzernamen, Gruppennamen oder eine bestimmte UID / GID-Kombination an, um den spezifischen Besitz des hinzugefügten Inhalts zu beanspruchen Das Verzeichnis wird mit einer UID und einer GID von 0 erstellt.
In Form des Flags --chown
können Sie eine beliebige Kombination aus Benutzernamen- und Gruppennamenzeichenfolgen oder direkte ganzzahlige UID und GID verwenden.
Wenn Sie einen Benutzernamen ohne Gruppennamen oder eine UID ohne GID angeben, wird dieselbe numerische UID wie die GID verwendet.
Wenn ein Benutzer- oder Gruppenname angegeben ist, verwenden Sie die Dateien / etc / passwd
und / etc / group
des Root-Dateisystems des Containers, um vom Namen zur ganzzahligen UID oder GID zu wechseln. Jede Konvertierung wird durchgeführt.
Das folgende Beispiel zeigt eine gültige Definition des Flags "--chown".
ADD --chown=55:mygroup files* /somedir/
ADD --chown=bin files* /somedir/
ADD --chown=1 files* /somedir/
ADD --chown=10:11 files* /somedir/
Wenn das Container-Root-Dateisystem keine / etc / passwd
- oder / etc / group
-Datei enthält und der Benutzername oder Gruppenname mit dem --chown
-Flag verwendet wird Die Operation ADD
führt dazu, dass der Build fehlschlägt.
Die Verwendung numerischer IDs erfordert keine Suche und ist unabhängig vom Inhalt des Container-Root-Dateisystems.
Wenn <src>
die URL einer entfernten Datei ist, verfügt das Ziel über 600 Berechtigungen.
Wenn die Remote-Datei, die Sie erhalten, einen HTTP-Header für die letzte Änderung enthält, verwenden Sie den Zeitstempel in diesem Header, um die Zeit für die Zieldatei festzulegen.
Wie bei jeder anderen Datei, die während "HINZUFÜGEN" verarbeitet wird, wird mtime jedoch nicht in die Feststellung einbezogen, ob sich eine Datei geändert hat, und muss den Cache aktualisieren.
** Achtung **
Wenn Sie eine Docker-Datei zum Erstellen an
STDIN
(Docker-Build- <Somefile
) übergeben, kann die Docker-Datei nur URL-basierteADD
-Anweisungen enthalten, da kein Build-Kontext vorhanden ist. Ich werde. Sie können das komprimierte Archiv auch überSTDIN
übergeben: (docker build- <archive.tar.gz
). Die Docker-Datei im Stammverzeichnis des Archivs und der Rest des Archivs werden als Build-Kontext verwendet.
Wenn die URL-Datei durch Authentifizierung geschützt ist, unterstützt die Anweisung ADD
die Authentifizierung nicht. Verwenden Sie daher RUN wget
, RUN curl
oder aus dem Container heraus. Sie müssen ein anderes Tool verwenden.
** Achtung **
Die erste erkannte Anweisung "ADD" macht den Cache aller nachfolgenden Anweisungen aus der Docker-Datei ungültig, wenn der Inhalt von "
" geändert wird. Dies beinhaltet das Deaktivieren des Caches der Anweisung RUN
. Weitere Informationen finden Sie im Dockerfile Best Practices Guide-Leveraging Build Cache (https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache).
ADD
folgt den folgenden Regeln:
<src>
muss sich im Kontext des Builds befinden.
`` ADD ../something / etwas kann nicht getan werden.<src>
die URL ist und <dest>
nicht mit einem abschließenden Schrägstrich endet, wird die Datei von der URL heruntergeladen und nach <dest>
kopiert.<src>
eine URL ist und <dest>
mit einem Schrägstrich am Ende endet, wird der Dateiname aus der URL abgeleitet und die Datei lautet <dest> / <Dateiname>
Wird heruntergeladen auf.
Beispiel: ADD http: // example.com / foobar /
erstellt die Datei / foobar
.
In diesem Fall muss die URL einen wichtigen Pfad haben, damit sie den richtigen Dateinamen finden kann ( http: // example.com
funktioniert nicht).<src>
ein Verzeichnis ist, wird der gesamte Inhalt des Verzeichnisses mit den Metadaten des Dateisystems kopiert.** Achtung **
Das Verzeichnis selbst wird nicht kopiert, nur sein Inhalt wird kopiert.
<src>
ein lokales Tar-Archiv in einem anerkannten Komprimierungsformat ist ( gzip
, bzip2
oder xz
), wird es als Verzeichnis dekomprimiert.
Ressourcen von Remote-URLs werden nicht entpackt.
Wenn das Verzeichnis kopiert oder entpackt wird, verhält es sich genauso wie tar -x
und das Ergebnis ist die folgende Summe.** Achtung **
Ob eine Datei als erkanntes Komprimierungsformat identifiziert wird, hängt ausschließlich vom Inhalt der Datei ab, nicht vom Namen der Datei. Wenn beispielsweise eine leere Datei mit ".tar.gz" endet, wird sie nicht als komprimierte Datei erkannt, es wird keine Dekomprimierungsfehlermeldung generiert und die Datei wird einfach an das Ziel kopiert.
<src>
ein anderer Dateityp ist, wird er separat mit den Metadaten kopiert.
In diesem Fall wird <dest>
, wenn am Ende ein Schrägstrich /
steht, als Verzeichnis betrachtet, und der Inhalt von <src>
lautet <dest> / base (<src>). )
Geschrieben an.<src>
Ressourcen entweder direkt oder mithilfe von Platzhaltern angegeben werden, muss <dest>
ein Verzeichnis sein und mit einem Schrägstrich /
enden. es gibt.<dest>
nicht mit einem abschließenden Schrägstrich endet, wird es als reguläre Datei betrachtet und der Inhalt von <src>
wird in <dest>
geschrieben.<dest>
nicht existiert, wird es mit allen fehlenden Verzeichnissen im Pfad erstellt.COPY
COPY
hat zwei Formen:
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
Das letztere Formular ist für Pfade erforderlich, die Leerzeichen enthalten.
** Achtung **
Die Funktion "--chown" wird nur in der Docker-Datei unterstützt, die zum Erstellen des Linux-Containers verwendet wird, nicht im Windows-Container. Da das Konzept des Benutzer- und Gruppenbesitzes nicht zwischen Linux und Windows übersetzt wird, verwenden Sie
/ etc / passwd
und/ etc / group
, um Benutzer- und Gruppennamen in IDs zu konvertieren. Benutzen. Diese Funktion ist nur auf ausführbare Dateien beschränkt, wenn es sich um einen Linux-basierten Container handelt.
Die Anweisung COPY
kopiert eine neue Datei oder ein neues Verzeichnis aus <src>
und fügt sie dem Dateisystem des Containers mit dem Pfad <dest>
hinzu.
Sie können mehrere <src>
Ressourcen angeben, aber die Datei- und Verzeichnispfade werden im Build-Kontext als relativ zur Quelle interpretiert.
Jedes <src>
kann Platzhalter enthalten und der Abgleich erfolgt mit der Regel filepath.Match
von Go.
So fügen Sie beispielsweise alle Dateien hinzu, die mit hom
beginnen:
COPY hom* /mydir/
Im folgenden Beispiel wird ?
Durch ein einzelnes Zeichen ersetzt, z. B. home.txt
.
COPY hom?.txt /mydir/
<dest>
ist ein absoluter Pfad oder ein Pfad relativ zu WORKDIR
, und die Quelle wird in den Zielcontainer kopiert.
Im folgenden Beispiel wird ein relativer Pfad verwendet, um test.txt
zu <WORKDIR> / relativeDir /
hinzuzufügen.
COPY test.txt relativeDir/
In diesem Beispiel wird ein absoluter Pfad verwendet, um test.txt
zu / abstractDir /
hinzuzufügen.
COPY test.txt /absoluteDir/
Wenn Sie Dateien oder Verzeichnisse kopieren, die Sonderzeichen enthalten (z. B. [
oder ]
), maskieren Sie diese Pfade gemäß den Go-Sprachregeln, damit sie nicht als übereinstimmende Muster behandelt werden. wird gebraucht.
Verwenden Sie zum Kopieren einer Datei mit dem Namen "arr [0] .txt" Folgendes:
COPY arr[[]0].txt /mydir/
Bei allen neuen Dateien, es sei denn, das optionale Flag "--chown" gibt einen bestimmten Benutzernamen, Gruppennamen oder eine bestimmte UID / GID-Kombination an, um einen bestimmten Besitz des kopierten Inhalts zu beanspruchen. Das Verzeichnis wird mit einer UID und einer GID von 0 erstellt.
In Form des Flags --chown
können Sie eine beliebige Kombination aus Benutzernamen- und Gruppennamenzeichenfolgen oder direkte ganzzahlige UID und GID verwenden.
Wenn Sie einen Benutzernamen ohne Gruppennamen oder eine UID ohne GID angeben, wird dieselbe numerische UID wie die GID verwendet.
Wenn ein Benutzer- oder Gruppenname angegeben ist, verwenden Sie die Dateien / etc / passwd
und / etc / group
des Root-Dateisystems des Containers, um vom Namen zur ganzzahligen UID oder GID zu wechseln. Jede Konvertierung wird durchgeführt.
Das folgende Beispiel zeigt eine gültige Definition des Flags "--chown".
COPY --chown=55:mygroup files* /somedir/
COPY --chown=bin files* /somedir/
COPY --chown=1 files* /somedir/
COPY --chown=10:11 files* /somedir/
Das Root-Dateisystem des Containers enthält keine / etc / passwd
oder / etc / group
Datei und der Benutzername oder Gruppenname wird im --chown
Flag verwendet In diesem Fall schlägt der Build mit der Operation "COPY" fehl.
Die Verwendung numerischer IDs erfordert keine Suche und ist unabhängig vom Inhalt des Container-Root-Dateisystems.
** Achtung **
Wenn Sie mit
STDIN
(Docker build- <somefile
) erstellen, können SieCOPY
nicht verwenden, da es keinen Build-Kontext gibt.
Optional ist COPY
ein Flag, mit dem der Quellspeicherort auf die vorherige Erstellungsphase gesetzt werden kann (erstellt mit FROM .. AS <Name>
) `` --from = Akzeptiere
.
Wird anstelle des vom Benutzer übermittelten Build-Kontexts verwendet.
Wenn die Erstellungsphase mit dem angegebenen Namen nicht gefunden wird, wird stattdessen ein Image mit demselben Namen verwendet.
COPY
folgt den folgenden Regeln:
<src>
muss sich im Kontext des Builds befinden.
Sie können "COPY ../something / Something" nicht ausführen, da der erste Schritt in "Dockerbuild" darin besteht, das Kontextverzeichnis (und die Unterverzeichnisse) an den Docker-Daemon zu senden.<src>
ein Verzeichnis ist, wird der gesamte Inhalt des Verzeichnisses mit den Metadaten des Dateisystems kopiert.** Achtung **
Das Verzeichnis selbst wird nicht kopiert, nur sein Inhalt wird kopiert.
<src>
ein anderer Dateityp als ein Verzeichnis ist, wird er separat mit den Metadaten kopiert.
In diesem Fall wird <dest>
, wenn am Ende ein Schrägstrich /
steht, als Verzeichnis betrachtet, und der Inhalt von <src>
lautet <dest> / base (<src>). )
Geschrieben an.<src>
Ressourcen entweder direkt oder mithilfe von Platzhaltern angegeben werden, muss <dest>
ein Verzeichnis sein und mit einem Schrägstrich /
enden. es gibt.<dest>
nicht mit einem abschließenden Schrägstrich endet, wird es als reguläre Datei betrachtet und der Inhalt von <src>
wird in <dest>
geschrieben.<dest>
nicht existiert, wird es mit allen fehlenden Verzeichnissen im Pfad erstellt.** Achtung **
Die erste erkannte Anweisung "COPY" macht den Cache aller nachfolgenden Anweisungen aus der Docker-Datei ungültig, wenn der Inhalt von "
" geändert wird. Dies beinhaltet das Deaktivieren des Caches der Anweisung RUN
. Weitere Informationen finden Sie im Dockerfile Best Practices Guide-Leveraging Build Cache (https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache).
ENTRYPOINT
ENTRYPOINT
hat zwei Formen:
Das empfohlene Format ist das exec
Format:
ENTRYPOINT ["executable", "param1", "param2"]
Shell-Format:
ENTRYPOINT command param1 param2
Sie können "ENTRYPOINT" verwenden, um den Container zu konfigurieren, in dem "ausführbare Datei" ausgeführt wird.
Das folgende Beispiel startet beispielsweise nginx mit Standardinhalten und überwacht Port 80.
$ docker run -i -t --rm -p 80:80 nginx
Befehlszeilenargumente für "Docker run docker run <image> -d
übergibt das Argument -d
an den Einstiegspunkt.
Sie können die Anweisung ENTRYPOINT
mit dem Flag Docker run --entrypoint
überschreiben.
Die Shell-Form verwendet nicht länger "CMD" oder die Ausführung von Befehlszeilenargumenten, aber der Nachteil ist, dass "ENTRYPOINT" als Unterbefehl von "/ bin / sh -c" gestartet wird, der kein Signal weiterleitet. es gibt.
Dies bedeutet, dass "ausführbare Datei" keine PID 1 für den Container empfängt und kein Unix-Signal empfängt.
Daher empfängt ausführbar
kein SIGTERM
von Docker Stop <Container>
.
Nur die letzte Anweisung ENTRYPOINT
in der Docker-Datei ist gültig.
ENTRYPOINT
im Exec-FormatKann mit beiden Formen von "CMD" geändert werden, nachdem ein ziemlich stabiler Standardbefehl und Argumente mit "ENTRYPOINT" in Form von "exec" festgelegt wurden Sie können zusätzliche Standardverhalten festlegen, die wahrscheinlicher sind.
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
Wenn Sie den Container ausführen, können Sie sehen, dass top
der einzige Prozess ist.
$ docker run -it --rm --name test top -H
top - 08:25:00 up 7:27, 0 users, load average: 0.00, 0.01, 0.05
Threads: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.1 us, 0.1 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 2056668 total, 1616832 used, 439836 free, 99352 buffers
KiB Swap: 1441840 total, 0 used, 1441840 free. 1324440 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 19744 2336 2080 R 0.0 0.1 0:00.04 top
Sie können "Docker Exec" verwenden, um die Ergebnisse weiter zu untersuchen.
$ docker exec -it test ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 2.6 0.1 19752 2352 ? Ss+ 08:24 0:00 top -b -H
root 7 0.0 0.1 15572 2164 ? R+ 08:25 0:00 ps aux
Sie können auch den Docker-Stopp-Test verwenden, um zu fordern, dass "top" ordnungsgemäß heruntergefahren wird.
Die folgende Docker-Datei zeigt, wie Apache im Vordergrund (dh als PID 1) mit "ENTRYPOINT" ausgeführt wird.
FROM debian:stable
RUN apt-get update && apt-get install -y --force-yes apache2
EXPOSE 80 443
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
Wenn Sie ein einzelnes ausführbares
Starter-Skript erstellen müssen, verwenden Sie die Befehle exec
und gosu
, um sicherzustellen, dass die letzte ausführbare Datei
das Unix-Signal empfängt. Sie können in der Lage sein.
#!/usr/bin/env bash
set -e
if [ "$1" = 'postgres' ]; then
chown -R postgres "$PGDATA"
if [ -z "$(ls -A "$PGDATA")" ]; then
gosu postgres initdb
fi
exec gosu postgres "$@"
fi
exec "$@"
Wenn Sie beim Herunterfahren eine zusätzliche Bereinigung durchführen (oder mit anderen Containern kommunizieren) müssen oder mehrere ausführbare Dateien koordinieren möchten, signalisiert das Skript ENTRYPOINT ein Unix. Sie müssen sicherstellen, dass Sie senden und empfangen, um weitere Arbeiten ausführen zu können.
#!/bin/sh
# Note: I've written this using sh so it works in the busybox container too
# USE the trap if you need to also do manual cleanup after the service is stopped,
# or need to start multiple services in the one container
trap "echo TRAPed signal" HUP INT QUIT TERM
# start service in background here
/usr/sbin/apachectl start
echo "[hit enter key to exit] or run 'docker stop <container>'"
read
# stop service and clean up here
echo "stopping apache"
/usr/sbin/apachectl stop
echo "exited $0"
Wenn Sie dieses Image mit dockerrun -it --rm -p 80:80 --name test apache
ausführen, können Sie den Containerprozess mit docker exec
oder docker top
sehen. Bitten Sie nachfolgende Skripte, Apache zu stoppen.
$ docker exec -it test ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.0 4448 692 ? Ss+ 00:42 0:00 /bin/sh /run.sh 123 cmd cmd2
root 19 0.0 0.2 71304 4440 ? Ss 00:42 0:00 /usr/sbin/apache2 -k start
www-data 20 0.2 0.2 360468 6004 ? Sl 00:42 0:00 /usr/sbin/apache2 -k start
www-data 21 0.2 0.2 360468 6000 ? Sl 00:42 0:00 /usr/sbin/apache2 -k start
root 81 0.0 0.1 15572 2140 ? R+ 00:44 0:00 ps aux
$ docker top test
PID USER COMMAND
10035 root {run.sh} /bin/sh /run.sh 123 cmd cmd2
10054 root /usr/sbin/apache2 -k start
10055 33 /usr/sbin/apache2 -k start
10056 33 /usr/sbin/apache2 -k start
$ /usr/bin/time docker stop test
test
real 0m 0.27s
user 0m 0.03s
sys 0m 0.03s
Hinweis
Sie können --entrypoint
verwenden, um die Einstellung ENTRYPOINT
zu überschreiben, aber dies kann nur binary
auf exec
( sh -c
setzen) Nicht benutzt).
Hinweis
Das exec
Format wird als JSON Array analysiert.
Das heißt, Sie müssen doppelte Anführungszeichen (`` "
) vor und nach dem Wort anstelle von einfachen Anführungszeichen (
'
) verwenden.
Im Gegensatz zum Shell-Format ruft das exec
-Format die Befehlsshell nicht auf.
Dies bedeutet, dass keine normale Shell-Verarbeitung stattfindet.
Zum Beispiel ersetzt ENTRYPOINT ["echo", "$ HOME"]
die Variable in $ HOME
nicht.
Wenn eine Shell-Verarbeitung erforderlich ist, verwenden Sie das Shell-Format oder führen Sie die Shell direkt aus.
Beispiel: ENTRYPOINT ["sh", "-c", "echo $ HOME"]
Wenn Sie die Shell direkt im Format exec
ausführen, wie im Shell-Format, erweitert die Shell und nicht der Docker die Umgebungsvariablen.
Wenn Sie eine einfache Zeichenfolge für "ENTRYPOINT" angeben, wird diese mit "/ bin / sh -c" ausgeführt.
Dieses Formular verwendet die Shell-Verarbeitung, um Shell-Umgebungsvariablen zu ersetzen, und ignoriert die Befehlszeilenargumente CMD
oder Docker run.
Denken Sie daran, mit exec
für Docker Stop
zu beginnen, um Sie korrekt über eine lang laufende ENTRYPOINT ausführbare Datei
zu benachrichtigen.
FROM ubuntu
ENTRYPOINT exec top -b
Das Ausführen dieses Bildes zeigt einen einzelnen PID 1-Prozess.
$ docker run -it --rm --name test top
Mem: 1704520K used, 352148K free, 0K shrd, 0K buff, 140368121167873K cached
CPU: 5% usr 0% sys 0% nic 94% idle 0% io 0% irq 0% sirq
Load average: 0.08 0.03 0.05 2/98 6
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
1 0 root R 3164 0% 0% top -b
Reinigen mit Docker Stop
:
$ /usr/bin/time docker stop test
test
real 0m 0.20s
user 0m 0.02s
sys 0m 0.04s
Wenn Sie vergessen, exec
am Anfang von ENTRYPOINT
hinzuzufügen:
FROM ubuntu
ENTRYPOINT top -b
CMD --ignored-param1
Sie können dies dann tun (benennen Sie den nächsten Schritt).
$ docker run -it --name test top --ignored-param2
Mem: 1704184K used, 352484K free, 0K shrd, 0K buff, 140621524238337K cached
CPU: 9% usr 2% sys 0% nic 88% idle 0% io 0% irq 0% sirq
Load average: 0.01 0.02 0.05 2/101 7
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
1 0 root S 3168 0% 0% /bin/sh -c top -b cmd cmd2
7 1 root R 3164 0% 0% top -b
Die Ausgabe von top
zeigt, dass der angegebene ENTRYPOINT
nicht PID 1 ist.
Wenn Sie dann den Docker-Stopp-Test ausführen, wird der Container nicht erfolgreich beendet.
Nach dem Timeout erzwingt der Befehl stop
das Senden eines SIGKILL
.
$ docker exec -it test ps aux
PID USER COMMAND
1 root /bin/sh -c top -b cmd cmd2
7 root top -b
8 root ps aux
$ /usr/bin/time docker stop test
test
real 0m 10.19s
user 0m 0.04s
sys 0m 0.03s
CMD
und ENTRYPOINT
Sowohl die Anweisungen "CMD" als auch "ENTRYPOINT" definieren die Befehle, die ausgeführt werden, wenn der Container ausgeführt wird.
Hier sind die Regeln, die die Zusammenarbeit zwischen CMD
und ENTRYPOINT
beschreiben.
CMD
sollte verwendet werden, um Standardargumente für den Befehl ENTRYPOINT
zu definieren oder um Ad-hoc-Befehle in einem Container auszuführen.Die folgende Tabelle zeigt die Befehle, die für verschiedene ENTRYPOINT
/ CMD
-Kombinationen ausgeführt wurden.
No ENTRYPOINT | ENTRYPOINT exec_entry p1_entry | ENTRYPOINT [“exec_entry”, “p1_entry”] |
---|---|---|
No CMD | error, not allowed | /bin/sh -c exec_entry p1_entry |
CMD [“exec_cmd”, “p1_cmd”] | exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry |
CMD [“p1_cmd”, “p2_cmd”] | p1_cmd p2_cmd | /bin/sh -c exec_entry p1_entry |
CMD exec_cmd p1_cmd | /bin/sh -c exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry |
** Achtung **
Wenn "CMD" aus dem Basisbild definiert ist, wird durch Setzen von "ENTRYPOINT" "CMD" auf einen leeren Wert zurückgesetzt. Sie müssen im aktuellen Bild "CMD" definieren, um den Wert in diesem Szenario festzulegen.
VOLUME
VOLUME ["/data"]
Die Anweisung VOLUME
erstellt einen Einhängepunkt mit dem angegebenen Namen und markiert ihn als Speicher eines Volumes, das extern vom nativen Host oder einem anderen Container bereitgestellt wird.
Der Wert ist das JSON-Array VOLUME ["/ var / log /"]
oder VOLUME / var / log
oder
Es kann sich um eine einfache Zeichenfolge mit mehreren Argumenten handeln, z. B. "VOLUME / var / log / var / db".
Weitere Informationen, Anwendungsfälle und Anweisungen zum Mounten über den Docker-Client finden Sie unter Freigeben von Direktoren über Volumes (https://docs.docker.com/storage/volumes/).
Der Befehl Docker-Ausführung initialisiert das neu erstellte Volume mit den Daten, die an der angegebenen Position im Basis-Image vorhanden sind. Betrachten Sie beispielsweise das folgende Dockerfile-Snippet:
FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
Diese Docker-Datei ist eine Docker-Ausführung, die einen neuen Einhängepunkt für / myvol
erstellt und eine Gruß
-Datei auf das neu erstellte Volume legt. Es wird das zu kopierende Bild sein.
Beachten Sie Folgendes zu Dockerfile-Volumes:
C:
) anstatt in einfache Anführungszeichen (
'
) eingeschlossen werden. VOLUME
unterstützt nicht die Angabe des Parameters host-dir
.
Sie müssen den Einhängepunkt angeben, wenn Sie den Container erstellen oder ausführen.USER
USER <user>[:<group>]
Oder
USER <UID>[:<GID>]
Die Anweisung USER
ist der Benutzername (oder die UID) und optional die Benutzergruppe (oder UID), die beim Ausführen des Bildes und in den Anweisungen nach RUN
, CMD
, ENTRYPOINT
in der Docker-Datei verwendet wird. Oder GID).
Wenn Sie eine Gruppe von Benutzern angeben, beachten Sie, dass Benutzer nur die angegebene Gruppenmitgliedschaft haben. Andere konfigurierte Gruppenmitgliedschaften werden ignoriert.
** Warnung **
Wenn der Benutzer keine primäre Gruppe hat, wird das Image (oder der nächste Schritt) in der Stammgruppe ausgeführt.
Unter Windows müssen Sie zuerst einen Benutzer erstellen, wenn es sich nicht um ein integriertes Konto handelt. Dies kann mit dem Befehl
netuser
erfolgen, der als Teil der Docker-Datei aufgerufen wird.
FROM microsoft/windowsservercore
# Create Windows user in the container
RUN net user /add patrick
# Set it for subsequent commands
USER patrick
WORKDIR
WORKDIR /path/to/workdir
Die Anweisung WORKDIR
ist das Arbeitsverzeichnis aller nachfolgenden Anweisungen RUN
, CMD
, ENTRYPOINT
, COPY
und `ADD
in der Docker-Datei. Einstellen.
Wenn "WORKDIR" nicht vorhanden ist, wird es erstellt, auch wenn es nicht in nachfolgenden Dockerfile-Anweisungen verwendet wird.
Die Anweisung WORKDIR
kann in einer Docker-Datei mehrfach verwendet werden.
Wenn ein relativer Pfad angegeben wird, ist er relativ zum Pfad der vorherigen Anweisung "WORKDIR". Zum Beispiel:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
Die Ausgabe des letzten "pwd" -Befehls in dieser Docker-Datei lautet "/ a / b / c".
Der Befehl WORKDIR
kann Umgebungsvariablen auflösen, die zuvor mit ENV
festgelegt wurden.
Sie können nur Umgebungsvariablen verwenden, die explizit in der Docker-Datei festgelegt sind.
Zum Beispiel:
ENV DIRPATH=/path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
Die Ausgabe des letzten Befehls pwd
in dieser Docker-Datei lautet / path / $ DIRNAME
.
ARG
ARG <name>[=<default value>]
Die Anweisung ARG
verwendet das Flag `` --build-arg
[Warning] One or more build-args [foo] were not consumed.
Die Docker-Datei kann eine oder mehrere "ARG" -Anweisungen enthalten. Das Folgende ist beispielsweise eine gültige Docker-Datei.
FROM busybox
ARG user1
ARG buildno
# ...
** Warnung **
Wir empfehlen, keine Build-Time-Variablen zu verwenden, um vertrauliche Informationen wie Github-Schlüssel, Benutzeranmeldeinformationen usw. zu übergeben. Variablenwerte für die Erstellungszeit sind für alle Benutzer des Bildes mit dem Befehl "Docker-Verlauf" sichtbar.
Eine sichere Möglichkeit zur Verwendung vertraulicher Informationen beim Erstellen eines Images finden Sie unter Erstellen eines Images mit BuildKit (https://docs.docker.com/develop/develop-images/build_enhancements/#new-) Siehe Docker-Build-Secret-Information).
Die Anweisung ARG
kann optional einen Standardwert enthalten.
FROM busybox
ARG user1=someuser
ARG buildno=1
# ...
Wenn der Befehl ARG
einen Standardwert hat und zum Zeitpunkt der Erstellung kein Wert übergeben wird, verwendet der Builder den Standardwert.
Scope
Die Definition der Variablen "ARG" wird anhand der in der Docker-Datei definierten Zeile wirksam, nicht anhand der Verwendung von Argumenten in der Befehlszeile oder anderswo. Betrachten Sie beispielsweise die folgende Docker-Datei.
FROM busybox
USER ${user:-some_user}
ARG user
USER $user
# ...
Der Benutzer ruft den folgenden Befehl auf, um diese Datei zu erstellen.
$ docker build --build-arg user=what_user .
Die zweite Zeile, "USER", wird zu "some_user" ausgewertet, da die Benutzervariable in der nächsten dritten Zeile definiert ist.
Die vierte Zeile, "USER", wird zu "what_user" ausgewertet, wenn der Benutzer definiert ist und der Wert "what_user" an die Befehlszeile übergeben wird.
Vor der Definition mit der Anweisung ARG
wird die Zeichenfolge durch Verwendung einer Variablen geleert.
Der Befehl ARG
verlässt am Ende der Build-Phase, in der er definiert ist, den Gültigkeitsbereich.
Um "arg" in mehreren Stufen zu verwenden, muss jede Stufe eine "ARG" -Anweisung enthalten.
FROM busybox
ARG SETTINGS
RUN ./run/setup $SETTINGS
FROM busybox
ARG SETTINGS
RUN ./run/other $SETTINGS
ARG
Sie können die Anweisungen ARG
oder ENV
verwenden, um die in der Anweisung RUN
verfügbaren Variablen anzugeben.
Umgebungsvariablen, die mit der Anweisung ENV
definiert wurden, überschreiben immer die Anweisung ARG
mit demselben Namen.
Betrachten Sie diese Docker-Datei, die die Anweisungen ENV
und ARG
enthält.
FROM ubuntu
ARG CONT_IMG_VER
ENV CONT_IMG_VER=v1.0.0
RUN echo $CONT_IMG_VER
Angenommen, dieses Bild wurde mit dem folgenden Befehl erstellt:
$ docker build --build-arg CONT_IMG_VER=v2.0.1 .
In diesem Fall verwendet der Befehl RUN
v1.0.0 anstelle der Einstellung ARG
, die von user: v2.0.1
übergeben wurde.
Dieses Verhalten ähnelt einem Shell-Skript, bei dem eine Variable mit lokalem Gültigkeitsbereich eine Variable überschreibt, die als Argument übergeben wurde, oder eine Variable, die aus definitorischer Sicht von der Umgebung geerbt wurde.
Anhand des obigen Beispiels, jedoch mit einer anderen "ENV" -Spezifikation, können Sie eine bequemere Interaktion zwischen den "ARG" - und den "ENV" -Anweisungen erstellen.
FROM ubuntu
ARG CONT_IMG_VER
ENV CONT_IMG_VER=${CONT_IMG_VER:-v1.0.0}
RUN echo $CONT_IMG_VER
Im Gegensatz zur Anweisung "ARG" wird der Wert "ENV" immer im erstellten Image beibehalten.
Betrachten Sie einen Docker-Build ohne das Flag --build-arg
:
$ docker build .
In diesem Dockerfile-Beispiel bleibt "CONT_IMG_VER" im Image erhalten, es ist jedoch Version 1.0.0, da dies der Standardwert ist, der in Zeile 3 durch die Anweisung "ENV" festgelegt wurde. ..
Mit der Variablenerweiterungstechnik in diesem Beispiel können Sie Argumente über die Befehlszeile und übergeben
Sie können die Anweisung ENV
verwenden, um sie bis zum endgültigen Bild beizubehalten.
Die variable Erweiterung wird nur mit einer begrenzten Kombination von Dockerfile-Anweisungen unterstützt.
ARG
Docker verfügt über eine Reihe vordefinierter "ARG" -Variablen, die Sie ohne die entsprechenden "ARG" -Anweisungen in Ihrer Docker-Datei verwenden können.
Um sie zu verwenden, übergeben Sie sie einfach in der Befehlszeile mit Flags.
--build-arg <varname>=<value>
Standardmäßig werden diese vordefinierten Variablen von der Ausgabe des Docker-Verlaufs ausgeschlossen. Das Ausschließen der vordefinierten Variablen verringert das Risiko, dass versehentlich vertrauliche Anmeldeinformationen in der Variablen "HTTP_PROXY" verloren gehen.
Erwägen Sie, die folgende Docker-Datei mit beispielsweise "--build-arg HTTP_PROXY = http: // user: pass @ proxy.lon.example.com" zu erstellen.
FROM ubuntu
RUN echo "Hello World"
In diesem Fall ist der Wert der Variablen "HTTP_PROXY" in der Docker-Historie nicht verfügbar und wird nicht zwischengespeichert. Wenn Sie den Speicherort ändern und der Proxyserver in "http: // user: pass @ proxy.sfo.example.com" geändert wird, wird bei nachfolgenden Builds kein Cache-Fehler auftreten.
Wenn Sie dieses Verhalten überschreiben müssen, können Sie es überschreiben, indem Sie die Anweisung "ARG" wie folgt zu Ihrer Docker-Datei hinzufügen:
FROM ubuntu
ARG HTTP_PROXY
RUN echo "Hello World"
Wenn Sie diese Docker-Datei erstellen, wird "HTTP_PROXY" in "Docker-Verlauf" gespeichert. Wenn Sie den Wert ändern, wird der Build-Cache ungültig.
Diese Funktion ist nur verfügbar, wenn Sie das BuildKit-Backend verwenden.
Docker definiert eine Reihe von ARG-Variablen mit Informationen über die Plattform des Knotens, der den Build ausführt (Build-Plattform), und die Plattform des resultierenden Images (Zielplattform). Die Zielplattform kann mit dem Flag "--platform" in [Docker Build] angegeben werden (https://qiita.com/JhonnyBravo/items/87976fe9de47ed58b8b1).
Die folgenden "ARG" -Variablen werden automatisch gesetzt.
Diese Argumente sind im globalen Bereich definiert und können nicht automatisch in der Erstellungsphase oder im Befehl RUN
verwendet werden.
Um eines dieser Argumente in der Erstellungsphase verfügbar zu machen, definieren Sie es ohne Wert neu.
Zum Beispiel:
FROM alpine
ARG TARGETPLATFORM
RUN echo "I'm building for $TARGETPLATFORM"
Auswirkungen auf den Build-Cache
Die Variable "ARG" bleibt nicht in dem Bild erhalten, das wie die Variable "ENV" erstellt wurde. Die Variable "ARG" wirkt sich jedoch auf ähnliche Weise auf den Build-Cache aus. Wenn das Dockerfile eine "ARG" -Variable mit einem anderen Wert als in früheren Builds definiert, erhalten Sie bei der ersten Verwendung anstelle dieser Definition einen "Cache-Fehler". Insbesondere verwenden alle "RUN" -Anweisungen, die der "ARG" -Anweisung folgen, implizit die "ARG" -Variable (als Umgebungsvariable) und können Cache-Fehler verursachen. Alle vordefinierten "ARG" -Variablen werden aus dem Cache ausgeschlossen, es sei denn, die Docker-Datei enthält eine übereinstimmende "ARG" -Anweisung.
Betrachten Sie beispielsweise die folgenden zwei Docker-Dateien.
FROM ubuntu
ARG CONT_IMG_VER
RUN echo $CONT_IMG_VER
FROM ubuntu
ARG CONT_IMG_VER
RUN echo hello
Wenn Sie in der Befehlszeile --build-arg CONT_IMG_VER = <Wert>
angeben, verursacht die zweite Zeile in beiden Fällen keinen Cache-Fehler.
Die dritte Zeile verursacht einen Cache-Fehler.
ARG CONT_IMG_VER
identifiziert die RUN
-Zeile als dasselbe wie das Ausführen von CONT_IMG_VER = <Wert> Echo Hallo
, so dass es zwischengespeichert wird, wenn <Wert>
geändert wird. Ein Fehler wird auftreten.
Betrachten Sie ein anderes Beispiel in derselben Befehlszeile.
FROM ubuntu
ARG CONT_IMG_VER
ENV CONT_IMG_VER=$CONT_IMG_VER
RUN echo $CONT_IMG_VER
In diesem Beispiel tritt der Cache-Fehler in Zeile 3 auf.
Ein Cache-Fehler tritt auf, weil sich der Wert der Variablen "ENV" auf die Variable "ARG" bezieht und diese Variable in der Befehlszeile geändert wird.
In diesem Beispiel füllt der Befehl ENV
das Bild.
Wenn der Befehl "ENV" den Befehl "ARG" mit demselben Namen wie in dieser Docker-Datei überschreibt:
FROM ubuntu
ARG CONT_IMG_VER
ENV CONT_IMG_VER=hello
RUN echo $CONT_IMG_VER
In der dritten Zeile ist der Wert von "CONT_IMG_VER" eine Konstante (Hallo), sodass kein Cache-Fehler auftritt.
Infolgedessen ändern sich die in RUN
(Zeile 4) verwendeten Umgebungsvariablen und -werte nicht zwischen Builds.
ONBUILD
ONBUILD <INSTRUCTION>
Der Befehl ONBUILD
fügt dem Image einen Triggerbefehl hinzu, der später ausgeführt wird, wenn das Image als Basis für einen anderen Build verwendet wird.
Der Trigger wird im Kontext eines Downstream-Builds ausgeführt, als ob er unmittelbar nach der Anweisung "FROM" in der Downstream-Docker-Datei eingefügt worden wäre.
Jede Build-Anweisung kann als Trigger registriert werden.
Dies ist nützlich, wenn Sie ein Bild erstellen, das als Basis für die Erstellung anderer Bilder verwendet wird. Zum Beispiel eine Anwendungserstellungsumgebung oder ein Dämon, der mit Ihrer eigenen Konfiguration angepasst werden kann.
Wenn es sich bei dem Image beispielsweise um einen wiederverwendbaren Python-Anwendungsgenerator handelt, müssen Sie möglicherweise den Quellcode der Anwendung einem bestimmten Verzeichnis hinzufügen und dann das Build-Skript aufrufen. Sie können jetzt nicht einfach "ADD" und "RUN" aufrufen, da der Quellcode der Anwendung noch nicht verfügbar ist und von Build zu Anwendung unterschiedlich ist. Sie können dem Anwendungsentwickler auch die Docker-Datei für die Kesselplatte zur Verfügung stellen und diese kopieren und in die Anwendung einfügen. Dies ist ineffizient, fehleranfällig und mit anwendungsspezifischem Code gemischt, was die Aktualisierung schwierig macht.
Die Lösung besteht darin, "ONBUILD" zu verwenden, um eine Voranweisung zu erstellen, die später in der nächsten Erstellungsphase ausgeführt werden soll.
Der Mechanismus ist wie folgt.
ONBUILD
auftritt, fügt der Builder den Metadaten des zu erstellenden Bildes einen Trigger hinzu.
Andernfalls hat die Anweisung keine Auswirkung auf den aktuellen Build. docker inspect
überprüft werden. FROM
verwenden, um das Image als Grundlage für einen neuen Build zu verwenden.
Im Rahmen der Verarbeitung der FROM-Anweisungen sucht der nachgeschaltete Builder nach den ONBUILD-Triggern und führt sie in derselben Reihenfolge aus, in der sie registriert wurden.
Wenn einer der Trigger fehlschlägt, wird der Befehl FROM
abgebrochen und der Build schlägt fehl.
Wenn alle Trigger erfolgreich sind, ist der Befehl FROM
abgeschlossen und der Build wird normal fortgesetzt.Sie können beispielsweise Folgendes hinzufügen:
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
** Warnung **
ONBUILD ONBUILD
darfONBUILD
-Anweisungen nicht verketten.Der Befehl
ONBUILD
löst möglicherweise nicht den BefehlFROM
oderMAINTAINER
aus.
STOPSIGNAL
STOPSIGNAL signal
Der Befehl STOPSIGNAL
setzt das Systemanrufsignal, das zum Beenden an den Container gesendet wird.
Dieses Signal sollte eine gültige vorzeichenlose Nummer sein, die mit einer Position in der syscall
-Tabelle des Kernels übereinstimmt (z. B. 9), oder ein Signalname in Form von SIGNAME
(zum Beispiel SIGKILL
). Ich kann.
HEALTHCHECK
Die "HEALTHCHECK" -Anweisung gibt es in zwei Formen:
HEALTHCHECK [OPTIONS] CMD-Befehl
(Führen Sie einen Befehl im Container aus, um den Status des Containers zu überprüfen.) HEALTHCHECK NONE
(deaktiviert die vom Basis-Image geerbten Integritätsprüfungen)Die Anweisung HEALTHCHECK
teilt Docker mit, wie der Container getestet werden soll, um sicherzustellen, dass er noch funktioniert.
Auf diese Weise können Sie Fälle erkennen, in denen der Webserver in einer Endlosschleife steckt und keine neuen Verbindungen verarbeiten kann, selbst wenn der Serverprozess noch ausgeführt wird.
Wenn für einen Container eine Integritätsprüfung angegeben ist, hat er zusätzlich zum normalen Status einen Integritätsstatus. Dieser Status ist anfänglich "Starten". Wenn Sie den Gesundheitscheck bestehen, ist der Gesundheitscheck "normal" (unabhängig vom vorherigen Status). Nach einer bestimmten Anzahl aufeinanderfolgender Fehler wird es "abnormal".
Die Optionen, die vor "CMD" angezeigt werden, sind:
--interval = DURATION
(Standard: 30s) --timeout = DURATION
(Standard: 30s) --start-period = DURATION
(Standard: 0s) --retries = N
(Standard: 3)Die Integritätsprüfung wird einige Sekunden nach dem ersten Start des Containers und einige Sekunden nach Abschluss jeder vorherigen Prüfung erneut ausgeführt.
Wenn eine Prüfung länger als die Zeitüberschreitungssekunden ausgeführt wird, wird die Prüfung als nicht erfolgreich angesehen.
Aufeinanderfolgende Fehler bei der Gesundheitsprüfung müssen wiederholt werden, damit der Behälter als abnormal eingestuft wird.
Die Startperiode gibt die Containerinitialisierungszeit an, die Zeit für den Bootstrap benötigt. Sondenfehler während dieses Zeitraums zählen nicht für die maximale Anzahl von Wiederholungsversuchen. Wenn die Integritätsprüfung jedoch während des Startzeitraums erfolgreich ist, wird der Container als gestartet betrachtet und alle aufeinander folgenden Fehler werden in der maximalen Anzahl von Wiederholungsversuchen gezählt.
In einer Docker-Datei kann es nur eine "HEALTHCHECK" -Anweisung geben. Wenn Sie mehrere Elemente auflisten, ist nur der letzte "HEALTHCHECK" gültig.
Der Befehl nach dem Schlüsselwort "CMD" ist entweder ein Shell-Befehl (z. B. "HEALTHCHECK CMD / bin / check-running") oder ein "exec" -Array (wie jeder andere Dockerfile-Befehl). (Weitere Informationen finden Sie unter "ENTRYPOINT".)
Der Endstatus des Befehls gibt den Integritätsstatus des Containers an. Die gültigen Werte sind:
So überprüfen Sie beispielsweise alle 5 Minuten, ob der Webserver die Hauptseite Ihrer Website innerhalb von 3 Sekunden bereitstellen kann:
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
Um das Debuggen eines fehlgeschlagenen Tests zu unterstützen, wird der Ausgabetext (UTF-8-codiert), den der Befehl in "stdout" oder "stderr" schreibt, im Integritätsstatus gespeichert und kann von "docker inspect" durchsucht werden. .. Diese Ausgabe sollte kurz sein (derzeit werden nur die ersten 4096 Bytes gespeichert).
Wenn sich der Integritätsstatus eines Containers ändert, wird mit dem neuen Status ein Ereignis "Health_status" generiert.
Die Funktion "HEALTHCHECK" wurde in Docker 1.12 hinzugefügt.
SHELL
SHELL ["executable", "parameters"]
Mit der Anweisung SHELL
können Sie die Standard-Shell überschreiben, die für Befehle im Shell-Stil verwendet wird.
Die Standard-Shell für Linux ist ["/ bin / sh", "-c"]
.
Die Standard-Shell für Windows ist "[" cmd "," / S "," / C "]".
Die Anweisung SHELL
muss im Dockerfile im JSON-Format vorliegen.
Die Anweisung SHELL
ist unter Windows mit zwei häufig verwendeten nativen Shells ( cmd
und Powershell
) und einer alternativen Shell verfügbar, die sh
enthält. Besonders nützlich.
Die Anweisung SHELL
kann mehrmals angezeigt werden.
Jede "SHELL" -Anweisung überschreibt alle vorherigen "SHELL" -Anweisungen und wirkt sich auf alle nachfolgenden Anweisungen aus.
Beispiel:
FROM microsoft/windowsservercore
# Executed as cmd /S /C echo default
RUN echo default
# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default
# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello
# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S", "/C"]
RUN echo hello
Die folgenden Anweisungen können durch die Anweisung SHELL
beeinflusst werden, wenn das Shell-Format in der Docker-Datei verwendet wird:
RUN
CMD
ENTRYPOINT
Das folgende Beispiel ist ein allgemeines Muster unter Windows, das mit der Anweisung SHELL
optimiert werden kann.
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
Der von Docker aufgerufene Befehl sieht folgendermaßen aus:
cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
Dies ist aus zwei Gründen ineffizient. Zunächst wird der unerwünschte Befehlsprozessor "cmd.exe" (auch als Shell bezeichnet) aufgerufen. Zweitens erfordert jeder RUN-Befehl im Shell-Stil vor dem Befehl einen zusätzlichen Powershell-Befehl.
Sie können einen von zwei Mechanismen verwenden, um dies effizienter zu gestalten.
Eine Möglichkeit besteht darin, das JSON-Format des Befehls RUN
zu verwenden, das folgendermaßen aussieht:
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
Das JSON-Format ist klar und verwendet nicht das unnötige "cmd.exe", aber doppelte Anführungszeichen und Escapezeichen erfordern detailliertere Informationen.
Ein anderer Mechanismus besteht darin, die Anweisung SHELL
und die Shell-Form zu verwenden.
Dies macht die Syntax für Windows-Benutzer natürlicher, insbesondere in Kombination mit Escape-Parser-Anweisungen.
# escape=`
FROM microsoft/nanoserver
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'
Ausführungsergebnis:
PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 4.096 kB
Step 1/5 : FROM microsoft/nanoserver
---> 22738ff49c6d
Step 2/5 : SHELL powershell -command
---> Running in 6fcdb6855ae2
---> 6331462d4300
Removing intermediate container 6fcdb6855ae2
Step 3/5 : RUN New-Item -ItemType Directory C:\Example
---> Running in d0eef8386e97
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 10/28/2016 11:26 AM Example
---> 3f2fbf1395d9
Removing intermediate container d0eef8386e97
Step 4/5 : ADD Execute-MyCmdlet.ps1 c:\example\
---> a955b2621c31
Removing intermediate container b825593d39fc
Step 5/5 : RUN c:\example\Execute-MyCmdlet 'hello world'
---> Running in be6d8e63fe75
hello world
---> 8e559e9bf424
Removing intermediate container be6d8e63fe75
Successfully built 8e559e9bf424
PS E:\docker\build\shell>
Die Anweisung SHELL
kann auch verwendet werden, um das Verhalten der Shell zu ändern.
Unter Windows können Sie beispielsweise "SHELL cmd / S / C / V: ON | OFF" verwenden, um die erweiterte Semantik verzögerter Umgebungsvariablen zu ändern.
Die Anweisung SHELL
kann auch unter Linux verwendet werden, wenn eine alternative Shell wie zsh, csh, tcsh erforderlich ist.
Die Funktion "SHELL" wurde in Docker 1.12 hinzugefügt.
Diese Funktion ist nur verfügbar, wenn Sie das BuildKit-Backend verwenden.
Docker-Build wird durch Verwendung einer externen Implementierung des Builders mit Syntaxanweisungen wie Cache-Mounts, Build-Geheimnissen, SSH-Übertragungen usw. aktiviert. Unterstützt experimentelle Funktionen. Informationen zu diesen Funktionen finden Sie in der BuildKit-Repository-Dokumentation (https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md).
Hier einige Beispiele für die Dockerfile-Syntax:
# Nginx
#
# VERSION 0.0.1
FROM ubuntu
LABEL Description="This image is used to start the foobar executable" Vendor="ACME Products" Version="1.0"
RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server
# Firefox over VNC
#
# VERSION 0.3
FROM ubuntu
# Install vnc, xvfb in order to create a 'fake' display and firefox
RUN apt-get update && apt-get install -y x11vnc xvfb firefox
RUN mkdir ~/.vnc
# Setup a password
RUN x11vnc -storepasswd 1234 ~/.vnc/passwd
# Autostart firefox (might not be the best way, but it does the trick)
RUN bash -c 'echo "firefox" >> /.bashrc'
EXPOSE 5900
CMD ["x11vnc", "-forever", "-usepw", "-create"]
# Multiple images example
#
# VERSION 0.1
FROM ubuntu
RUN echo foo > bar
# Will output something like ===> 907ad6c2736f
FROM ubuntu
RUN echo moo > oink
# Will output something like ===> 695d7793cbe4
# You'll now have two images, 907ad6c2736f with /bar, and 695d7793cbe4 with
# /oink.
Recommended Posts