Eu tenho dockerfile
FROM centos:7
ENV foo=42
então eu construo
docker build -t my_docker .
e execute-o.
docker run -it -d my_docker
É possível passar argumentos da linha de comando e usá-los com if no Dockerfile? Quero dizer algo como
FROM centos:7
if (my_arg==42)
{ENV=TRUE}
else:
{ENV=FALSE}
e construa com este argumento.
docker build -t my_docker . --my_arg=42
docker
dockerfile
nick_gabpe
fonte
fonte
RUN if [ "$arg" == "42" ]; then ENV=TRUE; else ENV=FALSE; fi
. Ou se arg estiver faltando:RUN if [ "x$arg" == "x42" ]; then ...
Respostas:
Pode não parecer tão limpo, mas você pode ter seu Dockerfile (condicional) da seguinte maneira:
e construir a imagem como:
docker build -t my_docker . --build-arg arg=45
ou
docker build -t my_docker .
fonte
[ "$arg" = "x" ]
vez de[ "x$arg" = "x" ]
?if [ $arg != "" ] ;
mas tenho certeza de que há algum problema com o qual não estou familiarizadoif [[ -n "$arg" ]]
verdadeiro se um parâmetro não estiver vazio,if [[ -z "$arg" ]]
verdadeiro se um parâmetro estiver vazio[ "x$arg" = "x" ]
parece que está comparando duas strings entre aspas, mas as aspas são removidas; Isso mantém a sintaxe correta. Depois de extracção Citação: Bom:if x = x ..
. Bad:if =
. NO ENTANTO, HÁ maneiras melhores de verificar a existência de um parâmetro: Verifique a existência de argumentos de entrada .Por algum motivo, a maioria das respostas aqui não me ajudou (talvez esteja relacionado à minha imagem FROM no Dockerfile)
Então, eu preferi criar um
bash script
em meu espaço de trabalho combinado com a--build-arg
fim de manipular a instrução if enquanto o Docker constrói verificando se o argumento está vazio ou nãoScript Bash:
Dockerfile:
Docker Build:
Observação: Isso irá para o else (false) no script bash
Observação: Isso irá para o if (true)
Editar 1:
Depois de várias tentativas eu encontrei o seguinte artigo e este um que me ajudou a entender 2 coisas:
1) ARG antes de FROM estar fora da construção
2) O shell padrão é / bin / sh, o que significa que if else está funcionando um pouco diferente na construção do docker. por exemplo, você precisa apenas de um "=" em vez de "==" para comparar strings.
Então você pode fazer isso dentro do
Dockerfile
e no
docker build
:fonte
De acordo com o doc para o
docker build
comando , existe um parâmetro chamado--build-arg
.Exemplo de uso:
IMO é o que você precisa :)
fonte
Há uma alternativa interessante para as soluções propostas, que funciona com um único Dockerfile , requer apenas uma única chamada para docker build por compilação condicional e evita bash .
Solução:
O seguinte
Dockerfile
resolve esse problema. Copie e cole e experimente você mesmo.Explicação do Dockerfile:
Primeiro pegamos uma
base
imagem (centos:7
no seu caso) e a colocamos em seu próprio palco. Obase
palco deve conter coisas que você deseja fazer antes da condição. Depois disso, temos mais duas etapas, representando os ramos da nossa condição:branch-version-1
ebranch-version-2
. Nós construímos os dois. Ofinal
estágio então escolhe um desses estágios, com base emmy_arg
. Dockerfile condicional. Ai está.Saída durante a execução:
(Eu abreviei um pouco isso ...)
my_arg==2
my_var==1
Obrigado ao Tõnis por esta ideia incrível!
fonte
Basta usar o binário "teste" diretamente para fazer isso. Você também deve usar o comando noop ":" se não quiser especificar uma condição "else", para que o docker não pare com um erro de valor de retorno diferente de zero.
fonte
RUN [ -z "$YOURVAR" ] && ... || :
, eu acreditoRUN test -z "$YOURVAR" || echo "var is set" && echo "var is not set"
&&
na frente de||
:test ! -z "$YOURVAR" && echo "var is set" || echo "var is not set"
Exatamente como outros disseram, o script de shell ajudaria.
Apenas um caso adicional, IMHO vale a pena mencionar (para alguém que tropeçar aqui, procurando um caso mais fácil), que é Substituição de ambiente .
fonte
A resposta aceita pode resolver a questão, mas se quiser
if
condições de várias linhas no dockerfile, você pode fazer isso colocando\
no final de cada linha (semelhante a como faria em um script de shell) e terminando cada comando com;
. Você pode até definir algoset -eux
como o primeiro comando.Exemplo:
No seu caso:
Em seguida, construa com:
fonte
Usando script Bash e Alpine / Centos
Dockerfile
script.sh
Passando arg:
docker build -t test --build-arg MYARG="this is a test" .
Sem arg:
docker build -t test .
fonte