Über die Angelegenheit, die tendenziell mit ARG von Dockerfile verwechselt wird, einem mehrstufigen Build

TL;DR

Wenn Sie ARG mit einer mehrstufigen Docker-Datei verwenden, beachten Sie, dass der Bereich innerhalb der Bühne geschlossen ist! Deklarieren Sie das ARG für jede Stufe! Wenn das in mehreren Stufen verwendete ARG einen Standardwert hat, definieren Sie ein globales ARG und geben Sie dort den Standardwert ein!

Es ist okay, wenn du es so machst!

Dockerfile


#Wenn es einen Standardwert für das ARG gibt, der üblicherweise in jeder Stufe verwendet wird, definieren Sie ihn vor dem ersten FROM.
ARG YOUR_ARG="Default value"

FROM alpine:latest as first_stage
#ARG muss für jede verwendete Stufe deklariert werden.
ARG YOUR_ARG
RUN echo "1st stage: ${YOUR_ARG}"

FROM alpine:latest as second_stage
#ARG muss für jede verwendete Stufe deklariert werden.
ARG YOUR_ARG
RUN echo "2nd stage: ${YOUR_ARG}"

Über die Beziehung zwischen mehrstufigem Build und ARG

In mehrstufigen Builds scheint der Umfang von ARG und ENV pro Stufe begrenzt zu sein. Wussten Sie alle? Ich wusste es nicht, bis mir klar wurde, dass ich mich in der Phase der von mir erstellten Docker-Datei nicht auf den Wert von ARG beziehen konnte.

Laut diesem Kommentar

Correct, Dockerfile instructions, including ENV vars and ARG are scoped per build-stage, and will not be preserved in the next stage; this is by design. You can, however, set a global ARG (set before the first build-stage), and use that value in each build-stage; Dockerfile-Anweisungen, einschließlich ENV und ARG, gelten für jede Build-Phase und werden nicht auf die nächste Phase übertragen. Dies ist, was es beabsichtigt ist. Wenn Sie jedoch das globale ARG (definiert vor der ersten Erstellungsphase) verwenden, können Sie diesen Wert für jede Erstellungsphase nutzen.

... anscheinend ... "Ja wirklich?"

Es wurde auch fest im offiziellen Dokument aufgeführt.

Der variable Bereich der ARG-Anweisung gilt bis zum Ende der Erstellungsphase, in der sie definiert ist. Wenn Sie ARG in mehreren Erstellungsphasen verwenden möchten, müssen Sie die ARG-Anweisung einzeln angeben.

Als ich das Dokument zum ersten Mal las, hatte ich das Gefühl, ich dachte: "Ahhhhh, ich habe es vollständig verstanden", ohne die Bedeutung der Erstellungsphase zu kennen. .. ..

Lassen Sie uns die Bewegung von ARG sehen

Mal sehen, wie ARG in einem mehrstufigen Build funktioniert.

Betriebsüberprüfungsumgebung dieses Dokuments

Zum Zeitpunkt des Schreibens dieses Artikels haben wir den Vorgang mit den folgenden Versionen bestätigt.

# docker --version
Docker version 18.09.1, build 4c52b90

Dockerfile

Die in dieser Überprüfung verwendete Docker-Datei lautet wie folgt.

Dockerfile


#ARG1 deklariert global und legt globale Standardwerte fest.
ARG ARG1="arg1 global default value"
#ARG2 deklariert global, legt jedoch keinen globalen Standardwert fest.
ARG ARG2
#ARG3 deklariert nicht global.
# ARG ARG3


FROM alpine:latest as first_stage

# first_In der Phase wird jedes ARG deklariert und der Standardwert im Bereich festgelegt.
ARG ARG1="arg1 first stage value"
ARG ARG2="arg2 first stage value"
ARG ARG3="arg3 first stage value"
RUN echo -e "first_stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}"


FROM alpine:latest as second_stage

