【问题标题】:Pass windows environmental variables to dockerized python app将 windows 环境变量传递给 dockerized python 应用程序
【发布时间】:2021-02-19 23:50:26
【问题描述】:

我正在运行一个 python 应用程序,它从 Windows 环境变量中读取两个路径,然后继续使用这些路径中的可执行文件对某些文档进行 OCR。由于 POPPLER、TESSERACT 环境变量已经在 Windows 中设置,这个 Python sn-p 对我有用:

popplerPath = os.environ.get('POPPLER')
tesseractPath = os.environ.get('TESSERACT')

现在我正在尝试对应用程序进行 docker 化,据我了解,由于我的容器需要访问这些路径,因此我需要在运行期间使用 VOLUME 安装它们。我的 dockerfile 看起来像这样:

FROM python:3.7.7-slim
WORKDIR ./
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY documents/ .
COPY src/ ./src
CMD [ "python", "./src/run.py" ] 

我使用以下方法构建图像:

docker build -t ocr .

我尝试使用以下方法运行我的容器:

docker run -v %POPPLER%:%POPPLER% -v %TESSERACT%:%TESSERACT% ocr

...但我的应用程序仍然为这些路径获取 None 值,并且无法使用可执行文件。我的方法是否正确,除此之外,这是一种好的开发实践吗?

【问题讨论】:

  • 我相信 %POPPLER% 检索了一个名为 POPPLER 的 Windows 环境变量,我正在尝试安装它(至少通过 cmd 它确实如此)。我的目标是挂载用户已经设置的路径

标签: python docker environment-variables


【解决方案1】:

见doc,环境变量的开关是-e:

$ docker run -e MYVAR1 --env MYVAR2=foo --env-file ./env.list ubuntu bash

在dockerfile,你可以使用

ENV FOO=/bar

如果我正确理解您的陈述,您的路径将安装在与主机相同的容器中。唯一的问题是您的 Python 脚本,它期望路径由环境变量提供。除非您将它们从主机系统传递到容器系统,否则这将不存在。

使用-v 验证挂载的卷是否正确后,您可以尝试使用

docker run -v %POPPLER%:%POPPLER% -v %TESSERACT%:%TESSERACT% --env POPPLER=%POPPLER% --env TESSERACT=%TESSERACT% ocr

或者,如果你总是运行它,你可以考虑将它们放在你的 dockerfile 中以节省一些击键。

【讨论】:

    【解决方案2】:

    您调用的任何可执行文件都必须内置到映像中。容器通常不能调用主机或其他容器中的可执行文件。在您展示的具体示例中,Linux 容器无法运行 Windows 可执行文件,即使您确实使用绑定挂载将其注入容器。

    “slim”python images 是基于 Debian GNU/Linux 构建的,您需要使用它的 APT 工具将这些可执行依赖项安装到您的 Dockerfile 中。 (https://www.debian.org/distrib/packages 有一个搜索框可以帮助您找到正确的包名称;Ubuntu Linux 也使用 Debian 包。)

    FROM python:3.7-slim
    RUN apt-get update \
     && DEBIAN_FRONTEND=noninteractive \
        apt-get install -y \
          popper-utils \
          tesseract-ocr-all
    COPY requirements.txt .
    ...
    

    如果未设置这些环境变量,我建议在您的代码中设置合理的默认值。 apt-get install 命令会将它们放在镜像内的系统路径中。

    popplerPath = os.environ.get('POPPLER', 'poppler')
    tesseractPath = os.environ.get('TESSERACT', 'tesseract')
    

    如果你真的需要它们作为环境变量,你可以使用 Dockerfile ENV 指令

    ENV POPPLER=poppler TESSERACT=tesseract
    

    来自主机的环境变量不会自动传递给容器;你需要一个 Dockerfile ENV 或 docker run -e 选项。还要记住,容器有一个独立的文件系统(Windows 语法路径在 Linux 容器中没有意义),因此这些环境变量需要是容器路径,即您建议的 docker run -v 选项的后半部分。

    【讨论】:

    • 感谢您提供详细信息。我目前正在使用“子进程”在 python 代码中运行可执行文件,所以如果我理解正确,我可以稍微修改我的代码以在 Linux 容器上运行(poppler/tesseract 执行),或者我猜切换到 Windows 容器和继续绑定?
    • 重申一下,构建缺少部分可执行代码的映像并不是最佳实践。将这些工具构建到镜像中,不要使用绑定挂载来注入它们。
    猜你喜欢
    • 2016-07-31
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 2015-10-17
    • 2017-05-02
    • 2020-12-30
    • 2013-12-29
    • 2021-05-23
    相关资源
    最近更新 更多