web-dev-qa-db-fra.com

Dockerfile si else condition avec des arguments externes

J'ai dockerfile

FROM centos:7
ENV foo=42

alors je le construit 

docker build -t my_docker .

et l'exécuter.

docker run -it -d  my_docker

Est-il possible de passer des arguments en ligne de commande et de les utiliser avec if else dans Dockerfile? Je veux dire quelque chose comme

FROM centos:7
if (my_arg==42)
     {ENV=TRUE}
else:
     {ENV=FALSE}

et construire avec cet argument.

 docker build -t my_docker . --my_arg=42
53
nick_gabpe

Cela peut ne pas sembler si propre mais vous pouvez avoir votre fichier Docker (conditionnel) comme suit:

FROM centos:7
ARG arg
RUN if [ "x$arg" = "x" ] ; then echo Argument not provided ; else echo Argument is $arg ; fi

puis construisez l'image en tant que:

docker build -t my_docker . --build-arg arg=45

ou 

docker build -t my_docker .

102
Qasim Sarfraz

Selon build commande documentation , il existe un paramètre appelé --build-arg

https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables-build-arg

Exemple d'utilisation
docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 .

OMI c'est ce dont vous avez besoin :)

18
barat

Pour une raison quelconque, la plupart des réponses ne m'ont pas aidé (c'est peut-être lié à mon image FROM dans le fichier docker)

J'ai donc préféré créer un bash script dans mon espace de travail combiné avec --build-arg afin de gérer l'instruction if pendant la compilation de Docker en vérifiant si l'argument est vide ou non.

Script Bash:

#!/bin/bash -x

if test -z $1 ; then 
    echo "The arg is empty"
    ....do something....
else 
    echo "The arg is not empty: $1"
    ....do something else....
fi

Dockerfile:

FROM ...
....
ARG arg
COPY bash.sh /tmp/  
RUN chmod u+x /tmp/bash.sh && /tmp/bash.sh $arg
....

Construction Docker:

docker build --pull -f "Dockerfile" -t $SERVICE_NAME --build-arg arg="yes" .

Remarque: Ceci ira à l’autre (false) dans le script bash

docker build --pull -f "Dockerfile" -t $SERVICE_NAME .

Remarque: Cela ira à la si (vrai)

Éditer 1:

Après plusieurs essais, j'ai trouvé le article et celui-ci celui-ci .__ qui m'a aidé à comprendre 2 choses:

1) ARG avant que FROM ne soit en dehors de la construction

2) Le shell par défaut est/bin/sh, ce qui signifie que le if if fonctionne un peu différemment dans la construction du menu fixe. Par exemple, vous n'avez besoin que d'un "=" au lieu de "==" pour comparer des chaînes.

Donc, vous pouvez le faire dans la Dockerfile

ARG argname=false   #default argument when not provided in the --build-arg
RUN if [ "$argname" = "false" ] ; then echo 'false'; else echo 'true'; fi

et dans le docker build:

docker build --pull -f "Dockerfile" --label "service_name=${SERVICE_NAME}" -t $SERVICE_NAME --build-arg argname=true .
8
dsaydon

Utilisez simplement le binaire "test" directement pour le faire. Vous devez également utiliser la commande noop ":" si vous ne souhaitez pas spécifier de condition "else", afin que docker ne s'arrête pas avec une erreur de valeur non nulle.

RUN test -z "$YOURVAR" || echo "var is set" && echo "var is not set"
RUN test -z "$YOURVAR" && echo "var is not set" || :
RUN test -z "$YOURVAR" || echo "var is set" && :
6
benjhess

Exactement comme d'autres l'ont dit, le script Shell pourrait aider.

Juste un cas supplémentaire, à mon humble avis, il vaut la peine de mentionner (pour quelqu'un d’autre qui tombe ici et cherche un cas plus facile), c’est Remplacement de l’environnement .

Les variables Environment (déclarées avec l'instruction ENV) peuvent également être utilisées dans certaines instructions en tant que variables à interpréter par la variable Dockerfile.

La syntaxe ${variable_name} prend également en charge quelques-uns des modificateurs bash standard spécifiés ci-dessous:

  • ${variable:-Word} indique que si variable est défini, le résultat sera cette valeur. Si variable n'est pas défini, alors Word sera le résultat.

  • ${variable:+Word} indique que si variable est défini, alors Word sera le résultat, sinon le résultat est la chaîne vide.

1
Jing Li

Utilisation du script Bash et Alpine/Centos 

Dockerfile  

FROM Alpine  #just change this to centos 

ARG MYARG=""
ENV E_MYARG=$MYARG

ADD . /tmp
RUN chmod +x /tmp/script.sh && /tmp/script.sh

script.sh  

#!/usr/bin/env sh

if [ -z "$E_MYARG" ]; then
    echo "NO PARAM PASSED"
else
    echo $E_MYARG
fi

Argument de passage: docker build -t test --build-arg MYARG="this is a test" .

....
Step 5/5 : RUN chmod +x /tmp/script.sh && /tmp/script.sh
 ---> Running in 10b0e07e33fc
this is a test
Removing intermediate container 10b0e07e33fc
 ---> f6f085ffb284
Successfully built f6f085ffb284

Sans argument: docker build -t test .

....
Step 5/5 : RUN chmod +x /tmp/script.sh && /tmp/script.sh
 ---> Running in b89210b0cac0
NO PARAM PASSED
Removing intermediate container b89210b0cac0
....
0
msoliman

Si vous voulez créer des images de manière dynamique, vous devriez probablement le faire avec un script de construction.

Docker fournit déjà des kits de développement logiciel (SDK) pour de nombreuses langues, qui incluent généralement un appel de construction vous permettant de fournir une chaîne ou un fichier Docker à partir duquel vous souhaitez créer.

Par exemple, avec Ruby:

require 'docker'

val = my_arg == 42 ? "TRUE" : "FALSE"

# Create an Image from a Dockerfile as a String.
Docker::Image.build("FROM centos:7\nENV MY_ENV=" + val)
0
Snps