wake-up-neo.com

Andockdatei if-else-Bedingung mit externen Argumenten

Ich habe Dockerfile

FROM centos:7
ENV foo=42

dann baue ich es 

docker build -t my_docker .

und führe es aus.

docker run -it -d  my_docker

Ist es möglich, Argumente von der Kommandozeile zu übergeben und mit if else in Dockerfile zu verwenden? Ich meine sowas

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

und bauen mit diesem Argument.

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

Es sieht vielleicht nicht so sauber aus, aber Sie können Ihre Docker-Datei (bedingt) wie folgt haben:

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

und baue dann das Bild als:

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

oder 

docker build -t my_docker .

102
Qasim Sarfraz

Gemäß build command documentation gibt es einen Parameter namens --build-arg

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

Verwendungsbeispiel
docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 .

IMO ist es was du brauchst :)

18
barat

Aus irgendeinem Grund haben mir die meisten Antworten nicht geholfen (vielleicht hängt es mit meinem FROM-Bild in der Docker-Datei zusammen)

Daher zog ich es vor, einen bash script in meinem Arbeitsbereich in Kombination mit --build-arg zu erstellen, um die if -Anweisung während des Docker-Builds zu behandeln, indem geprüft wird, ob das Argument leer ist oder nicht

Bash-Skript:

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

Docker Build:

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

Anmerkung: Dies wird zu den else (false) im Bash-Skript gehen

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

Bemerkung: Dies geht an das if (true)

Edit 1:

Nach mehreren Versuchen habe ich den folgenden Artikel und diesen einen Gefunden, der mir dabei geholfen hat, 2 Dinge zu verstehen:

1) ARG vor FROM ist außerhalb des Builds

2) Die Standard-Shell ist/bin/sh, was bedeutet, dass das if else im Docker-Build ein wenig anders arbeitet. Zum Beispiel brauchen Sie nur ein "=" anstelle von "==", um Strings zu vergleichen.

So können Sie dies in der Dockerfile tun

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

und im docker build:

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

Verwenden Sie dazu einfach die "test" -binäre. Sie sollten auch den Befehl noop ":" verwenden, wenn Sie keine "else" -Bedingung angeben möchten. Andernfalls stoppt das Docker-Objekt nicht mit einem Rückgabewert, der nicht Null ist.

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

Genau wie andere sagten, würde das Shell-Skript helfen.

Nur ein zusätzlicher Fall, meiner Meinung nach ist es erwähnenswert (für jemanden, der hier stolpert und nach einem einfacheren Fall sucht), nämlich Environment Replacement .

Umgebungsvariablen (mit der Anweisung ENV deklariert) können auch in bestimmten Anweisungen als Variablen verwendet werden, die von der Variable Dockerfile interpretiert werden sollen.

Die ${variable_name}-Syntax unterstützt auch einige der unten angegebenen Standard-Modifizierer für die Bash:

  • ${variable:-Word} zeigt an, dass, wenn variable gesetzt ist, das Ergebnis dieser Wert ist. Wenn variable nicht gesetzt ist, ist Word das Ergebnis.

  • ${variable:+Word} zeigt an, dass wenn variable gesetzt ist, Word das Ergebnis ist, andernfalls ist das Ergebnis die leere Zeichenfolge.

1
Jing Li

Bash-Skript und Alpine/Centos verwenden 

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 übergeben: 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

Ohne 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

Wenn Sie dynamisch Images erstellen möchten, sollten Sie dies wahrscheinlich mit einem Buildskript tun.

Docker stellt bereits SDKs für viele Sprachen bereit, die im Allgemeinen einen Build-Aufruf enthalten, mit dem Sie eine beliebige Zeichenfolge oder Docker-Datei angeben können, aus der er erstellt werden kann.

ZB mit 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