У меня есть файл docker-compose.yml
, в котором я определяю ряд сервисов. Для одной из служб требуется переменная среды, специфичная для хост-компьютера (например, IP-адрес устройства в локальной сети Wi-Fi). Вместо жесткого кодирования я бы предпочел использовать выражение bash, которое при оценке возвращает правильное значение.
Это кажется, что правильный способ передачи таких переменных окружения — через файл dot-env, помещенный в текущий рабочий каталог. См. текущий код ниже:
докер-compose.yml:
version: '3.1'
services:
...
mobile:
build:
context: .
dockerfile: Dockerfile.mobile
command: bash -c "export BASE_URL=$$(node base_url.js)
&& npm start --lan"
environment:
- REACT_NATIVE_PACKAGER_HOSTNAME=${HOST_DEVICE_IP}
depends_on:
- ngrok
ports:
# Expose Metro Bundler
- 19001:19001
# Expose Expo DevTools
- 19002:19002
# Expose App
- 19000:19000
.env:
HOST_DEVICE_IP=$(ipconfig getifaddr en0)
Однако при запуске сервисов с помощью docker-compose envvar REACT_NATIVE_PACKAGER_HOSTNAME
имеет значение $(ipconfig getifaddr en0)
. Другими словами, файл .env
не оценивает выражение и вставляется в виде строки.
TLDR: Как я могу передать переменные среды в контейнер, где значение может быть выражением bash, которое оценивается на хост-компьютере?
Удалите HOST_DEVICE_IP
из вашего .env
файла и вместо этого установите его в командной строке при запуске docker-compose up
:
HOST_DEVICE_IP=$(ipconfig getifaddr en0) docker-compose up -d
Но мне интересно, нужно ли вам это на самом деле? Если вы работаете на Mac или Windows, вы можете использовать специальное имя хоста host.docker.internal
для ссылки на хост Docker. Если вы работаете в Linux, вы можете просто посмотреть адрес шлюза по умолчанию внутри контейнера (который будет соответствовать адресу мостового устройства на хосте, к которому подключен контейнер).
Это единственный способ передать переменную, установленную в «выражение bash, оцененное на хосте». Конечно, вы можете предоставить сценарий, который завершит этот процесс, если вы обеспокоены тем, что ваши инженеры забудут установить это сами.
О, мужик. Это облом и кажется потенциально распространенным вариантом использования. Могу ли я также заставить host.docker.internal
разрешаться перед инъекцией? думаю нет?
Это имя хоста будет разрешаться только внутри контейнера Docker.
Итак, суть в том, что мне нужно разрешить и внедрить его в хост-среду перед запуском docker-compose, так как нет возможности что-то оценить на хосте через докер?
Правильно. Если вы можете придумать решение, которое не требует вычисления значения на хосте, я думаю, вы будете в лучшей форме.
Я знал об установке его в командной строке, но хотел избежать этого, поскольку над этим проектом сотрудничает несколько инженеров, поэтому чем больше можно абстрагировать в инфраструктурный код, тем проще / с большей вероятностью людям будет запускать систему. концы с концами. Разрешается ли
host.docker.internal
илиdocker.for.mac.localhost
IP-адрес устройства в сети? Тем не менее, мне нужно, чтобы он разрешался в IP-адрес, поскольку код загружается на телефон (магия Expo), поэтому нажатиеhost.docker.internal
не будет автоматически разрешено.