我正在尝试在docker容器中运行python应用程序。python 应用程序从.env
文件中获取机密,并使用 python 中的dotenv.load_dotenv
将机密拉入。当我在本地运行时工作绝对正常。所以我认为它必须与在基本映像上运行的 Python 版本有关,但是。我已经尝试了与本地运行的完全相同的版本,但它仍然失败。
码头工人文件:
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: cannot import name 'load_dotenv' from 'dotenv' (/usr/local/lib/python3.9/site-packages/dotenv/__init__.py)
当前测试正在使用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']
从我的终端的静脉内:
>>> 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']
它仍然给了我错误的包裹。
dotenv 是否在您的要求中.txt带有版本?我会在问题下发表评论,但我不需要更多代表
python-dotenv==0.15.0
更新: 查看您的 dir(dotenv),您应该看到它没有为您提供正确的包,因此首先将 python-dotenv 更新到您的要求中的 0.15.0.txt就像我上面显示的那样。 然后更新
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 变量。
环境管理员="插孔">
您可以使用以下方法访问它
import os
admin_name = os.environ['ADMIN']
好吧,我不确定这有多大的答案......但我只是让它工作。
如果我使用upgrade
开关安装python-dotenv
,它会显示正确的结果,dir(dotenv)
我的解决方法是从requirements.txt
中删除python-dotenv
,然后在Dockerfile
中添加另一行:
RUN pip install -r requirements.txt
RUN pip install -U python-dotenv
它现在可以工作并且应用程序运行。