Como faço para usar a variável de ambiente Docker na matriz ENTRYPOINT?

109

Se eu definir uma variável de ambiente, digamos ENV ADDRESSEE=world, e quiser usá-la no script de ponto de entrada concatenado em uma string fixa como:

ENTRYPOINT ["./greeting", "--message", "Hello, world!"]

com worldsendo o valor da varible ambiente, como é que eu faço isso? Tentei usar, "Hello, $ADDRESSEE"mas não parece funcionar, pois leva o $ADDRESSEEliteralmente.

Psycho Punch
fonte

Respostas:

216

Você está usando a forma exec de ENTRYPOINT. Ao contrário do formulário shell , o formulário exec não invoca um shell de comando. Isso significa que o processamento normal do shell não ocorre. Por exemplo, ENTRYPOINT [ "echo", "$HOME" ]não fará substituição de variáveis ​​em $ HOME. Se você quiser processamento de shell, em seguida, usar o formulário de shell ou executar um shell diretamente, por exemplo: ENTRYPOINT [ "sh", "-c", "echo $HOME" ].
Ao usar o formulário exec e executar um shell diretamente, como no caso do formulário shell, é o shell que está fazendo a expansão da variável de ambiente, não o docker. ( Da referência do Dockerfile )

No seu caso, eu usaria a forma de shell

ENTRYPOINT ./greeting --message "Hello, $ADDRESSEE\!"
vitr
fonte
2
ENTRYPOINT java -jar /dockertest.jar -Djava.security.egd=file:/dev/./urandom -Dserver.port=$portenquanto ENV port=123. A porta ENV não foi resolvida. Alguma ideia por quê?
xetra11
1
Enquanto funciona, parece criar alguns novos problemas, como não incluir os argumentos passados ​​para esse ponto de entrada. Por exemplo, você não pode adicionar um --attitude "shouting"argumento ao docker runcomando que deve ser passado para./greeting
Daniel F
5
Use ENTRYPOINT ./greeting --message "Hello, $ADDRESSEE\! $0 $@"se você também quiser passar variáveis ​​adicionais por ./greetingmeio da docker runinvocação (ou para passar o CMDdo Dockerfile)
Daniel F
3
Observe que a forma de shell pode fazer com que os sinais não sejam transmitidos ao processo ( greetingem seu exemplo). hynek.me/articles/docker-signals
jbg
posso obter o valor de uma variável de ambiente na forma exec, como `[myexecutable.sh," $ variable "], posso fazer isso por [" sh "," -c "," echo $ var "], mas não desta forma
Lázaro
13

Tentei resolver com a resposta sugerida e ainda encontrei alguns problemas ...

Esta foi uma solução para o meu problema:

ARG APP_EXE="AppName.exe"
ENV _EXE=${APP_EXE}

# Build a shell script because the ENTRYPOINT command doesn't like using ENV
RUN echo "#!/bin/bash \n mono ${_EXE}" > ./entrypoint.sh
RUN chmod +x ./entrypoint.sh

# Run the generated shell script.
ENTRYPOINT ["./entrypoint.sh"]

Visando especificamente o seu problema:

RUN echo "#!/bin/bash \n ./greeting --message ${ADDRESSEE}" > ./entrypoint.sh
RUN chmod +x ./entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]
Ben Kauffman
fonte
parece que sua resposta não fornece soluções completas a pergunta do OP
usuário9405863
Suponho que não entendi como não dá uma solução para a pergunta do OP ... Atualizei com um exemplo para resolver com a pergunta exata em mente.
Ben Kauffman
você mencionou ainda que teve alguns problemas !!
user9405863
correto, é por isso que apresentei uma nova solução. ... a resposta "aceita" não funcionou para mim, então repito para um script de shell e funcionou.
Ben Kauffman
2
Eu estaria interessado em ouvir sua abordagem, então @ReverendTim;)
Ben Kauffman
6

Depois de muita dor e grande ajuda de @vitr et al acima, decidi tentar

  • substituição bash padrão
  • forma de shell de ENTRYPOINT (ótima dica de cima)

e funcionou.

ENV LISTEN_PORT=""

ENTRYPOINT java -cp "app:app/lib/*" hello.Application --server.port=${LISTEN_PORT:-80}

por exemplo

docker run --rm -p 8080:8080 -d --env LISTEN_PORT=8080 my-image

e

docker run --rm -p 8080:80 -d my-image

ambos configuram a porta corretamente no meu contêiner

Refs

consulte https://www.cyberciti.biz/tips/bash-shell-parameter-substitution-2.html

mlo55
fonte