Файл 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 execps Команда получает новый идентификатор процесса, но имеет искусственный идентификатор родительского процесса, равный 0 - он не является дочерним по отношению к корневому процессу контейнера.

Если вы хотите отладить среду запуска вашего изображения, с помощью типичного сценария точки входа, такого как

#!/bin/sh
. /env.sh
exec "$@"

вы можете docker run --rm -it myimage sh и получившаяся оболочка будет запущена через ваш скрипт точки входа. Но, как вы заметили, пытаясь отладить его с помощью docker exec не проходит через любую часть последовательности точек входа.

Другие вопросы по тегам