Unterschied zwischen RUN und CMD in einer Docker-Datei

293

Ich bin verwirrt darüber, wann ich CMDvs verwenden soll RUN. Zum Beispiel, um Bash / Shell-Befehle auszuführen (dh ls -la), die ich immer verwenden würde, CMDoder gibt es eine Situation, in der ich verwenden würde RUN? Der Versuch, die Best Practices für diese beiden ähnlichen DockerfileRichtlinien zu verstehen .

TakeSoUp
quelle

Antworten:

425

RUN ist ein Image-Erstellungsschritt. Der Status des Containers, nachdem ein RUNBefehl für das Container-Image festgeschrieben wurde. Eine Docker-Datei kann viele RUNSchritte enthalten, die übereinander liegen, um das Image zu erstellen.

CMD ist der Befehl, den der Container standardmäßig ausführt, wenn Sie das erstellte Image starten. Eine Docker-Datei verwendet nur die endgültig CMDdefinierte. Das CMDkann beim Starten eines Containers mit überschrieben werden docker run $image $other_command.

ENTRYPOINT ist auch eng mit CMDder Art und Weise verbunden, in der ein Container ein Bild startet , und kann diese ändern.

Matt
quelle
15
Sie tun alles RUN, um Ihre Umgebung CMD ["nginx", "-g", "daemon off;"]
einzurichten
"Eine Docker-Datei kann nur eine CMD haben" - technisch nicht wahr, aber effektiv werden alle bis auf eine ignoriert. Siehe die Antwort von GingerBeer.
Colm Bhandal
"Eine Docker-Datei verwendet nur die endgültig definierte CMD"? Tatsächlich wird die endgültig definierte CMD beim Starten des Images als Container verwendet, oder?
Paul Cheung
1
Ja @paulcheung Der letzte Befehl in der Docker-Datei wird in das Image geschrieben und ist der Befehl, den der Container standardmäßig ausführt, wenn Sie das erstellte Image starten.
Matt
126

RUN - Befehl wird ausgelöst, während wir das Docker-Image erstellen.

CMD - Befehl wird ausgelöst, während wir das erstellte Docker-Image starten.

Nisal Edu
quelle
67

Ich fand diesen Artikel sehr hilfreich, um den Unterschied zwischen ihnen zu verstehen:

RUN - Mit der RUN-Anweisung können Sie Ihre Anwendung und die dafür erforderlichen Pakete installieren. Es führt alle Befehle über dem aktuellen Bild aus und erstellt durch Festschreiben der Ergebnisse eine neue Ebene. Oft finden Sie mehrere RUN-Anweisungen in einer Docker-Datei.

CMD - Mit der CMD-Anweisung können Sie einen Standardbefehl festlegen, der nur ausgeführt wird, wenn Sie den Container ausführen, ohne einen Befehl anzugeben. Wenn der Docker-Container mit einem Befehl ausgeführt wird, wird der Standardbefehl ignoriert. Wenn Dockerfile mehr als eine CMD-Anweisung enthält, werden alle bis auf die letzten
CMD-Anweisungen ignoriert.

Fay
quelle
13

RUN - Installiere Python, dein Container hat jetzt Python in sein Image gebrannt.
CMD - python hello.py, führe dein Lieblingsskript aus

Rohit Salecha
quelle
CMD - Python installieren, hat mein Container jetzt nicht Python in sein Image gebrannt?
Carlos Fontes
RUN erstellt eine Bildebene aus Python, CMD führt einfach den Befehl aus, das Bild nicht zu erstellen
Rohit Salecha
8

RUN-Befehl: Der RUN-Befehl führt grundsätzlich den Standardbefehl aus, wenn wir das Image erstellen. Außerdem werden die Bildänderungen für den nächsten Schritt festgeschrieben.

Es kann mehr als einen RUN-Befehl geben, um das Erstellen eines neuen Images zu unterstützen.

CMD-Befehl: CMD-Befehle legen nur den Standardbefehl für den neuen Container fest. Dies wird zur Erstellungszeit nicht ausgeführt.

Wenn eine Docker-Datei mehr als 1 CMD-Befehle enthält, werden alle außer dem letzten ignoriert. Da dieser Befehl nichts ausführt, sondern nur den Standardbefehl festlegt.

