Suche…


Einführung

Dockerfiles sind Dateien, mit denen Docker-Images programmatisch erstellt werden. Sie ermöglichen es Ihnen, schnell und reproduzierbar ein Docker-Image zu erstellen und sind daher für die Zusammenarbeit hilfreich. Docker-Dateien enthalten Anweisungen zum Erstellen eines Docker-Images. Jede Anweisung ist in einer Zeile geschrieben und in der Form <INSTRUCTION><argument(s)> . Docker-Dateien werden verwendet, um Docker-Images mit dem docker build Befehl zu docker build .

Bemerkungen

Dockerfiles haben die Form:

# This is a comment
INSTRUCTION arguments
  • Kommentare beginnen mit einem #
  • Anweisungen sind nur in Großbuchstaben
  • Die erste Anweisung einer Docker-Datei muss FROM , um das Basisabbild anzugeben

Beim Erstellen einer Docker-Datei sendet der Docker-Client einen "Build-Kontext" an den Docker-Daemon. Der Build-Kontext enthält alle Dateien und Ordner im selben Verzeichnis wie die Docker-Datei. COPY und ADD Vorgänge können nur Dateien aus diesem Kontext verwenden.


Einige Docker-Dateien beginnen mit:

# escape=`

Hiermit wird der Docker-Parser angewiesen, ` als Escape-Zeichen anstelle von \ . Dies ist vor allem für Windows Docker-Dateien nützlich.

HelloWorld Dockerfile

Eine minimale Docker-Datei sieht folgendermaßen aus:

FROM alpine
CMD ["echo", "Hello StackOverflow!"]

Dadurch wird Docker angewiesen, ein Abbild auf der Grundlage von Alpine ( FROM ), einer minimalen Verteilung für Container, zu erstellen und beim Ausführen des resultierenden Abbilds einen bestimmten Befehl ( CMD ) auszuführen.

Bauen Sie es auf und führen Sie es aus:

docker build -t hello .
docker run --rm hello

Dies wird ausgegeben:

Hello StackOverflow!

Dateien kopieren

Verwenden Sie zum Kopieren von Dateien aus dem Build-Kontext in einem Docker-Image die COPY Anweisung:

COPY localfile.txt containerfile.txt

Wenn der Dateiname Leerzeichen enthält, verwenden Sie die alternative Syntax:

COPY ["local file", "container file"]

Der Befehl COPY unterstützt Platzhalter. Es kann beispielsweise verwendet werden, um alle Bilder in das Verzeichnis images/ zu kopieren:

COPY *.jpg images/

Hinweis: In diesem Beispiel sind möglicherweise keine images/ vorhanden. In diesem Fall erstellt Docker es automatisch.

Einen Hafen freigeben

Um deklarierte Ports aus einer Dockerfile zu deklarieren, verwenden Sie die Anweisung EXPOSE :

EXPOSE 8080 8082

Die Einstellung der freigelegten Ports kann von der Docker-Befehlszeile aus überschrieben werden. Es ist jedoch empfehlenswert, sie explizit in der Docker-Datei festzulegen, da dies die Funktionsweise einer Anwendung erleichtert.

Dockerfiles beste Praktiken

Gemeinsame Operationen gruppieren

Docker erstellt Bilder als eine Sammlung von Ebenen. Jede Ebene kann nur Daten hinzufügen, selbst wenn diese Daten anzeigen, dass eine Datei gelöscht wurde. Jede Anweisung erstellt eine neue Ebene. Zum Beispiel:

RUN apt-get -qq update
RUN apt-get -qq install some-package

Hat ein paar Nachteile:

  • Es werden zwei Ebenen erstellt, wodurch ein größeres Bild erzeugt wird.
  • Die alleinige Verwendung von apt-get update in einer RUN Anweisung führt zu Zwischenspeicherungsproblemen und anschließend können apt-get install fehlschlagen . Angenommen, Sie ändern apt-get install durch Hinzufügen zusätzlicher Pakete. Dann interpretiert das Andockfenster die ursprünglichen und geänderten Anweisungen als identisch und verwendet den Cache von den vorherigen Schritten. Daher wird der Befehl apt-get update nicht ausgeführt, da seine zwischengespeicherte Version während des Builds verwendet wird.

Verwenden Sie stattdessen:

RUN apt-get -qq update && \
    apt-get -qq install some-package

da dies nur eine Schicht erzeugt.

Erwähnen Sie den Betreuer

Dies ist normalerweise die zweite Zeile der Dockerfile. Es sagt, wer verantwortlich ist und helfen kann.

LABEL maintainer John Doe <[email protected]>

Wenn Sie es überspringen, wird Ihr Bild nicht beschädigt. Aber es hilft auch nicht Ihren Benutzern.

Sei präzise

Halten Sie Ihre Dockerfile kurz. Wenn ein komplexes Setup erforderlich ist, sollten Sie ein dediziertes Skript verwenden oder Basisabbilder einrichten.

USER-Anweisung

USER daemon

Der USER - Befehl setzt die Benutzername oder UID zu verwenden , wenn das Bild ausgeführt wird und für jeden RUN , CMD und ENTRYPOINT Anweisungen , die es in dem folgen Dockerfile .

WORKDIR-Anweisung

WORKDIR /path/to/workdir

Die WORKDIR Anweisung legt das Arbeitsverzeichnis für alle Anweisungen RUN , CMD , ENTRYPOINT , COPY und ADD , die in der Docker-Datei folgen. Wenn das WORKDIR nicht existiert, wird es erstellt, auch wenn es nicht in einer nachfolgenden Dockerfile Anweisung verwendet wird.

Es kann mehrmals in einer Dockerfile . Wenn ein relativer Pfad angegeben wird, ist dieser relativ zum Pfad der vorherigen WORKDIR Anweisung. Zum Beispiel:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

Die Ausgabe des letzten pwd Befehls in dieser Dockerfile wäre /a/b/c .

Die WORKDIR Anweisung kann Umgebungsvariablen auflösen, die zuvor mit ENV . Sie können nur Umgebungsvariablen verwenden, die explizit in der Dockerfile . Zum Beispiel:

ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd

Die Ausgabe des letzten pwd Befehls in dieser Docker-Datei wäre /path/$DIRNAME

VOLUME-Anweisung

VOLUME ["/data"]

Mit der Anweisung VOLUME wird ein Mountpunkt mit dem angegebenen Namen erstellt und als für extern gemountete Volumes auf dem nativen Host oder anderen Containern markiert. Der Wert kann ein JSON-Array, VOLUME ["/var/log/"] oder eine einfache Zeichenfolge mit mehreren Argumenten sein, beispielsweise VOLUME /var/log oder VOLUME /var/log /var/db . Weitere Informationen / Beispiele und Installationsanweisungen über den Docker-Client finden Sie in der Dokumentation zum Freigeben von Verzeichnissen über Volumes.

Der docker run Befehl initialisiert den neu erstellten Datenträger mit allen Daten, die an der angegebenen Position im Basisabbild 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 führt zu einem Bild, das das Andockfenster veranlasst, einen neuen Mount-Punkt unter / myvol zu erstellen und die Begrüßungsdatei in das neu erstellte Volume zu kopieren.

Hinweis: Wenn Build-Schritte die Daten innerhalb des Volumes ändern, nachdem sie deklariert wurden, werden diese Änderungen verworfen.

Anmerkung: Die Liste wird als JSON-Array analysiert. Das bedeutet, dass Sie doppelte Anführungszeichen (“) für Wörter verwenden müssen, nicht einfache Anführungszeichen (').

COPY-Anweisung

COPY hat zwei Formen:

COPY <src>... <dest>
COPY ["<src>",... "<dest>"] (this form is required for paths containing whitespace)

Die COPY Anweisung kopiert neue Dateien oder Verzeichnisse aus <src> und fügt sie dem Dateisystem des Containers unter dem Pfad <dest> .

Es können mehrere <src> -Ressourcen angegeben werden, sie müssen jedoch relativ zu dem Quellverzeichnis sein, das erstellt wird (dem Kontext des Builds).

Jedes <src> kann Platzhalter enthalten, und der Abgleich wird mit den filepath.Match Regeln von Go filepath.Match . Zum Beispiel:

COPY hom* /mydir/        # adds all files starting with "hom"
COPY hom?.txt /mydir/    # ? is replaced with any single character, e.g., "home.txt"

Der <dest> ist ein absoluter Pfad oder ein Pfad relativ zu WORKDIR , in den die Quelle in den WORKDIR kopiert wird.

COPY test relativeDir/   # adds "test" to `WORKDIR`/relativeDir/
COPY test /absoluteDir/  # adds "test" to /absoluteDir/

Alle neuen Dateien und Verzeichnisse werden mit einer UID und einer GID von 0 erstellt.

Hinweis: Wenn Sie mit stdin ( docker build - < somefile ) docker build - < somefile , gibt es keinen Build-Kontext, sodass COPY nicht verwendet werden kann.

COPY beachtet die folgenden Regeln:

  • Der Pfad <src> muss sich im Kontext des Builds befinden. Sie können nicht COPY ../something / etwas, weil der erste Schritt eines Docker Build ist das Kontext Verzeichnis (und Unterverzeichnisse) mit der Docker - Daemon zu senden.

  • Wenn <src> ein Verzeichnis ist, wird der gesamte Inhalt des Verzeichnisses einschließlich der Metadaten des Dateisystems kopiert. Hinweis: Das Verzeichnis selbst wird nicht kopiert, sondern nur der Inhalt.

  • Wenn <src> eine andere Art von Datei ist, wird sie zusammen mit ihren Metadaten einzeln kopiert. Wenn in diesem Fall <dest> mit einem nachgestellten Schrägstrich / endet, wird dies als Verzeichnis betrachtet und der Inhalt von <src> wird in <dest>/base(<src>) .

  • Wenn mehrere <src> -Ressourcen angegeben werden, entweder direkt oder aufgrund der Verwendung eines Platzhalters, muss <dest> ein Verzeichnis sein und mit einem Schrägstrich / enden.

  • Wenn <dest> nicht mit einem nachgestellten Schrägstrich endet, wird dies als reguläre Datei betrachtet und der Inhalt von <src> wird an <dest> .

  • Wenn <dest> nicht vorhanden ist, wird es zusammen mit allen fehlenden Verzeichnissen in seinem Pfad erstellt.

Die ENV- und ARG-Anweisung

ENV

ENV <key> <value>
ENV <key>=<value> ...

Die Anweisung ENV setzt die Umgebungsvariable <key> auf den Wert. Dieser Wert befindet sich in der Umgebung aller "nachkommenden" Dockerfile-Befehle und kann auch in vielen Inline-Versionen ersetzt werden.

Die ENV Anweisung hat zwei Formen. Die erste Form ENV <key> <value> setzt eine einzelne Variable auf einen Wert. Die gesamte Zeichenfolge nach dem ersten Leerzeichen wird als <value> behandelt, einschließlich Zeichen wie Leerzeichen und Anführungszeichen.

Die zweite Form ENV <key>=<value> ... ermöglicht das gleichzeitige Setzen mehrerer Variablen. Beachten Sie, dass das zweite Formular das Gleichheitszeichen (=) in der Syntax verwendet, das erste Formular jedoch nicht. Wie bei der Befehlszeilenanalyse können Anführungszeichen und umgekehrte Schrägstriche verwendet werden, um Leerzeichen in Werte einzuschließen.

Zum Beispiel:

ENV myName="John Doe" myDog=Rex\ The\ Dog \
    myCat=fluffy

und

ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat fluffy

führt im endgültigen Container zu den gleichen Nettoergebnissen, aber die erste Form wird bevorzugt, da sie eine einzelne Cache-Ebene erzeugt.

Die mit ENV festgelegten Umgebungsvariablen bleiben erhalten, wenn ein Container vom resultierenden Image aus ausgeführt wird. Sie können die Werte mithilfe der Docker- docker run --env <key>=<value> und mithilfe des docker run --env <key>=<value> .

ARG

Wenn Sie die Einstellung nicht beibehalten möchten, verwenden Sie stattdessen ARG . ARG setzt Umgebungen nur während des Builds. Zum Beispiel Einstellung

ENV DEBIAN_FRONTEND noninteractive

apt-get Benutzer können auf einem Debian-basierten Image verwirrt werden, wenn sie den Container in einem interaktiven Kontext über das docker exec -it the-container bash eingeben.

Verwenden Sie stattdessen:

ARG DEBIAN_FRONTEND noninteractive

Sie können alternativ auch einen Wert für einen einzelnen Befehl festlegen, indem Sie Folgendes verwenden:

RUN <key>=<value> <command>

EXPOSE Anweisung

EXPOSE <port> [<port>...]

Die Anweisung EXPOSE informiert Docker darüber, dass der Container zur Laufzeit die angegebenen Netzwerkports abhört. EXPOSE macht die Ports des Containers NICHT für den Host zugänglich. Dazu müssen Sie entweder das -p Flag zum Veröffentlichen eines -P oder das -P Flag zum Veröffentlichen aller freigelegten Ports verwenden. Diese Flags werden im docker run [OPTIONS] IMAGE [COMMAND][ARG...] , um den Port für den Host docker run [OPTIONS] IMAGE [COMMAND][ARG...] . Sie können eine Portnummer freigeben und extern unter einer anderen Nummer veröffentlichen.

docker run -p 2500:80 <image name>

Dieser Befehl erstellt einen Container mit dem Namen <image> und bindet den Port 80 des Containers an den Port 2500 der Hostmaschine.

Informationen zum Einrichten der Portumleitung auf dem Hostsystem finden Sie unter Verwenden des Kennzeichens -P . Die Docker-Netzwerkfunktion unterstützt das Erstellen von Netzwerken, ohne dass Ports innerhalb des Netzwerks verfügbar gemacht werden müssen (detaillierte Informationen finden Sie in der Übersicht dieser Funktion).

LABEL-Anweisung

LABEL <key>=<value> <key>=<value> <key>=<value> ...

Die LABEL Anweisung fügt einem Bild Metadaten hinzu. Ein LABEL ist ein Schlüssel-Wert-Paar. Verwenden Sie zum LABEL von Leerzeichen in einen LABEL Wert Anführungszeichen und LABEL Schrägstriche wie bei der Befehlszeilenanalyse. Einige Anwendungsbeispiele:

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."

Ein Bild kann mehr als ein Label haben. Um mehrere Labels anzugeben, empfiehlt Docker, die Labels möglichst in einer einzigen LABEL Anweisung zu kombinieren. Jede LABEL Anweisung erzeugt eine neue Ebene, die zu einem ineffizienten Bild führen kann, wenn Sie viele Beschriftungen verwenden. Dieses Beispiel ergibt eine einzelne Bildebene.

LABEL multi.label1="value1" multi.label2="value2" other="value3"

Das oben Gesagte kann auch geschrieben werden als:

LABEL multi.label1="value1" \
      multi.label2="value2" \
      other="value3"

Labels sind additiv, einschließlich LABEL in FROM Bildern. Wenn Docker auf ein bereits vorhandenes Label / einen Schlüssel stößt, überschreibt der neue Wert alle vorherigen Labels mit identischen Schlüsseln.

Verwenden Sie den Andockbefehl, um die Beschriftungen eines Bildes anzuzeigen.

"Labels": {
    "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"
},

CMD-Anweisung

Die CMD Anweisung hat drei Formen:

CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)

Es kann nur eine CMD Anweisung in einer Dockerfile . Wenn Sie mehr als eine CMD CMD wird nur die letzte CMD wirksam.

Der Hauptzweck einer CMD besteht darin, Standardwerte für einen ausgeführten Container bereitzustellen. Diese Standardwerte können eine ausführbare Datei enthalten oder sie können die ausführbare Datei weglassen. In diesem Fall müssen Sie auch eine ENTRYPOINT Anweisung angeben.

Anmerkung: Wenn CMD verwendet wird, um Standardargumente für die Anweisung ENTRYPOINT , sollten sowohl die Anweisungen CMD als auch ENTRYPOINT mit dem JSON-Array-Format angegeben werden.

Hinweis: Das exec-Formular wird als JSON-Array analysiert. Das bedeutet, dass Sie doppelte Anführungszeichen (“) für Wörter verwenden müssen, nicht einfache Anführungszeichen (').

Hinweis: Im Gegensatz zum Shell-Formular ruft das Exec-Formular keine Befehls-Shell auf. Dies bedeutet, dass eine normale Shell-Verarbeitung nicht stattfindet. Beispielsweise führt CMD [ "echo", "$HOME" ] keine Variablensubstitution bei $HOME . Wenn Sie eine Shell-Verarbeitung wünschen, verwenden Sie entweder die Shell-Form oder führen Sie eine Shell direkt aus, zum Beispiel: CMD [ "sh", "-c", "echo $HOME" ] .

Bei Verwendung in Shell- oder Exec-Formaten legt der CMD Befehl fest, dass der Befehl ausgeführt wird, wenn das Image ausgeführt wird.

Wenn Sie die Shell-Form des CMD , wird der Befehl in /bin/sh -c :

FROM ubuntu
CMD echo "This is a test." | wc -

Wenn Sie Ihren Befehl ohne Shell ausführen möchten, müssen Sie den Befehl als JSON-Array ausdrücken und der ausführbaren Datei den vollständigen Pfad angeben. Diese Feldform ist das bevorzugte Format von CMD . Alle zusätzlichen Parameter müssen einzeln als Strings im Array ausgedrückt werden:

FROM ubuntu
CMD ["/usr/bin/wc","--help"]

Wenn Sie möchten, dass Ihr Container jedes Mal dieselbe ausführbare Datei ENTRYPOINT sollten Sie ENTRYPOINT in Kombination mit CMD in Betracht ENTRYPOINT . Siehe ENTRYPOINT .

Wenn der Benutzer Argumente für die Ausführung des Dockers angibt, überschreibt er den in CMD angegebenen Standard.

Hinweis: Verwechseln Sie RUN mit CMD . RUN tatsächlich einen Befehl zur Image-Erstellungszeit aus und überträgt das Ergebnis. CMD führt zum Erstellungszeitpunkt nichts aus, gibt jedoch den beabsichtigten Befehl für das Image an.

MAINTAINER-Anweisung

MAINTAINER <name>

Mit der Anweisung MAINTAINER können Sie das Autorenfeld der generierten Bilder festlegen.

DIE MAINTAINER-RICHTLINIE NICHT VERWENDEN

Gemäß der offiziellen Docker-Dokumentation ist die MAINTAINER Anweisung veraltet. Stattdessen sollte man die LABEL Anweisung verwenden, um den Autor der erzeugten Bilder zu definieren. Der LABEL - Befehl ist flexibler, ermöglicht Metadaten Einstellung und können leicht mit dem Befehl betrachtet werden docker inspect .

LABEL maintainer="[email protected]"

FROM Anweisung

FROM <image>

Oder

FROM <image>:<tag>

Oder

FROM <image>@<digest>

Die FROM Anweisung legt das Basisbild für nachfolgende Anweisungen fest. Daher muss eine gültige Docker-Datei FROM als erste Anweisung enthalten. Das Bild kann ein beliebiges gültiges Bild sein. Es ist besonders einfach, ein Bild aus den öffentlichen Repositorys zu ziehen.

FROM muss die erste Anweisung ohne Kommentar in der Dockerfile sein.

FROM kann in einer einzigen Docker-Datei mehrmals angezeigt werden, um mehrere Bilder zu erstellen. Notieren Sie sich vor jedem neuen FROM Befehl einfach die letzte vom Commit ausgegebene Bild-ID.

Die Tag- oder Digest-Werte sind optional. Wenn Sie eine der beiden Optionen weglassen, geht der Builder standardmäßig von einer neuen Version aus. Der Builder gibt einen Fehler zurück, wenn er nicht mit dem Tag-Wert übereinstimmen kann.

RUN-Anweisung

RUN hat 2 Formen:

RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
RUN ["executable", "param1", "param2"] (exec form)

Die RUN Anweisung führt alle Befehle in einer neuen Ebene über dem aktuellen Bild aus und schreibt die Ergebnisse fest. Das resultierende festgeschriebene Image wird für den nächsten Schritt in der Dockerfile .

Das Beschichten von RUN Anweisungen und das Generieren von Commits entspricht den Kernkonzepten von Docker, bei denen Commits billig sind und Container von jedem Punkt in der Historie eines Bildes erstellt werden können, ähnlich wie bei der Quellcodeverwaltung.

Die exec Form ermöglicht es , Shell String munging zu vermeiden und RUN Befehle ein Basisbild verwenden , die nicht die angegebene ausführbare Shell enthält.

Die Standard-Shell für das Shell-Formular kann mit dem Befehl SHELL geändert werden.

In der Shell-Form können Sie einen \ (Backslash) verwenden, um einen einzelnen RUN Befehl in der nächsten Zeile fortzusetzen. Betrachten Sie zum Beispiel diese beiden Zeilen:

RUN /bin/bash -c 'source $HOME/.bashrc ;\
echo $HOME'

Zusammen entsprechen sie dieser einzelnen Zeile:

RUN /bin/bash -c 'source $HOME/.bashrc ; echo $HOME'

Hinweis: Wenn Sie eine andere Shell als '/ bin / sh' verwenden möchten, verwenden Sie das Exec-Formular, das in der gewünschten Shell übergeben wird. Zum Beispiel RUN ["/bin/bash", "-c", "echo hello"]

Hinweis: Das exec-Formular wird als JSON-Array analysiert. Das bedeutet, dass Sie doppelte Anführungszeichen ( ) für Wörter verwenden müssen, nicht einfache Anführungszeichen ( ' ).

Hinweis: Im Gegensatz zum Shell-Formular ruft das Exec-Formular keine Befehls-Shell auf. Dies bedeutet, dass eine normale Shell-Verarbeitung nicht stattfindet. Zum Beispiel führt RUN [ "echo", "$HOME" ] keine Variablensubstitution bei $HOME . Wenn Sie eine Shell-Verarbeitung wünschen, verwenden Sie entweder die Shell-Form oder führen Sie eine Shell direkt aus, zum Beispiel: RUN [ "sh", "-c", "echo $HOME" ] .

Hinweis: Im JSON-Formular müssen umgekehrte Schrägstriche ausgeblendet werden. Dies ist insbesondere unter Windows relevant, wo der Backslash das Pfadtrennzeichen ist. Die folgende Zeile wird ansonsten als Shell-Form behandelt, da sie nicht gültig ist und unerwartet fehlschlägt: RUN ["c:\windows\system32\tasklist.exe"]

Die korrekte Syntax für dieses Beispiel lautet: RUN ["c:\\windows\\system32\\tasklist.exe"]

Der Cache für RUN Anweisungen wird beim nächsten Build nicht automatisch ungültig gemacht. Der Cache für eine Anweisung wie RUN apt-get dist-upgrade -y wird beim nächsten Build wiederverwendet. Der Cache für RUN Anweisungen kann mit dem Flag --no-cache ungültig gemacht werden, z. B. Docker-Build --no-cache.

Weitere Informationen finden Sie im Handbuch Dockerfile Best Practices.

Der Cache für RUN Anweisungen kann durch ADD Anweisungen ungültig gemacht werden. Details finden Sie unten.

ONBUILD-Anweisung

ONBUILD [INSTRUCTION]

Der ONBUILD Befehl fügt dem Bild einen Auslöserbefehl hinzu, der zu einem späteren Zeitpunkt ausgeführt wird, wenn das Bild als Basis für einen anderen Build verwendet wird. Der Trigger wird im Kontext des Downstream-Builds ausgeführt, als ob er unmittelbar nach dem FROM Befehl in die Downstream-Docker-Datei eingefügt worden wäre.

Jede Build-Anweisung kann als Auslöser registriert werden.

Dies ist nützlich, wenn Sie ein Abbild erstellen, das als Basis zum Erstellen anderer Abbilder verwendet wird, z. B. eine Anwendungserstellungsumgebung oder einen Dämon, der mit einer benutzerspezifischen Konfiguration angepasst werden kann.

Wenn es sich bei Ihrem Image beispielsweise um einen wiederverwendbaren Python-Anwendungsersteller handelt, muss der Anwendungsquellcode in einem bestimmten Verzeichnis hinzugefügt werden. Möglicherweise muss danach ein Build-Skript aufgerufen werden. Sie können jetzt nicht einfach ADD und RUN aufrufen, da Sie noch keinen Zugriff auf den Anwendungsquellcode haben. Dieser wird für jeden Anwendungsaufbau unterschiedlich sein. Sie können Anwendungsentwickler einfach mit einer Boilerplate-Docker-Datei versehen, um sie in ihre Anwendung zu kopieren. Dies ist jedoch ineffizient, fehleranfällig und schwierig zu aktualisieren, da sie mit anwendungsspezifischem Code gemischt wird.

Die Lösung besteht darin, ONBUILD zu verwenden, um erweiterte Anweisungen für die spätere Ausführung während der nächsten ONBUILD zu registrieren.

So funktioniert das:

Wenn er auf eine ONBUILD Anweisung ONBUILD , fügt der Builder den Metadaten des zu ONBUILD einen Auslöser hinzu. Die Anweisung wirkt sich sonst nicht auf den aktuellen Build aus.

Am Ende des Builds wird im Image-Manifest eine Liste aller Trigger unter dem Schlüssel OnBuild gespeichert. Sie können mit dem docker inspect Befehl docker inspect . Später kann das Image mit der FROM Anweisung als Basis für einen neuen Build verwendet werden. Bei der Verarbeitung der FROM Anweisung sucht der Downstream-Builder nach ONBUILD Triggern und führt sie in der Reihenfolge aus, in der sie registriert wurden. Wenn einer der Trigger fehlschlägt, wird der FROM Befehl abgebrochen, wodurch der Build fehlschlägt. Wenn alle Trigger erfolgreich sind, wird die FROM Anweisung abgeschlossen und der Build wird wie gewohnt fortgesetzt.

Trigger werden nach ihrer Ausführung aus dem endgültigen Bild gelöscht. Mit anderen Worten, sie werden nicht von Enkelkindern vererbt.

Zum Beispiel könnten Sie so etwas hinzufügen:

[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]

Warnung: Das Verketten von ONBUILD Anweisungen mit ONBUILD ONBUILD ist nicht zulässig.

Achtung: Die ONBUILD Anweisung nicht auslösen können FROM oder MAINTAINER Anweisungen.

STOPSIGNAL-Anweisung

STOPSIGNAL signal

Die Anweisung STOPSIGNAL setzt das Systemaufrufsignal, das an den Container gesendet wird, zum Beenden. Dieses Signal kann eine gültige vorzeichenlose Zahl sein, die mit einer Position in der Syscall-Tabelle des Kernels übereinstimmt, beispielsweise 9, oder ein Signalname im Format SIGNAME, beispielsweise SIGKILL.

HEALTHCHECK-Anweisung

Der HEALTHCHECK Befehl hat zwei Formen:

HEALTHCHECK [OPTIONS] CMD command (check container health by running a command inside the container)
HEALTHCHECK NONE (disable any healthcheck inherited from the base image)

Die Anweisung HEALTHCHECK teilt Docker mit, wie ein Container getestet werden kann, um zu überprüfen, ob er noch funktioniert. Dadurch können Fälle wie ein Webserver erkannt werden, der sich in einer Endlosschleife befindet und keine neuen Verbindungen verarbeiten kann, obwohl der Serverprozess noch ausgeführt wird.

Wenn für einen Container eine Integritätsprüfung angegeben wurde, hat er zusätzlich zum normalen Status einen Integritätsstatus. Dieser Status wird zunächst gestartet. Wenn eine Gesundheitsprüfung bestanden wird, wird sie gesund (in welchem ​​Zustand sie zuvor war). Nach einer bestimmten Anzahl aufeinander folgender Fehler wird es ungesund.

Die Optionen, die vor CMD werden können, sind:

--interval=DURATION (default: 30s)
--timeout=DURATION (default: 30s)
--retries=N (default: 3)

Die Zustandsprüfung wird erst Sekunden nach dem Start des Containers ausgeführt und danach erneut Sekunden nach jeder vorherigen Prüfung.

Wenn ein einzelner Durchlauf der Prüfung länger dauert als Timeout-Sekunden, gilt die Prüfung als nicht bestanden.

Wiederholungen aufeinanderfolgender Fehler der Integritätsprüfung erfordern, dass der Container als fehlerhaft eingestuft wird.

Es kann nur eine HEALTHCHECK Anweisung in einer Dockerfile . Wenn Sie mehrere Listen HEALTHCHECK wird nur der letzte HEALTHCHECK wirksam.

Der Befehl nach dem CMD Schlüsselwort kann entweder ein Shell-Befehl (z. B. HEALTHCHECK CMD /bin/check-running ) oder ein Exec-Array (wie bei anderen Dockerfile-Befehlen) sein (siehe ENTRYPOINT für Details).

Der Beendigungsstatus des Befehls zeigt den Integritätsstatus des Containers an. Die möglichen Werte sind:

  • 0: success - der Behälter ist gesund und einsatzbereit
  • 1: unhealthy - Der Container funktioniert nicht ordnungsgemäß
  • 2: starting - Der Container ist noch nicht betriebsbereit, funktioniert aber ordnungsgemäß

Wenn die Sonde 2 zurückgibt ("Start"), wenn der Container bereits den Status "Start" verlassen hat, wird er stattdessen als "ungesund" behandelt.

Um beispielsweise alle fünf Minuten zu überprüfen, dass ein Webserver die Hauptseite der Website innerhalb von drei Sekunden bereitstellen kann:

HEALTHCHECK --interval=5m --timeout=3s \
  CMD curl -f http://localhost/ || exit 1

Um das Debuggen fehlgeschlagener Tests zu erleichtern, wird der von stdout oder stderr geschriebene Ausgabetext (UTF-8-codiert) im Integritätsstatus gespeichert und kann mit docker inspect abgefragt werden. Diese Ausgabe sollte kurz gehalten werden (derzeit werden nur die ersten 4096 Bytes gespeichert).

Wenn sich der health_status eines Containers ändert, wird ein health_status Ereignis mit dem neuen Status generiert.

Die HEALTHCHECK Funktion wurde in Docker 1.12 hinzugefügt.

SHELL-Anweisung

SHELL ["executable", "parameters"]

Mit der SHELL Anweisung kann die Standard-Shell, die für die Shell-Form von Befehlen verwendet wird, überschrieben werden. Die Standardshell unter Linux ist ["/bin/sh", "-c"] und unter Windows ["cmd", "/S", "/C"] . Die SHELL Anweisung muss in einer Dockerfile in JSON-Form geschrieben werden.

Die SHELL Anweisung ist besonders nützlich unter Windows, wo es zwei häufig verwendete und recht unterschiedliche native Shells gibt: cmd und powershell sowie alternative Shells, einschließlich sh.

Die SHELL Anweisung kann mehrmals erscheinen. Jede SHELL Anweisung überschreibt alle vorherigen SHELL Anweisungen und wirkt sich auf alle nachfolgenden Anweisungen aus. Zum Beispiel:

FROM 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 von der SHELL Anweisung beeinflusst werden, wenn ihre Shell-Form in einer Docker-Datei verwendet wird: RUN , CMD und ENTRYPOINT .

Das folgende Beispiel ist ein allgemeines Muster unter Windows, das mit der SHELL Anweisung optimiert werden kann:

...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...

Der vom Docker aufgerufene Befehl lautet:

cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"

Dies ist aus zwei Gründen ineffizient. Zunächst wird ein nicht notwendiger Befehlsprozessor cmd.exe (auch als Shell bezeichnet) aufgerufen. Zweitens erfordert jede RUN Anweisung in der Shell-Form einen zusätzlichen Powershell-Befehl, der dem Befehl vorangestellt wird.

Um dies effizienter zu gestalten, kann einer von zwei Mechanismen eingesetzt werden. Verwenden Sie zum Beispiel die JSON-Form des RUN Befehls, z.

...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...

Das JSON-Formular ist zwar eindeutig und verwendet nicht die nicht benötigte cmd.exe, es erfordert jedoch mehr Ausführlichkeit durch doppelte Anführungszeichen und Escape-Anweisungen. Der alternative Mechanismus besteht darin, die SHELL Anweisung und die Shell-Form zu verwenden, um eine natürlichere Syntax für Windows-Benutzer zu schaffen, insbesondere in Kombination mit der Escape-Parser-Direktive:

# escape=`

