À propos du sujet qui a tendance à être confondu avec ARG de Dockerfile qui est une construction en plusieurs étapes

TL;DR

Si vous utilisez ARG avec un Dockerfile de construction en plusieurs étapes, sachez que la portée est fermée à l'intérieur de la scène! Déclarez l'ARG à utiliser pour chaque étape! De plus, si l'ARG utilisé en plusieurs étapes a une valeur par défaut, définissez un ARG global et mettez-y la valeur par défaut!

Ce n'est pas grave si vous faites comme ça!

Dockerfile


#S'il existe une valeur par défaut pour l'ARG qui est couramment utilisée à chaque étape, définissez-la avant le premier FROM.
ARG YOUR_ARG="Default value"

FROM alpine:latest as first_stage
#ARG doit être déclaré pour chaque étape utilisée.
ARG YOUR_ARG
RUN echo "1st stage: ${YOUR_ARG}"

FROM alpine:latest as second_stage
#ARG doit être déclaré pour chaque étape utilisée.
ARG YOUR_ARG
RUN echo "2nd stage: ${YOUR_ARG}"

À propos de la relation entre la construction en plusieurs étapes et l'ARG

Dans les versions en plusieurs étapes, la portée d'ARG et d'ENV semble être limitée par étape. Le saviez-vous tous? Je ne savais pas jusqu'à ce que je réalise que je ne pouvais pas faire référence à la valeur d'ARG dans l'étape du Dockerfile que j'ai créé.

D'après ce commentaire

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; Les instructions Dockerfile, y compris ENV et ARG, sont définies pour chaque étape de construction et ne seront pas reportées à l'étape suivante. C'est ce que c'est par conception. Cependant, si vous utilisez l'ARG global (défini avant la première étape de construction), vous pouvez tirer parti de cette valeur pour chaque étape de construction.

... Apparemment ... Vraiment?

Il a également été fermement répertorié dans le Document officiel.

La portée variable de l'instruction ARG est jusqu'à la fin de l'étape de construction au cours de laquelle elle est définie. Si vous souhaitez utiliser ARG dans plusieurs étapes de construction, vous devez spécifier l'instruction ARG individuellement.

Quand j'ai lu le document pour la première fois, j'ai eu l'impression de penser: «Ahhhhh, je l'ai complètement compris», sans connaître le sens de l'étape de construction. .. ..

Voyons le mouvement d'ARG

Voyons en fait comment ARG fonctionne dans une construction en plusieurs étapes.

Environnement de vérification de fonctionnement de ce document

Au moment de la rédaction de cet article, nous avons confirmé l'opération avec les versions suivantes.

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

Dockerfile

Le Dockerfile utilisé dans cette vérification est le suivant.

Dockerfile


#ARG1 déclare globalement et définit les valeurs par défaut globales.
ARG ARG1="arg1 global default value"
#ARG2 déclare globalement mais ne définit pas de valeur par défaut globale.
ARG ARG2
#ARG3 ne déclare pas globalement.
# ARG ARG3


FROM alpine:latest as first_stage

# first_Dans l'étape, chaque ARG est déclaré et la valeur par défaut de la portée est définie.
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_Dans l'étape, chaque ARG est déclaré, mais aucune valeur par défaut dans la portée n'est définie.
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_Au stade, ne déclarez pas tous les ARG.
# ARG ARG1
# ARG ARG2
# ARG ARG3
RUN echo -e "third_stage:\n\tARG1=${ARG1}\n\tARG2=${ARG2}\n\tARG3=${ARG3}"

Chaque ARG est défini comme suit.

Nom ARG Réglages
ARG1 Défini comme un ARG global. Spécifiez également la valeur par défaut.
ARG2 Défini comme un ARG global. Aucune valeur par défaut n'est spécifiée.
ARG3 Ne définissez pas comme ARG global.

De plus, chaque étape est définie comme suit.

Nom de scène Réglages
first_stage Déclarez chaque ARG. Définissez la valeur par défaut dans la scène.
second_stage Déclarez chaque ARG. Ne définissez pas la valeur par défaut dans la scène.
third_stage Ne déclarez pas ARG.

--build-arg Construire sans spécification