# second_In der Phase wird jedes ARG deklariert, es wird jedoch kein Standardwert im Bereich festgelegt.
ARG ARG1
ARG ARG2
ARG ARG3
RUN echo -e "second_stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}"


FROM alpine:latest as third_stage

# third_Deklarieren Sie zu diesem Zeitpunkt nicht alle ARGs.
# ARG ARG1
# ARG ARG2
# ARG ARG3
RUN echo -e "third_stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}"

Jedes ARG wird wie folgt eingestellt.

ARG Name die Einstellungen
ARG1 Als globales ARG festlegen. Geben Sie auch den Standardwert an.
ARG2 Als globales ARG festlegen. Es ist kein Standardwert angegeben.
ARG3 Nicht als globales ARG festlegen.

Zusätzlich wird jede Stufe wie folgt eingestellt.

Künstlername die Einstellungen
first_stage Deklarieren Sie jedes ARG. Stellen Sie den Standardwert in der Stufe ein.
second_stage Deklarieren Sie jedes ARG. Stellen Sie den Standardwert nicht in der Stufe ein.
third_stage Deklarieren Sie ARG nicht.

--build-arg Build ohne Angabe

Versuchen Sie beim Erstellen von Docker Image, ohne den Wert mit "--build-arg" anzugeben.

# docker build . --no-cache
Sending build context to Docker daemon  14.85kB
...snip...
Step 7/14 : RUN echo -e "1st stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}"
 ---> Running in 2bbe78634ee8
first_stage:
        ARG1=arg1 first stage value
        ARG2=arg2 first stage value
        ARG3=arg3 first stage value
...snip...
Step 12/14 : RUN echo -e "2nd stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}"
 ---> Running in 0c28af93ea9b
second_stage:
        ARG1=arg1 global default value
        ARG2=
        ARG3=
...snip...
Step 14/14 : RUN echo -e "3rd stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}"
 ---> Running in cbca9ed88691
third_stage:
        ARG1=
        ARG2=
        ARG3=
...snip...

--build-arg Build mit Spezifikation

Versuchen Sie nun, mit dem durch --build-arg angegebenen Wert zu erstellen.

# docker build --build-arg ARG1="build arg1 value" --build-arg ARG2="build arg2 value" --build-arg ARG3="build arg3 value" . --no-cache
Sending build context to Docker daemon  14.85kB
...snip...
Step 7/14 : RUN echo -e "1st stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}"
 ---> Running in 10b37c5a524b
first_stage:
        ARG1=build arg1 value
        ARG2=build arg2 value
        ARG3=build arg3 value
...snip...
Step 12/14 : RUN echo -e "2nd stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}"
 ---> Running in e70e3ff9fe9b
second_stage:
        ARG1=build arg1 value
        ARG2=build arg2 value
        ARG3=build arg3 value
...snip...
Step 14/14 : RUN echo -e "3rd stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}"
 ---> Running in e675e8f648e8
third_stage:
        ARG1=
        ARG2=
        ARG3=
...snip...

Zusammenfassung

  1. Wert angegeben durch --build-arg [Hohe Priorität]
  2. Standardwert in der Stufe
  3. Globaler Standardwert [Niedrige Priorität]

Das ist es.

Werbung

Dies ist eine Werbung für das Projekt, die mich dazu veranlasste, das Verhalten von ARG im mehrstufigen Build zu bemerken.

Lassen Sie uns Minecrafts Bedrock Server einfach bedienen! Es ist ein Projekt in diesem Sinne. Minecraft wird gelegentlich aktualisiert, aber der Client wird meistens selbst aktualisiert, aber Bedrock Server wird nicht automatisch aktualisiert, indem die neue Version manuell heruntergeladen und die Zip-Datei extrahiert wird, um die Binärdatei zu extrahieren. Ich musste es ersetzen und den Dienst neu starten ... oder so. Dieses Projekt muss nur einmal eingerichtet werden und der Bedrock Server wird automatisch aktualisiert! Docker wird übrigens zum Erstellen von Bedrock Server verwendet, damit die Umwelt nicht verschmutzt wird!

