如何通过脚本在 Dockerfile 中动态设置环境变量?
How to set environment variables dynamically by script in Dockerfile?
我通过 Dockerfile 构建我的项目。该项目需要安装 Openvino。 Openvino 需要通过依赖架构的脚本动态设置一些环境变量。脚本是:script to set environment variables
据我了解,Dockerfile 无法将环境变量设置为来自脚本的映像。
如何按照方法解决问题?
我需要设置变量,因为稍后我会继续安装查看环境变量的 opencv。
我认为如果我把脚本放到 ~/.bashrc 文件中以在连接到 bash 时设置变量,如果我有什么技巧可以启动 bash一秒钟,它可以解决我的问题。
其次,我认为构建 openvino 图像,从中创建容器,连接它并在容器中通过 运行 脚本手动初始化变量。之后,将容器转换为图像。创建新的 Dockerfile 并通过将此图像用于正在进行的步骤来继续构建步骤。
Openvino Dockerfile exp and line that run the script
我的 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 && \
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 && \
cd l_openvino_toolkit_p_2020.2.120 && \
sed -i 's/decline/accept/g' silent.cfg && \
./install.sh -s silent.cfg && \
# rm -rf /tmp/* && \
sudo -E $INSTALLDIR/install_dependencies/install_openvino_dependencies.sh
WORKDIR /home/sa
RUN /bin/bash -c "source /opt/intel/openvino/bin/setupvars.sh" && \
echo "source /opt/intel/openvino/bin/setupvars.sh" >> /home/sa/.bashrc && \
echo "source /opt/intel/openvino/bin/setupvars.sh" >> ~/.bashrc && \
$INSTALLDIR/deployment_tools/model_optimizer/install_prerequisites/install_prerequisites.sh && \
$INSTALLDIR/deployment_tools/demo/demo_squeezenet_download_convert_run.sh
RUN bash
# opencv installation
RUN unzip opencv.zip && \
unzip opencv_contrib.zip && \
# rm opencv.zip opencv_contrib.zip && \
mv opencv-4.3.0 opencv && \
mv opencv_contrib-4.3.0 opencv_contrib && \
cd ./opencv && \
mkdir build && \
cd build && \
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 .. && \
make && \
make install && \
ldconfig
您需要让 shell 在您使用它的每个 RUN
命令中以及在容器启动时加载该文件。
对于启动时间,您可以使用入口点包装器脚本:
#!/bin/sh
# Load the script of environment variables
. /opt/intel/openvino/bin/setupvars.sh
# Run the main container command
exec "$@"
然后在Docker文件中,需要在RUN
命令中包含环境变量脚本,并使这个脚本成为镜像的ENTRYPOINT
.
RUN . /opt/intel/openvino/bin/setupvars.sh && \
/opt/intel/openvino/deployment_tools/model_optimizer/install_prerequisites/install_prerequisites.sh && \
/opt/intel/openvino/deployment_tools/demo/demo_squeezenet_download_convert_run.sh
RUN ... && \
. /opt/intel/openvino/bin/setupvars.sh && \
cmake ... && \
make && \
...
COPY entrypoint.sh .
ENTRYPOINT ["./entrypoint.sh"]
CMD same as the command you set in the original image
如果您 docker exec
在容器中调试 shell,它们将看不到这些环境变量,您需要手动 re-read 环境变量脚本。如果你使用docker inspect
查看容器的low-level细节,它也不会显示环境变量。
看起来该脚本只是设置了几个环境变量(尤其是 $LD_LIBRARY_PATH
和 $PYTHONPATH
),如果设置为 long-winded 值,您可以使用 ENV
语句在 Docker 文件中。
如果您查看 docker build
输出,在每个构建步骤之后都有类似 ---> 0123456789ab
的行;这些是您可以 docker run
的有效图像 ID。你可以 运行
docker run --rm 0123456789ab \
env \
| sort > env-a
docker run --rm 0123456789ab \
sh -c '. /opt/intel/openvino/bin/setupvars.sh && env' \
| sort > env-b
这将为您提供两个包含环境变量的本地文件,其中包含和不包含此安装脚本运行。找出差异(例如,使用 comm(1)),在每一行之前放置 ENV
,并将其添加到您的 Docker 文件中。
你不能在 Docker 中真正使用 .bashrc
。许多常见路径不调用其 startup files:在该文档的语言中,Dockerfile RUN
命令和 docker run
指令都不是“交互式 shell" 所以那些不读取点文件,通常 docker run ... command
根本不会调用 shell。
您也不需要 sudo
(您已经 运行 root 身份,交互式密码提示将失败); RUN sh -c
是多余的(Docker 自己插入); source
不是标准的 shell 命令(更喜欢标准的 .
,它甚至可以在没有 shell 扩展名的 Alpine-based 图像上工作) .
我通过 Dockerfile 构建我的项目。该项目需要安装 Openvino。 Openvino 需要通过依赖架构的脚本动态设置一些环境变量。脚本是:script to set environment variables
据我了解,Dockerfile 无法将环境变量设置为来自脚本的映像。
如何按照方法解决问题?
我需要设置变量,因为稍后我会继续安装查看环境变量的 opencv。
我认为如果我把脚本放到 ~/.bashrc 文件中以在连接到 bash 时设置变量,如果我有什么技巧可以启动 bash一秒钟,它可以解决我的问题。
其次,我认为构建 openvino 图像,从中创建容器,连接它并在容器中通过 运行 脚本手动初始化变量。之后,将容器转换为图像。创建新的 Dockerfile 并通过将此图像用于正在进行的步骤来继续构建步骤。
Openvino Dockerfile exp and line that run the script
我的 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 && \
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 && \
cd l_openvino_toolkit_p_2020.2.120 && \
sed -i 's/decline/accept/g' silent.cfg && \
./install.sh -s silent.cfg && \
# rm -rf /tmp/* && \
sudo -E $INSTALLDIR/install_dependencies/install_openvino_dependencies.sh
WORKDIR /home/sa
RUN /bin/bash -c "source /opt/intel/openvino/bin/setupvars.sh" && \
echo "source /opt/intel/openvino/bin/setupvars.sh" >> /home/sa/.bashrc && \
echo "source /opt/intel/openvino/bin/setupvars.sh" >> ~/.bashrc && \
$INSTALLDIR/deployment_tools/model_optimizer/install_prerequisites/install_prerequisites.sh && \
$INSTALLDIR/deployment_tools/demo/demo_squeezenet_download_convert_run.sh
RUN bash
# opencv installation
RUN unzip opencv.zip && \
unzip opencv_contrib.zip && \
# rm opencv.zip opencv_contrib.zip && \
mv opencv-4.3.0 opencv && \
mv opencv_contrib-4.3.0 opencv_contrib && \
cd ./opencv && \
mkdir build && \
cd build && \
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 .. && \
make && \
make install && \
ldconfig
您需要让 shell 在您使用它的每个 RUN
命令中以及在容器启动时加载该文件。
对于启动时间,您可以使用入口点包装器脚本:
#!/bin/sh
# Load the script of environment variables
. /opt/intel/openvino/bin/setupvars.sh
# Run the main container command
exec "$@"
然后在Docker文件中,需要在RUN
命令中包含环境变量脚本,并使这个脚本成为镜像的ENTRYPOINT
.
RUN . /opt/intel/openvino/bin/setupvars.sh && \
/opt/intel/openvino/deployment_tools/model_optimizer/install_prerequisites/install_prerequisites.sh && \
/opt/intel/openvino/deployment_tools/demo/demo_squeezenet_download_convert_run.sh
RUN ... && \
. /opt/intel/openvino/bin/setupvars.sh && \
cmake ... && \
make && \
...
COPY entrypoint.sh .
ENTRYPOINT ["./entrypoint.sh"]
CMD same as the command you set in the original image
如果您 docker exec
在容器中调试 shell,它们将看不到这些环境变量,您需要手动 re-read 环境变量脚本。如果你使用docker inspect
查看容器的low-level细节,它也不会显示环境变量。
看起来该脚本只是设置了几个环境变量(尤其是 $LD_LIBRARY_PATH
和 $PYTHONPATH
),如果设置为 long-winded 值,您可以使用 ENV
语句在 Docker 文件中。
如果您查看 docker build
输出,在每个构建步骤之后都有类似 ---> 0123456789ab
的行;这些是您可以 docker run
的有效图像 ID。你可以 运行
docker run --rm 0123456789ab \
env \
| sort > env-a
docker run --rm 0123456789ab \
sh -c '. /opt/intel/openvino/bin/setupvars.sh && env' \
| sort > env-b
这将为您提供两个包含环境变量的本地文件,其中包含和不包含此安装脚本运行。找出差异(例如,使用 comm(1)),在每一行之前放置 ENV
,并将其添加到您的 Docker 文件中。
你不能在 Docker 中真正使用 .bashrc
。许多常见路径不调用其 startup files:在该文档的语言中,Dockerfile RUN
命令和 docker run
指令都不是“交互式 shell" 所以那些不读取点文件,通常 docker run ... command
根本不会调用 shell。
您也不需要 sudo
(您已经 运行 root 身份,交互式密码提示将失败); RUN sh -c
是多余的(Docker 自己插入); source
不是标准的 shell 命令(更喜欢标准的 .
,它甚至可以在没有 shell 扩展名的 Alpine-based 图像上工作) .