web-dev-qa-db-ja.com

そうでなくればDockerfileは外部数値で条件付きます

Dockerfileがあります

FROM centos:7
ENV foo=42

それから私はそれを構築する

docker build -t my_docker .

実行してください。

docker run -it -d  my_docker

コマンドラインから引数を渡してDockerfileにifを使用することは可能ですか?こんな感じ

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

そしてこの議論で構築してください。

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

それほどきれいには見えないかもしれませんが、あなたは以下のようにあなたのDockerfile(条件付き)を持つことができます:

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

そして次のようにイメージを構築します。

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

または

docker build -t my_docker .

117
Qasim Sarfraz

buildコマンド のドキュメント によると、--build-argというパラメータがあります。

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

使用例
docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 .

IMOはそれがあなたが必要としているものです:)

19
barat

いくつかの理由から、ここでの答えのほとんどは私を助けてくれませんでした(多分それはDockerfileの中の私のFROM画像に関連しています)

それで、Dockerが引数が空かどうか調べることによって構築する間、ifステートメントを扱うためにbash scriptと組み合わせて私のワークスペースに--build-argを作成することを好みました

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

Dockerビルド:

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

注意:これはbashスクリプトのelse(false)に行きます。

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

備考:これはif(true)に行きます

編集1:

何度か試した後、私は次の 記事 とこの 1つの記事 を見つけました2つのことを理解してください。

1)FROMより前のARGがビルドの外側にある

2)デフォルトのシェルは/ bin/shです。これは、dockerビルドでif elseが少し異なる動作をしていることを意味します。たとえば、文字列を比較するのに "=="の代わりに "="が1つだけ必要です。

だからあなたはDockerfileの中でこれを行うことができます

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

そしてdocker buildでは:

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

これを行うには、直接 "test"バイナリを使用してください。 "else"条件を指定したくない場合は、noopコマンド ":"を使用する必要があります。そのため、dockerはゼロ以外の戻り値エラーで停止しません。

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

まさに他の人が言ったように、シェルスクリプトが助けになるでしょう。

もう1つのケースですが、私見に言及する価値があります(ここでつまずく人、より簡単なケースを探す)、つまり 環境の置き換え .

環境変数ENVステートメントで宣言)は、Dockerfileによって解釈される変数として特定の命令で使用することもできます。

${variable_name}構文は、以下に指定されているように、いくつかの標準的なbash修飾子もサポートします。

  • ${variable:-Word}は、variableが設定されている場合、結果はその値になることを示します。 variableが設定されていない場合は、Wordが結果になります。

  • ${variable:+Word}は、variableが設定されている場合はWordが結果になることを示します。それ以外の場合、結果は空の文字列です。

2
Jing Li

Bashスクリプトと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

引数の引き渡し: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

引数なし: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

イメージを動的に構築することが目的の場合は、おそらく構築スクリプトを使用してください。

Dockerはすでに、多くの言語用のSDKをすでに提供しています。これらのSDKには、通常、任意の文字列またはDockerfileを作成するためのビルド呼び出しが含まれています。

たとえば、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