Как динамически устанавливать переменные среды с помощью скрипта в Dockerfile?

#docker #dockerfile #openvino

#docker #dockerfile #openvino

Вопрос:

Я создаю свой проект с помощью Dockerfile. Проекту необходима установка Openvino. Openvino необходимо динамически устанавливать некоторые переменные среды с помощью скрипта, который зависит от архитектуры. Sciprt — это: скрипт для установки переменных среды

Как я узнал, Dockerfile не может установить переменные среды в изображение из скрипта.

Как мне следовать пути решения проблемы?

Мне нужно установить переменные, потому что позже я продолжу устанавливать opencv, который просматривает переменные среды.

Я думаю, что если я помещу скрипт в файл ~ /.bashrc для установки переменных при подключении к bash, если у меня есть какой-нибудь трюк, чтобы запустить bash на секунду, это могло бы решить мою проблему.

Во-вторых, я думаю, что создайте образ openvino, создайте из него контейнер, подключите его и инициализируйте переменные, запустив скрипт вручную в контейнере. После этого преобразуйте контейнер в изображение. Создайте новый Dockerfile и продолжайте создавать шаги, используя эти изображения для текущих шагов.

Openvino Dockerfile exp и строка, которая запускает скрипт

Мой Dockerfile:

 FROM ubuntu:18.04

ARG DOWNLOAD_LINK=http://registrationcenter-download.intel.com/akdlm/irc_nas/16612/l_openvino_toolkit_p_2020.2.120.tgz

ENV INSTALLDIR /opt/intel/openvino

# openvino download
RUN curl -LOJ "${DOWNLOAD_LINK}"

# opencv download
RUN wget -O opencv.zip https://github.com/opencv/opencv/archive/4.3.0.zip amp;amp; 
    wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.3.0.zip

RUN apt-get -y install sudo

