Файл Env неправильно получен из сценария точки входа
Я пытаюсь получить файл.env из сценария условного entrypoint.sh, который частично выглядит так:
if [ -f "some-env-file.env" ]; then
source some-env-file.env
простой эхо-сигнал переменной среды, найденной в файле.env, сразу после указанной выше исходной команды выводит правильное значение, и операции, указанные после в сценарии точки входа, выполняются успешно.
Тем не менее, когда я делаю docker exec -it
внутри созданного контейнера файл env выглядит так, как будто он не получен. Только когда я получаю его снова оттуда, я получаю желаемые результаты. (Более конкретно, файл env используется для указания на конкретную среду выполнения для python. Поэтому после входа в контейнер python вызывается правильно только тогда, когда я снова получаю исходный файл env).
Что я делаю неправильно?
Для справки, это последние строки моего Dockerfile (ничего особенного в этом нет):
COPY ./entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
Создание экземпляра контейнера выполняется с помощью docker-compose
YAML.
Заранее спасибо и извините, если об этом уже спрашивали.
2 ответа
Добавление этого к моему entrypoint.sh
исправил проблему:
cat >> /etc/bash.bashrc <<EOF
if [ -f some-env-file.env ]; then
source some-env-file.env
fi
EOF
Процесс запуска Docker заключается в том, что Docker устанавливает некоторые переменные среды (из Dockerfile и docker run -e
параметры), а затем запускает точку входа контейнера. Все, что происходит в точке входа, не входит в компетенцию Докера. В частности, отладочная оболочка, которая запускается через docker exec
не является потомком точки входа и не будет наследовать переменные окружения, которые там установлены. (NB: я не могу найти это явно указано в документации Docker.)
Один хороший эксперимент, который стоит попробовать - запустить:
% docker run -d --name test busybox sh -c 'sleep 60; sleep 60'
6c6aada7e5299e816e9d12dfab9845cc396485a46d909255375128b87ee5eedf
% docker exec test ps -o pid,ppid,comm
PID PPID COMMAND
1 0 sh
6 1 sleep
7 0 ps
Корневой процесс контейнера представляет собой оболочку, которая получает идентификатор процесса 1 и запускает sleep
подпроцесс, с идентификатором процесса 6 и идентификатором родительского процесса 1. docker exec
ps
Команда получает новый идентификатор процесса, но имеет искусственный идентификатор родительского процесса, равный 0 - он не является дочерним по отношению к корневому процессу контейнера.
Если вы хотите отладить среду запуска вашего изображения, с помощью типичного сценария точки входа, такого как
#!/bin/sh
. /env.sh
exec "$@"
вы можете docker run --rm -it myimage sh
и получившаяся оболочка будет запущена через ваш скрипт точки входа. Но, как вы заметили, пытаясь отладить его с помощью docker exec
не проходит через любую часть последовательности точек входа.