我有一个奇怪的情况,我有一个 secret.env 文件,其中我设置了所有的环境变量,如下所示:
secret.env
export TWITTER_CONSUMER_KEY="something"
export TWITTER_CONSUMER_SECRET="something"
然后我构建了一个 docker 文件来导出所有变量并按如下方式运行该应用程序:
FROM python:3.8-slim-buster
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install the dependencies
RUN pip install -r requirements.txt
RUN find . -name \*.pyc -delete
# Export all variables
RUN /bin/bash -c "source secret.env";
# tell the port number the container should expose
EXPOSE 8083
# run the command
ENTRYPOINT ["python", "run.py"]
然而,这引发了一个关键错误:
$ docker run --name fortweet --rm -i -t fortweet:latest bash
Traceback (most recent call last):
File "run.py", line 1, in <module>
from app import socketio, app
File "/app/app/__init__.py", line 65, in <module>
app = create_app()
File "/app/app/__init__.py", line 38, in create_app
my_settings = settings.TwitterSettings.get_instance()
File "/app/app/setup/settings.py", line 47, in get_instance
TwitterSettings()
File "/app/app/setup/settings.py", line 14, in __init__
self.consumer_key = os.environ["TWITTER_CONSUMER_KEY"]
File "/usr/local/lib/python3.8/os.py", line 675, in __getitem__
raise KeyError(key) from None
KeyError: 'TWITTER_CONSUMER_KEY'
当我在 Windows 上运行它时,它运行良好!
有人可以帮我吗?
答案1
将最后一行更改为:
ENTRYPOINT ["/bin/bash", "-c", "source secret.env ; python run.py"]
相反,删除RUN
您正在执行采购的位置。另请参阅https://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/RUN
了解、CMD
和之间区别的解释ENTRYPOINT
。
简而言之:
- RUN 在新的层执行命令并创建新的镜像。例如,它通常用于安装软件包。
- CMD 设置默认命令和/或参数,可以在 docker 容器运行时从命令行覆盖这些命令和/或参数。
- ENTRYPOINT 配置一个将作为可执行文件运行的容器。
我不是 docker 专家,但在我的工作中用过几次,所以对它有一些基本的了解。我认为这之所以有效是因为分层,更重要的是,因为获取环境变量的操作纯粹是在内存范围内,而不是在磁盘上存储。所以在 RUN 下获取环境变量实际上并没有实现任何目标。您需要在实际应用程序执行时获取它们,这就是上面的 ENTRYPOINT 修复有效的原因,因为我们在执行时调用 BASH,将变量获取到环境中,然后在同一个 shell 下分叉您的 python 应用程序。
但是,这仍然不能解释为什么它在您的 Windows 环境中起作用 - 我怀疑您在 Windows 环境中的某个地方设置了环境变量,所以它对您来说是有效的,但原因却与您想象的不一样。