Ingwer Bier
quelle
6

Hinweis: Verwechseln Sie RUN nicht mit CMD. RUN führt tatsächlich einen Befehl aus und schreibt das Ergebnis fest. CMD führt zur Erstellungszeit nichts aus, gibt jedoch den beabsichtigten Befehl für das Image an.

aus der Docker-Dateireferenz

https://docs.docker.com/engine/reference/builder/#cmd

Elsayed
quelle
4

RUN : Kann viele sein und wird im Erstellungsprozess verwendet, z. B. beim Installieren mehrerer Bibliotheken

CMD : Nur 1 haben, die Ihre ist ausführen Startpunkt (zB ["npm", "start"], ["node", "app.js"])

Xin
quelle
2

Die vorhandenen Antworten decken das meiste ab, was jeder, der sich mit dieser Frage befasst, benötigen würde. Ich werde also nur einige Nischenbereiche für CMD und RUN abdecken.

CMD: Duplikate sind zulässig, aber verschwenderisch

GingerBeer macht einen wichtigen Punkt: Sie werden keine Fehler erhalten, wenn Sie mehr als eine CMD eingeben - aber es ist verschwenderisch, dies zu tun. Ich möchte mit einem Beispiel näher darauf eingehen:

FROM busybox
CMD echo "Executing CMD"
CMD echo "Executing CMD 2"

Wenn Sie dies in ein Image einbauen und einen Container in diesem Image ausführen, wird, wie GingerBeer feststellt, nur die letzte CMD berücksichtigt. Die Ausgabe dieses Containers lautet also:

CMD ausführen 2

Ich denke, dass "CMD" eine einzelne globale Variable für das gesamte zu erstellende Image festlegt. Daher überschreiben aufeinanderfolgende "CMD" -Anweisungen einfach alle vorherigen Schreibvorgänge in diese globale Variable und in das endgültige Image, das das erstellt Der letzte, der schreibt, gewinnt. Da eine Docker-Datei in der Reihenfolge von oben nach unten ausgeführt wird, wissen wir, dass die unterste CMD diejenige ist, die dieses endgültige "Schreiben" erhält (metaphorisch gesprochen).

RUN: Befehle werden möglicherweise nicht ausgeführt, wenn Bilder zwischengespeichert werden

Ein subtiler Punkt, der bei RUN zu beachten ist, ist, dass es als reine Funktion behandelt wird, selbst wenn es Nebenwirkungen gibt, und daher zwischengespeichert wird. Dies bedeutet, dass wenn RUN einige Nebenwirkungen hatte, die das resultierende Image nicht ändern, und dieses Image bereits zwischengespeichert wurde, der RUN nicht erneut ausgeführt wird und die Nebenwirkungen bei nachfolgenden Builds nicht auftreten. Nehmen Sie zum Beispiel diese Docker-Datei:

FROM busybox
RUN echo "Just echo while you work"

Wenn Sie es zum ersten Mal ausführen, erhalten Sie eine Ausgabe wie diese mit verschiedenen alphanumerischen IDs:

docker build -t example/run-echo .
Sending build context to Docker daemon  9.216kB
Step 1/2 : FROM busybox
 ---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
 ---> Running in ed37d558c505
Just echo while you work
Removing intermediate container ed37d558c505
 ---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest

Beachten Sie, dass die Echo-Anweisung oben ausgeführt wurde. Wenn Sie es zum zweiten Mal ausführen, wird der Cache verwendet, und in der Ausgabe des Builds wird kein Echo angezeigt:

docker build -t example/run-echo .
Sending build context to Docker daemon  9.216kB
Step 1/2 : FROM busybox
 ---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
 ---> Using cache
 ---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest
Colm Bhandal
quelle
1

Es gab genügend Antworten zu RUN und CMD . Ich möchte nur ein paar Worte zu ENTRYPOINT hinzufügen . CMD- Argumente können durch Befehlszeilenargumente überschrieben werden, während ENTRYPOINT- Argumente immer verwendet werden.

Dieser Artikel ist eine gute Informationsquelle.

Milo Lu
quelle