Jak używać zmiennej środowiskowej Docker w tablicy ENTRYPOINT?

109

Jeśli ustawię zmienną środowiskową, powiedzmy ENV ADDRESSEE=world, i chcę jej użyć w skrypcie punktu wejścia połączonym w ustalony ciąg, taki jak:

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

mając worldzmienną wartość środowiska, jak mam to zrobić? Próbowałem użyć, "Hello, $ADDRESSEE"ale to nie działa, ponieważ bierze się $ADDRESSEEdosłownie.

Psycho Punch
źródło

Odpowiedzi:

216

Używasz formy exec ENTRYPOINT. W odróżnieniu od postaci powłoki , forma Exec nie wywołuje powłokę poleceń. Oznacza to, że normalne przetwarzanie powłoki nie zachodzi. Na przykład, ENTRYPOINT [ "echo", "$HOME" ]nie spowoduje podstawienia zmiennej w $ HOME. Jeśli chcesz shell przetwarzanie następnie albo użyć formularza powłoki lub powłokę wykonać bezpośrednio, na przykład: ENTRYPOINT [ "sh", "-c", "echo $HOME" ].
Podczas korzystania z formy exec i wykonywania powłoki bezpośrednio, jak w przypadku formy powłoki, to powłoka rozwija zmienną środowiskową, a nie docker . (Z odniesienia do pliku Dockerfile )

W twoim przypadku użyłbym formy muszli

ENTRYPOINT ./greeting --message "Hello, $ADDRESSEE\!"
vitr
źródło
2
ENTRYPOINT java -jar /dockertest.jar -Djava.security.egd=file:/dev/./urandom -Dserver.port=$portpodczas ENV port=123. Port ENV nie został rozwiązany. Jakieś pomysły, dlaczego?
xetra11
1
Chociaż to działa, wydaje się, że stwarza nowe problemy, takie jak nieuwzględnianie przekazanych argumentów do tego punktu wejścia. Na przykład nie możesz dodać --attitude "shouting"argumentu do docker runpolecenia, które powinno zostać przekazane./greeting
Daniel F
5
Użyj, ENTRYPOINT ./greeting --message "Hello, $ADDRESSEE\! $0 $@"jeśli chcesz również przekazać dodatkowe zmienne ./greetingpoprzez docker runwywołanie (lub przekazać CMDplik Dockerfile)
Daniel F
3
Zauważ, że forma powłoki może spowodować, że sygnały nie będą przekazywane do procesu ( greetingw twoim przykładzie). hynek.me/articles/docker-signals
jbg
czy mogę uzyskać wartość zmiennej środowiskowej w postaci exec, np. `[myexecutable.sh," $ variable "], mogę to zrobić przez [" sh "," -c "," echo $ var "], ale nie w ten sposób
lazarus
13

Próbowałem rozwiązać za pomocą sugerowanej odpowiedzi i nadal napotkałem pewne problemy ...

To było rozwiązanie mojego problemu:

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

W szczególności ukierunkowane na Twój problem:

RUN echo "#!/bin/bash \n ./greeting --message ${ADDRESSEE}" > ./entrypoint.sh
RUN chmod +x ./entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]
Ben Kauffman
źródło
wydaje się, że twoja odpowiedź nie dostarcza kompletnych rozwiązań pytanie OP
user9405863
Przypuszczam, że nie rozumiem, w jaki sposób nie zapewnia rozwiązania pytania PO ... Zaktualizowałem przykład, aby rozwiązać dokładnie to pytanie.
Ben Kauffman
wspomniałeś, że nadal napotkałeś pewne problemy !!
user9405863
poprawne, dlatego wprowadziłem nowe rozwiązanie. ... odpowiedź „zaakceptowana” nie działa dla mnie, więc powtarzam do skryptu powłoki i to zadziałało.
Ben Kauffman
2
Byłbym wtedy zainteresowany usłyszeniem twojego podejścia @ReverendTim;)
Ben Kauffman
6

Po wielu bólach i wielkiej pomocy ze strony @vitr et al. Powyżej, zdecydowałem się spróbować

  • standardowe podstawienie basha
  • kształt muszli od punktu wejścia (Wielka końcówki z góry)

i to zadziałało.

ENV LISTEN_PORT=""

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

na przykład

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

i

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

oba ustawiły poprawnie port w moim kontenerze

Nr ref

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

mlo55
źródło