programing

Dockerfile if else 조건 외부 인수 포함

nasanasas 2020. 10. 7. 07:44
반응형

Dockerfile if else 조건 외부 인수 포함


나는 dockerfile이 있습니다

FROM centos:7
ENV foo=42

그런 다음 그것을 구축

docker build -t my_docker .

그리고 그것을 실행하십시오.

docker run -it -d  my_docker

명령 줄에서 인수를 전달하고 Dockerfile의 다른 경우와 함께 사용할 수 있습니까? 내 말은

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

이 주장으로 구축하십시오.

 docker build -t my_docker . --my_arg=42

깨끗하게 보이지 않을 수도 있지만 다음과 같이 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 .


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 그것은 당신이 필요한 것입니다 :)


어떤 이유로 여기에있는 대부분의 답변이 도움이되지 않았습니다 (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) FROM 이전의 ARG는 빌드 외부에 있습니다.

2) 기본 셸은 / bin / sh입니다. 즉, if else가 도커 빌드에서 약간 다르게 작동 함을 의미합니다. 예를 들어 문자열을 비교하려면 "=="대신 "="하나만 필요합니다.

그래서 당신은 내부에서 이것을 할 수 있습니다 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 .

Just use the "test" binary directly to do this. You also should use the noop command ":" if you don't want to specify an "else" condition, so docker does not stop with a non zero return value error.

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" && :

Exactly as others told, shell script would help.

Just an additional case, IMHO it's worth mentioning (for someone else who stumble upon here, looking for an easier case), that is Environment replacement.

Environment variables (declared with the ENV statement) can also be used in certain instructions as variables to be interpreted by the Dockerfile.

The ${variable_name} syntax also supports a few of the standard bash modifiers as specified below:

  • ${variable:-word} indicates that if variable is set then the result will be that value. If variable is not set then word will be the result.

  • ${variable:+word} indicates that if variable is set then word will be the result, otherwise the result is the empty string.


Using Bash script and 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

Passing arg: 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

Without arg: 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
....

If what you want is to dynamically build images then you could do so with a build script.

Docker already provides SDKs for many languages that generally include a build call that lets you supply an arbitrary string or Dockerfile to build from.

E.g., with 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)

참고URL : https://stackoverflow.com/questions/43654656/dockerfile-if-else-condition-with-external-arguments

반응형