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
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 .
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
Verwendungsbeispieldocker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 .
IMO ist es was du brauchst :)
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 .
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" && :
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 VariableDockerfile
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, wennvariable
gesetzt ist, das Ergebnis dieser Wert ist. Wennvariable
nicht gesetzt ist, istWord
das Ergebnis.
${variable:+Word}
zeigt an, dass wennvariable
gesetzt ist,Word
das Ergebnis ist, andernfalls ist das Ergebnis die leere Zeichenfolge.
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
....
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)