Vielen Dank!

Wirklich gemacht.

Recommended Posts

Über die Angelegenheit, die tendenziell mit ARG von Dockerfile verwechselt wird, einem mehrstufigen Build
Über die Sache, dass ich süchtig danach war, wie man Hashmap benutzt
Über die Angelegenheit, die tendenziell mit ARG von Dockerfile verwechselt wird, einem mehrstufigen Build
[Android Studio] Über die Tatsache, dass die Entwurfsansicht bei Verwendung von TextClock nicht angezeigt wird
Über die Sache, dass hidden_field wahnsinnig benutzt werden kann
Ein Memo des Programms, mit dem Sie feststellen können, dass die Wahrscheinlichkeit eines Würfelwurfs etwa 1/6 beträgt
[Docker] Ist es gut genug, um es als mehrstufigen Build zu bezeichnen? → Die Geschichte, die so gut wurde
Die Geschichte, ein Projekt zu bauen, das Maven mit Ant gebaut hat
Über die Sache, dass hidden_field wahnsinnig benutzt werden kann
Stellen Sie sicher, dass Sie das Java compareTo-Ergebnis mit 0 vergleichen
Eine Sammlung von Mustern, die Sie kennen möchten, um den Code nicht zu komplizieren
So beheben Sie das Problem, dass beim Stoppen der Webanwendung kein Protokollierungsprotokoll ausgegeben wird
Was ist mit dem Fehler "Kann nicht gelesen werden oder ist keine gültige ZIP-Datei?" Zu tun
Wie gehe ich mit dem Typ um, den ich 2 Jahre lang über das Schreiben eines Java-Programms nachgedacht habe?
Ich habe versucht, das Problem der "mehrstufigen Auswahl" mit Ruby zu lösen
Eine Geschichte über das Erreichen der League Of Legends-API mit JAVA
Über die Sache, dass ich süchtig danach war, wie man Hashmap benutzt
Eine Geschichte, die mit der Einführung von Web Apple Pay zu kämpfen hatte
So identifizieren Sie den Pfad, auf dem leicht Fehler gemacht werden können
[Java] Es kann glücklich sein, wenn der Rückgabewert der Methode, die null zurückgibt, Optional <> ist
Eine Geschichte, der ich mit der automatischen Starteinstellung von Tomcat 8 unter CentOS 8 zweimal verfallen war
Eine Geschichte, die ich mit der Stream-API von Java8 einem Prozess schreiben wollte, der einer while-Anweisung entspricht
Der Fall, in dem das in der "Docker-Datei" definierte "apt-get update" während des "Docker-Compose-Builds" nicht ausgeführt werden konnte.
Ein Memo, das nüchtern von der Anfrage nach mehrteiligen / Formulardaten abhängig war
So interagieren Sie mit einem Server, der die App nicht zum Absturz bringt
Für Sie, die beklagen, dass die Konvertierung von JODConverter + LibreOffice langsam ist
Ich kann nicht bauen, wenn ich das Build-Ziel mit XCode12 auf einen Simulator setze!
Eine Beschreibung des JDBC-Beispiels, die bei der Entwicklung eines benutzerdefinierten Authentifizierungsanbieters mit dem Cognos SDK hilfreich ist
Ich habe ein Programm erstellt, das aus dem mit Java überladenen Prozess nach der Zielklasse sucht
Was tun gegen "Ein Server läuft bereits ...", ohne dass der Rails-Server im Terminal ausgeschaltet wurde
Ich habe versucht, eine Webanwendung zu erstellen, die Tweets mit einer Vue-Word-Cloud durchsucht und die Tendenz untersucht, was im zugehörigen Profil geschrieben steht