Использование связанных переменных среды контейнера в среде приложения?

#docker

#docker

Вопрос:

У меня есть приложение, которое использует переменную среды с именем REDIS_URL . Типичным REDIS_URL было бы redis://172.17.0.5:6379/0 . Я хотел бы иметь возможность заполнять REDIS_URL на основе привязки контейнера:

 docker run --name redis -d redis
docker run --name firehose --link redis:redis -e REDIS_URL="redis://$REDIS_PORT_6379_TCP_ADDR:$REDIS_PORT_6379_TCP_PORT/0" -d firehose/server
 

Но в зависимости от того, как я экранирую переменные среды, они либо вычисляются в моей оболочке во время выполнения docker и являются пустыми ( redis://:/0 ), либо передаются как литеральные строки ( redis://$REDIS_PORT_6379_TCP_ADDR:$REDIS_PORT_6379_TCP_PORT/0 ) .

Как я могу заполнить REDIS_URL переменную среды моего приложения на основе связывания conatiner?

Ответ №1:

Переменные $REDIS_PORT_6379_TCP_ADDR and $REDIS_PORT_6379_TCP_PORT неизвестны во время выполнения docker run команды, поэтому нет способа создать ее с хоста.

Однако есть обходной путь. В Dockerfile для firehose/server изображения должно быть CMD или ENTRYPOINT , которое определяет, какая команда выполняется при запуске изображения. Вы можете поместить оболочку вокруг этой команды, которая создаст REDIS_URL переменную. Что-то вроде этого:

 #!/bin/sh
export REDIS_URL="redis://${REDIS_PORT_6379_TCP_ADDR}:${REDIS_PORT_6379_TCP_PORT}/0"
<run command>
 

Используйте сценарий-оболочку в качестве CMD или ENTRYPOINT в Dockerfile .

Комментарии:

1. Имеет смысл. В итоге я export REDIS_URL=${REDIS_URL:-"redis://$REDIS_PORT_6379_TCP_ADDR:$REDIS_PORT_6379_TCP_PORT/0"} смог сохранить функциональность любого из них. Спасибо!

Ответ №2:

Позвольте мне сначала немного отклониться от темы. Если вы хотите преобразовать переменную env в переменную CLI, вы можете избежать сценария-оболочки, оценив переменную внутри контейнера docker.

 docker run image /bin/bash -c '/container-command $INSIDE_DOCKER'
 

Теперь вы можете жаловаться на то, что не можете использовать переменные оболочки извне вашего контейнера. В этом случае работает приведенная ниже техника:

 docker run image /bin/bash -c "/container-command $OUTSIDE_DOCKER $INSIDE_DOCKER"
 

Вернемся к первоначальному вопросу. Если вы не используете команду по умолчанию из файла Dockerfile, а вместо этого указываете ее, вы можете использовать тот же подход.

 docker run image /bin/bash -c "export FOO=${INSIDE_DOCKER}; echo $FOO"
 

Потенциальное преимущество, которое это имеет в вашем случае по сравнению с оболочкой внутри контейнера, заключается в том, что оболочка внутри контейнера жестко запрограммирована на порт и имя ссылки. Должен быть способ написать оболочку за пределами docker, которая проверяет опубликованные порты (возможно, вместе с командой по умолчанию) и соответствующим образом устанавливает переменные с помощью команды link, чтобы вы не полагались на жесткое кодирование чего-либо.