#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, чтобы вы не полагались на жесткое кодирование чего-либо.