Передайте переменную ENV с помощью docker-compose.yml во время выполнения в Dockerfile - PullRequest
0 голосов
/ 30 декабря 2018

Я пытаюсь переопределить значения ENV в моем dockerfile в зависимости от среды (dev / uat / prod) из моего docker-compose.yml.Поскольку некоторые настройки являются чувствительными, я не могу сделать так, чтобы эти параметры были отделены от шага сборки образа докера, вместо этого эти значения должны быть переопределены во время выполнения.Я пытался развернуть следующий docker-compose с помощью команды docker stack deploy -c, однако я заметил, что мои переменные окружения не переопределяют существующие в dockerfile.

Dockerfile:

FROM openjdk:8-jdk-alpine
VOLUME /tmp
VOLUME /etc

ADD sample-0.0.1-SNAPSHOT.jar app.jar

ENV ENV_SETTINGS=ssldev
ENV ZK_HOST=zoo1
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 -Dspring.profiles.active=${ENV_SETTINGS}"

EXPOSE 8080
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
HEALTHCHECK CMD curl --fail -k https://localhost:8080/status || exit 1

docker-compose.yml

version: '3.1'

services:
api:
    image: SOME_RANDOM_IMAGE
    ports:
        - "9083:8080"
    networks:
        - net
    deploy:
        restart_policy:
            condition: on-failure
        mode: global
    environment:
        - ENV_SETTINGS: default,ssldev,postgres
        - ZK_HOST: zoo1:2181,zoo2:2181
networks:
nsp_net:
  external:
    name: net

1 Ответ

0 голосов
/ 30 декабря 2018

Когда вы пишете оператор ENV в Dockerfile, шаг docker build полностью его расширяет и «заполняет» расширенное значение в создаваемом ими образе.Docker не предоставляет шаг, который будет повторно раскрывать переменные окружения во время docker run.Таким образом, ваша проблема не в том, что ENV_SETTINGS не устанавливается, а в том, что JAVA_OPTS не интерпретируется с новым значением ENV_SETTINGS.

Чтобы обойти это, вы можете предоставитьсценарий оболочки, который устанавливает среду.Я склонен структурировать изображения, которые нуждаются в этом, в две части:

  1. ENTRYPOINT изображения - это скрипт, который устанавливает переменные среды и выполняет другую подготовку, и заканчивается exec "$@" для запуска CMD изображения или чего-либо ещекоманда была передана в docker run.
  2. 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 .)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...