我试图在一个码头容器中运行一个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']它还是给了我错误的包裹。
发布于 2020-10-29 18:42:17
dotenv在你的requirement.txt中有版本吗?我本可以在这个问题下留下评论,但我不需要更多的代表
python-dotenv==0.15.0更新:查看您的dir(dotenv),您应该会发现它没有给您提供正确的包,所以像我前面所示,首先在您的requirement.txt中将python更新为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,即使您正在安装它。如果这两种方法都不起作用,那么码头就会破坏和重建你的容器。我在当地做过这件事,我有一个工作的码头集装箱。如果它加速了您的开发,您可以这样添加您的ENV变量。
ENV ADMIN="jack“
您可以使用
import os
admin_name = os.environ['ADMIN']发布于 2020-10-30 08:40:45
嗯,我不知道这有多少答案..。但我刚刚让它起作用了。
如果我使用python-dotenv开关安装upgrade,它将显示来自dir(dotenv)的正确结果。
我的解决办法是从python-dotenv中删除requirements.txt,然后在Dockerfile中添加另一行。
RUN pip install -r requirements.txt
RUN pip install -U python-dotenv它现在起作用了,应用程序也在运行。
https://stackoverflow.com/questions/64596785
复制相似问题