我正在尝试在 docker 容器中运行 python 应用程序。 python 应用程序从 .env
文件中获取它的 secret ,并在 python 中使用 dotenv.load_dotenv
来提取 secret 。当我在本地运行时工作得很好..所以我假设它必须与在基本镜像上运行的 Python 版本有关,但是......我已经尝试使用与我在本地运行的版本完全相同的版本,但它仍然失败。
Docker 文件:
FROM python:latest
WORKDIR /casp
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . /casp
ENTRYPOINT [ "python3" ]
CMD [ "main.py" ]
在我的 python 应用程序中:
from pathlib import Path
from dotenv import load_dotenv
env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)
我实际上尝试过完全放弃这个想法,并恢复使用 docker run -e
传递环境变量,但事实证明 Flask
依赖于 dot_env
也是,因此它在那里也失败了。
我已经做了相当多的调查,似乎很多人确实有 Docker/Dotenv 问题,但似乎没有一个直接匹配这个问题。
以前的帖子表明它可能与位置有关,但这里的路径实际上只是匹配容器的 ./env
,因为创建了 WORKDIR
然后整个应用程序目录被复制到其中,其中包括 .env
和 main.py
。
我看到的错误是:
ImportError: 无法从 'dotenv' (/usr/local/lib/python3.9/site-packages/dotenv/__init__.py) 导入名称 'load_dotenv'
当前测试使用的是 Python 3.9
。我在本地运行 Python 3.85
- 我尝试更改 Dockerfile
以匹配此版本...同样的错误。
编辑:
(venv) root@jon-Blade:/home/jon/PycharmProjects/caspv2# pip freeze | grep dotenv
python-dotenv==0.14.0
(venv) root@jon-Blade:/home/jon/PycharmProjects/caspv2# grep dotenv requirements.txt
python-dotenv==0.14.0
编辑编辑:
root@jon-Blade:~# docker exec 2ce1ff67d74f pip list | grep dotenv
python-dotenv 0.14.0
编辑编辑编辑:
从容器中:
>>> import dotenv
>>> dir(dotenv)
['__author__', '__builtins__', '__cached__', '__doc__', '__email__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_get_line_', 'ast', 'get', 'load', 'os', 'save']
在我的终端的 venv 中:
>>> import dotenv
>>> dir(dotenv)
['IS_TYPE_CHECKING', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'compat', 'dotenv_values', 'find_dotenv', 'get_cli_string', 'get_key', 'load_dotenv', 'load_ipython_extension', 'main', 'parser', 'set_key', 'unset_key']
正如我们所见,在容器中是load
,在终端中是load_dotenv
。更重要的是,它与众不同!在 requirements.txt
航站楼:
(venv) jon@jon-Blade:~/PycharmProjects/caspv2$ pip freeze | grep dotenv
python-dotenv==0.14.0
容器:
root@2476f65ffa10:/casp# pip freeze | grep dotenv
python-dotenv==0.14.0
来自终端的版本:
(venv) jon@jon-Blade:~/PycharmProjects/caspv2$ python --version
Python 3.8.5
来自容器的版本:
root@3aa5c393846e:~# python --version
Python 3.8.5
在两者上运行 pip show python-dotenv
也确认了完全相同的细节,一行一行!
这当然很有趣,它令人困惑......但一定有一些有趣的事情发生。
编辑编辑编辑编辑:)
在容器中,我将 python-dotenv
升级到 0.15.0
:
root@8a94c1e22b8a:~# pip show python-dotenv | grep -i version
Version: 0.15.0
但是:
>>> import dotenv
>>> dir(dotenv)
['__author__', '__builtins__', '__cached__', '__doc__', '__email__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_get_line_', 'ast', 'get', 'load', 'os', 'save']
它仍然给我错误的包裹。
最佳答案
你的requirement.txt中的dotenv有版本吗?我会在问题下发表评论,但我不需要更多的代表
python-dotenv==0.15.0
更新: 查看您的 dir(dotenv),您应该看到它没有为您提供正确的包,因此首先将您的 requirement.txt 中的 python-dotenv 更新为 0.15.0,就像我上面显示的那样。 然后更新
FROM python:3.8.5
ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
# Install dependencies:
WORKDIR /casp
COPY requirements.txt /casp/
RUN pip install -r /casp/requirements.txt
# Run the application:
COPY . /casp /casp
CMD ["python3", "main.py"]
主要问题是您的容器没有访问 python-dotenv,即使您正在安装它。如果这不起作用,要么 docker 销毁并重建您的容器。我已经在本地完成了这个并且我有一个工作的 docker 容器。 如果它加快了您的开发速度,您可以通过这种方式添加您的 ENV 变量。
ENV ADMIN=" jack "
您可以使用它访问它
import os
admin_name = os.environ['ADMIN']
关于python - dotenv 不会加载到 docker 容器中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64596785/