Когда вы пишете оператор ENV
в Dockerfile, шаг docker build
полностью его расширяет и «заполняет» расширенное значение в создаваемом ими образе.Docker не предоставляет шаг, который будет повторно раскрывать переменные окружения во время docker run
.Таким образом, ваша проблема не в том, что ENV_SETTINGS
не устанавливается, а в том, что JAVA_OPTS
не интерпретируется с новым значением ENV_SETTINGS
.
Чтобы обойти это, вы можете предоставитьсценарий оболочки, который устанавливает среду.Я склонен структурировать изображения, которые нуждаются в этом, в две части:
- ENTRYPOINT изображения - это скрипт, который устанавливает переменные среды и выполняет другую подготовку, и заканчивается
exec "$@"
для запуска CMD изображения или чего-либо ещекоманда была передана в docker run
. - CMD изображения - это фактическая команда, которую вы хотите запустить.
Ваш сценарий оболочки может выглядеть следующим образом:
#!/bin/sh
JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=${ENV_SETTINGS:-ssldev}"
exec "$@"
Соответствующий Dockerfile будет выглядеть следующим образом:
FROM openjdk:8-jdk-alpine
# Don't declare VOLUME of anything, especially not system directories.
# Prefer COPY to ADD.
COPY sample-0.0.1-SNAPSHOT.jar app.jar
# Should be executable (chmod +x) as checked into source control.
COPY entrypoint.sh entrypoint.sh
ENV ENV_SETTINGS=ssldev
ENV ZK_HOST=zoo1
# Don't include -Dspring.profiles.active here.
# Do include -Djava.security.egd here.
# The JVM knows about $JAVA_OPTS.
ENV JAVA_OPTS="-server -Xms6048m -Xmx6048m -XX:+UseParNewGC - XX:+UseConcMarkSweepGC -XX:+UseTLAB -XX:NewSize=128m -XX:MaxNewSize=128m - XX:MaxTenuringThreshold=0 -XX:SurvivorRatio=1024 - XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=40 - XX:MaxGCPauseMillis=1000 -XX:InitiatingHeapOccupancyPercent=50 - XX:+UseCompressedOops -XX:ParallelGCThreads=8 -XX:ConcGCThreads=8 - XX:+DisableExplicitGC -Djava.security.egd=file:/dev/./urandom"
EXPOSE 8080
ENTRYPOINT ["./entrypoint.sh"]
# Prefer quoted-word form. But if you need a shell to process the
# command line, use unquoted form; don't explicitly "sh -c".
CMD ["java", "-jar", "app.jar"]
HEALTHCHECK CMD curl --fail -k https://localhost:8080/status || exit 1
(Я всегда предпочитаю CMD ENTRYPOINT: этот шаблон-обертка полезен и вездесущ, так что лучше иметь его в наличии, и гораздо проще docker run --rm -it imagename sh
чтобы получить интерактивную отладочную оболочку, если вам не нужно переопределять точку входа, чтобы сделать это. Исключением является то, что я создаю FROM scratch
образ, где буквально невозможно сделать что-либо, кроме запуска связанного двоичного файла, но этоисключение.)
(Также обратите внимание, что более новые JVM, начиная с версии патча Java 8, имеют опции для выполнения контейнера mпределы emory, что приводит к гораздо меньшему значению JAVA_OPTS
;см. «Настройка JVM с учетом ограничений ЦП и ОЗУ» на в документации к образу openjdk .)