Lors de la construction de Docker Image, essayez de construire sans spécifier la valeur avec --build-arg.

# 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 Construire avec des spécifications

Maintenant, essayez de construire avec la valeur spécifiée par --build-arg.

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

Sommaire

  1. Valeur spécifiée par --build-arg [Haute priorité]
  2. Valeur par défaut dans la scène
  3. Valeur par défaut globale [Faible priorité]

C'est ça.

Publicité

C'est une promotion du projet qui m'a poussé à remarquer le comportement d'ARG en construction en plusieurs étapes.

Exploitons facilement le serveur Bedrock de Minecraft! C'est un projet à l'effet. Minecraft se met parfois à jour, mais le client est principalement mis à jour seul, mais Bedrock Server n'est pas mis à jour automatiquement, téléchargeant manuellement la nouvelle version et extrayant le fichier Zip pour extraire le fichier binaire. J'ai dû le remplacer et redémarrer le service ... ou quelque chose comme ça. Ce projet ne doit être configuré qu'une seule fois et le serveur Bedrock sera mis à jour automatiquement! Au fait, Docker est utilisé pour construire Bedrock Server, donc il ne pollue pas l'environnement!

Merci!

Vraiment fait.

Recommended Posts

À propos du sujet qui a tendance à être confondu avec ARG de Dockerfile qui est une construction en plusieurs étapes
À propos de la question pour laquelle j'étais accro à l'utilisation de hashmap
À propos du sujet qui a tendance à être confondu avec ARG de Dockerfile qui est une construction en plusieurs étapes
[Android Studio] À propos du fait que la vue de conception n'est pas affichée lors de l'utilisation de TextClock
À propos du problème que hidden_field peut être utilisé de manière insensée
Un mémo du programme que vous pouvez réaliser que la probabilité de lancer des dés est d'environ 1/6
[Docker] Est-il suffisant de l'appeler une construction en plusieurs étapes? → L'histoire qui est devenue si bonne
L'histoire de rendre possible la construction d'un projet qui a été construit par Maven avec Ant
À propos du problème que hidden_field peut être utilisé de manière insensée
Assurez-vous de comparer le résultat Java compareTo avec 0
Une collection de modèles dont vous voulez être conscient pour ne pas compliquer le code
Comment résoudre le problème de non-sortie du journal de connexion lorsque l'application Web est arrêtée
Que faire à propos de l'erreur "Impossible de lire ou n'est pas un fichier ZIP valide"
Comment gérer le type auquel j'ai pensé en écrivant un programme Java pendant 2 ans
J'ai essayé de résoudre le problème de la "sélection multi-étapes" avec Ruby
Une histoire sur l'utilisation de l'API League Of Legends avec JAVA
À propos de la question pour laquelle j'étais accro à l'utilisation de hashmap
Une histoire qui a eu du mal avec l'introduction de Web Apple Pay
Comment identifier le chemin sur lequel il est facile de se tromper
[Java] Cela peut être heureux si la valeur de retour de la méthode qui retourne null est facultative <>
Une histoire à laquelle j'étais accro à deux reprises avec le paramètre de démarrage automatique de Tomcat 8 sur CentOS 8
Je voulais écrire un processus équivalent à une instruction while avec l'API Java 8 Stream
Le cas où "apt-get update" défini dans "Dockerfile" n'a pas pu être exécuté au moment de "docker-compose build"
Un mémo sobrement accro à la demande de multipart / form-data
Comment interagir avec un serveur qui ne plante pas l'application
A vous qui regrettez que la conversion de JODConverter + LibreOffice soit lente
Je ne peux pas construire si je définis la destination de construction sur un simulateur avec XCode12!
Une description de l'exemple JDBC qui sera utile lors du développement d'un fournisseur d'authentification personnalisé avec le SDK Cognos
J'ai créé un programme qui recherche la classe cible à partir du processus surchargé avec Java
Que faire à propos de "Un serveur est déjà en cours d'exécution ..." qui s'est produit sans désactiver le serveur de rails dans le terminal
J'ai essayé de créer une application Web qui recherche les tweets avec vue-word cloud et examine la tendance de ce qui est écrit dans le profil associé