Comment utiliser la variable d'environnement Docker dans le tableau ENTRYPOINT?

109

Si je définis une variable d'environnement, disons ENV ADDRESSEE=world, et que je veux l'utiliser dans le script de point d'entrée concaténé dans une chaîne fixe comme:

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

avec worldétant la valeur du varible de l' environnement, comment puis-je le faire? J'ai essayé d'utiliser "Hello, $ADDRESSEE"mais cela ne semble pas fonctionner, car cela prend $ADDRESSEElittéralement.

Psycho Punch
la source

Réponses:

216

Vous utilisez la forme exec de ENTRYPOINT. Contrairement au formulaire shell , le formulaire exec n'invoque pas de shell de commande. Cela signifie que le traitement normal du shell ne se produit pas. Par exemple, ENTRYPOINT [ "echo", "$HOME" ]ne fera pas de substitution de variable sur $ HOME. Si vous souhaitez que le traitement shell puis utilisez soit la forme de la coque ou exécuter un shell directement, par exemple: ENTRYPOINT [ "sh", "-c", "echo $HOME" ].
Lors de l'utilisation du formulaire exec et de l'exécution directe d'un shell, comme dans le cas du formulaire shell, c'est le shell qui fait l'expansion de la variable d'environnement, et non docker. (À partir de la référence Dockerfile )

Dans votre cas, j'utiliserais la forme shell

ENTRYPOINT ./greeting --message "Hello, $ADDRESSEE\!"
vitr
la source
2
ENTRYPOINT java -jar /dockertest.jar -Djava.security.egd=file:/dev/./urandom -Dserver.port=$porttandis que ENV port=123. Le port ENV n'est pas résolu. Des idées pourquoi?
xetra11
1
Bien que cela fonctionne, il semble créer de nouveaux problèmes, comme ne pas inclure les arguments passés à ce point d'entrée. Par exemple, vous ne pouvez pas ajouter un --attitude "shouting"argument à la docker runcommande qui devrait être passé à./greeting
Daniel F
5
À utiliser ENTRYPOINT ./greeting --message "Hello, $ADDRESSEE\! $0 $@"si vous souhaitez également passer des variables supplémentaires ./greetingvia l' docker runinvocation (ou pour passer CMDle fichier Dockerfile)
Daniel F
3
Notez que la forme shell peut empêcher les signaux d'être transmis au processus ( greetingdans votre exemple). hynek.me/articles/docker-signals
jbg
puis-je obtenir la valeur d'une variable d'environnement sous forme exécutable, comme `[myexecutable.sh," $ variable "], je peux le faire par [" sh "," -c "," echo $ var "], mais pas de cette façon
lazarus
13

J'ai essayé de résoudre avec la réponse suggérée et j'ai toujours rencontré des problèmes ...

C'était une solution à mon problème:

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"]

Cibler spécifiquement votre problème:

RUN echo "#!/bin/bash \n ./greeting --message ${ADDRESSEE}" > ./entrypoint.sh
RUN chmod +x ./entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]
Ben Kauffman
la source
il semble que votre réponse ne fournit pas de solutions complètes à la question du PO
user9405863
Je suppose que je ne comprends pas comment cela ne fournit pas de solution à la question du PO ... J'ai mis à jour avec un exemple à résoudre avec la question exacte à l'esprit.
Ben Kauffman
vous avez mentionné encore que vous avez rencontré des problèmes !!
user9405863
correct, c'est pourquoi j'ai introduit une nouvelle solution. ... la réponse "acceptée" n'a pas fonctionné pour moi, donc j'ai fait écho à un script shell et cela a fonctionné.
Ben Kauffman
2
Je serais intéressé d'entendre votre approche alors @ReverendTim;)
Ben Kauffman
6

Après beaucoup de douleur et une grande assistance de @vitr et al ci-dessus, j'ai décidé d'essayer

  • substitution de bash standard
  • forme de coque de ENTRYPOINT (bonne astuce d'en haut)

et cela a fonctionné.

ENV LISTEN_PORT=""

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

par exemple

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

et

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

les deux définissent correctement le port dans mon conteneur

Réfs

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

mlo55
la source