# openvino installation
RUN tar -xvzf ./*.tgz amp;amp; 
    cd l_openvino_toolkit_p_2020.2.120 amp;amp; 
    sed -i 's/decline/accept/g' silent.cfg amp;amp; 
    ./install.sh -s silent.cfg amp;amp; 
    # rm -rf /tmp/* amp;amp; 
    sudo -E $INSTALLDIR/install_dependencies/install_openvino_dependencies.sh

WORKDIR /home/sa

RUN /bin/bash -c "source /opt/intel/openvino/bin/setupvars.sh" amp;amp; 
    echo "source /opt/intel/openvino/bin/setupvars.sh" >> /home/sa/.bashrc amp;amp; 
    echo "source /opt/intel/openvino/bin/setupvars.sh" >> ~/.bashrc amp;amp; 
    $INSTALLDIR/deployment_tools/model_optimizer/install_prerequisites/install_prerequisites.sh amp;amp; 
    $INSTALLDIR/deployment_tools/demo/demo_squeezenet_download_convert_run.sh

RUN bash

# opencv installation

RUN unzip opencv.zip amp;amp; 
    unzip opencv_contrib.zip amp;amp; 
    # rm opencv.zip opencv_contrib.zip amp;amp; 
    mv opencv-4.3.0 opencv amp;amp; 
    mv opencv_contrib-4.3.0 opencv_contrib amp;amp; 
    cd ./opencv amp;amp; 
    mkdir build amp;amp; 
    cd build amp;amp; 
    cmake -D CMAKE_BUILD_TYPE=RELEASE -D WITH_INF_ENGINE=ON -D ENABLE_CXX11=ON -D CMAKE_INSTALL_PREFIX=/usr/local -D INSTALL_PYTHON_EXAMPLES=OFF -D INSTALL_C_EXAMPLES=OFF -D ENABLE_PRECOMPILED_HEADERS=OFF -D OPENCV_ENABLE_NONFREE=ON -D OPENCV_EXTRA_MODULES_PATH=/home/sa/opencv_contrib/modules -D PYTHON_EXECUTABLE=/usr/bin/python3 -D WIDTH_GTK=ON -D BUILD_TESTS=OFF -D BUILD_DOCS=OFF -D WITH_GSTREAMER=OFF -D WITH_FFMPEG=ON -D BUILD_EXAMPLES=OFF .. amp;amp; 
    make amp;amp; 
    make install amp;amp; 
    ldconfig
  

Комментарии:

1. Пожалуйста, поделитесь всем соответствующим кодом в вашем вопросе

2. Мне кажется, вам следует использовать многоступенчатые сборки? docs.docker.com/develop/develop-images/multistage-build

3. @Paolo Я не могу решить, как мне запустить скрипт, который инициализирует переменные среды? Следуя моему мнению выше «Во-вторых …»?

Ответ №1:

Вам нужно заставить оболочку загружать этот файл в каждой RUN команде, в которой вы его используете, а также во время запуска контейнера.

Для времени запуска вы можете использовать скрипт-оболочку точки входа:

 #!/bin/sh
# Load the script of environment variables
. /opt/intel/openvino/bin/setupvars.sh
# Run the main container command
exec "$@"
  

Затем в Dockerfile вам нужно включить переменную среды script в RUN команды и сделать так, чтобы этот скрипт принадлежал изображению ENTRYPOINT .

 RUN . /opt/intel/openvino/bin/setupvars.sh amp;amp; 
    /opt/intel/openvino/deployment_tools/model_optimizer/install_prerequisites/install_prerequisites.sh amp;amp; 
    /opt/intel/openvino/deployment_tools/demo/demo_squeezenet_download_convert_run.sh

RUN ... amp;amp; 
    . /opt/intel/openvino/bin/setupvars.sh amp;amp; 
    cmake ... amp;amp; 
    make amp;amp; 
    ...

 COPY entrypoint.sh .
 ENTRYPOINT ["./entrypoint.sh"]
 CMD same as the command you set in the original image
  

Если вы docker exec отлаживаете оболочки в контейнере, они не увидят эти переменные среды, и вам нужно будет вручную перечитать переменную среды script. Если вы используете docker inspect для просмотра низкоуровневых сведений о контейнере, он также не будет отображать переменные среды.


Похоже, что этот скрипт просто устанавливает пару переменных среды (особенно $LD_LIBRARY_PATH и $PYTHONPATH ), хотя и в несколько затянутые значения, и вы могли бы просто установить их с помощью ENV инструкций в Dockerfile.

Если вы посмотрите на docker build выходные данные, после каждого шага сборки есть строки типа ---> 0123456789ab ; это допустимые идентификаторы изображений, которые вы можете docker run использовать. Вы могли бы запустить

 docker run --rm 0123456789ab 
  env 
  | sort > env-a
docker run --rm 0123456789ab 
  sh -c '. /opt/intel/openvino/bin/setupvars.sh amp;amp; env' 
  | sort > env-b
  

Это даст вам два локальных файла с переменными среды с запуском этого скрипта установки и без него. Найдите различия (скажем, с помощью запятой(1)), поставьте ENV перед каждой строкой и добавьте это в свой Dockerfile.


На самом деле вы не можете использовать .bashrc в Docker. Многие распространенные пути не вызывают его файлы запуска: на языке этой документации ни RUN команда Dockerfile, ни docker run инструкция не являются «интерактивной оболочкой», поэтому они не читают файлы dot и обычно docker run ... command вообще не вызывают оболочку.

Вам также не нужно sudo (вы уже работаете от имени root, и интерактивное приглашение пароля завершится ошибкой); RUN sh -c является избыточным (Docker вставляет его самостоятельно); и source не является стандартной командой командной строки (предпочитайте стандартную . , которая будет работать даже на изображениях на основе Alpine, у которых нет расширений командной оболочки).

Комментарии:

1. Вы решаете не только проблему. Вы также выводите мой мозг в космос, спасибо. Я понимаю сценарий запуска. ... COPY entrypoint.sh . RUN ["chmod", " x", "/home/foo/entrypoint.sh"] ... Для этого требуется разрешение. Я также не могу понять эти строки «Если вы используете docker exec для отладки оболочек …». После сборки docker run -it test bash он запускает контейнер с запущенным entrypoint.sh. И в bash с printenv командами я вижу переменные среды, установленные с помощью скрипта.

2. Да: этот docker run вызов запустит скрипт точки входа и передаст его bash в качестве $@ аргументов, и будет работать так, как вы ожидаете. Другие вопросы в этом пространстве ожидали, что у docker exec и docker inspect также будут переменные среды, вот почему я вызвал, что они не будут.

3. /opt/intel/openvino/bin/setupvars.sh сценарий оболочки использует символы [{, которые не разрешены тире, /bin/sh. Я использую #!/bin/bash в entrypoint.sh файл, но когда я это сделал, я не могу подключить интерактивную оболочку, например docker run -it foo bash