Здесь есть несколько слоев:
- Ваша локальная оболочка расширяет команду;
- , которая запускает некоторый контейнер Docker;
- , которая запускает некоторыедругой процесс (но не обязательно оболочка).
В вашем первом примере
docker run ... echo $DB_HOST
ваша локальная оболочка перехватывает ссылку на переменную до того, как она будет передана в Docker.
Если вы явно заключите его в одинарные кавычки
docker run ... echo '$DB_HOST'
Docker найдет /bin/echo
(при условии, что он существует в контейнере) и запустит его со строкой $DB_HOST
в качестве аргумента, но снова:поскольку на стороне докера не задействована оболочка, она покорно печатает эту строку как есть.
Непосредственный ответ на ваш вопрос заключается в том, чтобы на стороне докера была установлена оболочка
docker run -e DB_HOST=thehost --rm my_application \
sh -c 'echo $DB_HOST'
На немного более высоком уровне:
- Если вы запускаете программу на каком-то другом языке, а не просто команду оболочки, они будут нормально видеть среду (Python
os.environ
, Ruby's ENV
, Node's process.env
, и т. Д. ) - Если у вас есть что-то даже немного сложное, запишите его в сценарий оболочки, скопируйте его в изображение и запустите, что, вероятно, более легко обслуживать, и неявно включает в себя оболочку (первая строка скажет
#!/bin/sh
) - В вашем Dockerfile, если вы скажете
CMD some command
, Docker автоматически обернет это в оболочку;это эквивалентно CMD ["sh", "-c", "some command"]
- То же самое верно для
ENTRYPOINT
, но это, вероятно, ошибка, использовать его таким образом