FROM windowsservercore
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'

Ergebend:

PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 3.584 kB
Step 1 : FROM windowsservercore
 ---> 5bc36a335344
Step 2 : SHELL powershell -command
 ---> Running in 87d7a64c9751
 ---> 4327358436c1
Removing intermediate container 87d7a64c9751
Step 3 : RUN New-Item -ItemType Directory C:\Example
 ---> Running in 3e6ba16b8df9


Directory: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         6/2/2016   2:59 PM                Example


 ---> 1f1dfdcec085
Removing intermediate container 3e6ba16b8df9
Step 4 : ADD Execute-MyCmdlet.ps1 c:\example\
 ---> 6770b4c17f29
Removing intermediate container b139e34291dc
Step 5 : RUN c:\example\Execute-MyCmdlet -sample 'hello world'
 ---> Running in abdcf50dfd1f
Hello from Execute-MyCmdlet.ps1 - passed hello world
 ---> ba0e25255fda
Removing intermediate container abdcf50dfd1f
Successfully built ba0e25255fda
PS E:\docker\build\shell>

Die SHELL Anweisung kann auch verwendet werden, um die Funktionsweise einer Shell zu ändern. Bei Verwendung von SHELL cmd /S /C /V:ON|OFF unter Windows könnte die Erweiterungssemantik der verzögerten Umgebungsvariablen geändert werden.

Die SHELL Anweisung kann auch unter Linux verwendet werden, wenn eine alternative Shell wie zsh, csh, tcsh und andere erforderlich ist.

Die SHELL Funktion wurde in Docker 1.12 hinzugefügt.

Debian / Ubuntu-Pakete installieren

Führen Sie die Installation mit einem einzigen Ausführungsbefehl aus, um das Update zusammenzuführen und zu installieren. Wenn Sie später weitere Pakete hinzufügen, wird das Update erneut ausgeführt und alle benötigten Pakete installiert. Wenn das Update separat ausgeführt wird, wird es zwischengespeichert, und die Paketinstallation kann fehlschlagen. Das Setzen des Frontends auf nicht interaktiv und das Übergeben von -y zur Installation ist für Skriptinstallationen erforderlich. Durch das Reinigen und Löschen am Ende der Installation wird die Größe der Ebene minimiert.

FROM debian

RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    git \
    openssh-client \
    sudo \
    vim \
    wget \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow