繁体   English   中英

Docker 找不到 Python venv 可执行文件

[英]Docker can't find Python venv executable

我正在尝试为我的烧瓶应用程序创建一个 Docker 映像,如下所示:

# syntax=docker/dockerfile:1

FROM python:3.9.5-slim-buster as build
RUN python3 -m venv /app/venv
COPY . /app
RUN /app/venv/bin/pip install -r /app/requirements.txt

FROM gcr.io/distroless/python3
COPY --from=build /app /app
# ENV PATH = "/app/venv/bin:${PATH}"
EXPOSE 5000
ENTRYPOINT [ "/app/venv/bin/python3" , "main.py"]

基本上,我有两个构建阶段:第一个使用venv创建虚拟环境,第二个使用 distroless 映像并将虚拟环境(连同我的其余文件)从前一个构建阶段复制到新的。

Docker 映像构建没有问题,但是一旦我尝试使用docker run运行映像,我会收到以下错误:

docker: Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/app/venv/bin/python3": stat /app/venv/bin/python3: no such file or directory: unknown.

这个错误让我很困惑,因为我知道 python 可执行文件位于/app/venv/bin ,我通过使用docker export <container name> > container.tar并探索 tar 文件的内容来仔细检查这一点。 据我所知,我不应该收到这个错误。

我究竟做错了什么?

编辑:根据@RQDQ 的要求,以下是我的requirements.txtmain.py的最低版本:

requirements.txt

click==8.1.3
Flask==2.1.2
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.0.1
Werkzeug==2.1.2

main.py

from flask import Flask
app = Flask(__name__, static_folder='build')

@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

if (__name__ == "__main__"):
    app.run(use_reloader=False, host='0.0.0.0', port=5000, threaded=True)

virtualenv不是可以在操作系统(或容器)之间复制的独立环境:

$ python -m venv venv
$ ls -l venv/bin/

total 36
-rw-r--r-- 1 user user 1990 Jun  2 08:35 activate
-rw-r--r-- 1 user user  916 Jun  2 08:35 activate.csh
-rw-r--r-- 1 user user 2058 Jun  2 08:35 activate.fish
-rw-r--r-- 1 user user 9033 Jun  2 08:35 Activate.ps1
-rwxr-xr-x 1 user user  239 Jun  2 08:35 pip
-rwxr-xr-x 1 user user  239 Jun  2 08:35 pip3
-rwxr-xr-x 1 user user  239 Jun  2 08:35 pip3.10
lrwxrwxrwx 1 user user   46 Jun  2 08:35 python -> /home/user/.pyenv/versions/3.10.2/bin/python
lrwxrwxrwx 1 user user    6 Jun  2 08:35 python3 -> python
lrwxrwxrwx 1 user user    6 Jun  2 08:35 python3.10 -> python

如您所见, python可执行文件只是指向原始 python 可执行文件的链接。 它类似于原始 python 的快照,可以恢复或应用。 但是如果你没有原始基础,快照是没有用的。 因此,您必须在将要使用的相同环境中创建venv

但是,对于容器,您根本不需要venv 容器已经是一个隔离的环境,您不需要使用 venv 再增加一个隔离级别。 (至少我关于为什么我们需要在容器内使用venv的问题仍然没有答案)

简而言之:删除所有与venv相关的行:

# syntax=docker/dockerfile:1

FROM gcr.io/distroless/python3
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 5000
ENTRYPOINT [ "python" , "main.py"]

但是,如果您在通过pip安装 Python 库时需要一些额外的库/编译工具(如gcc )来构建 Python 库,那么venv可以用于仅移动生成的库二进制文件,而无需在容器内存储编译工具。

在这种情况下,您必须在build映像和生成的映像中使用相同(或兼容的)python 库( venv “快照”应该应用于兼容的库)。

让我们看看这个例子

FROM debian:11-slim AS build
...

FROM gcr.io/distroless/python3-debian11
...

这两个图像至少基于Debian

另一个例子

FROM python:3.9-slim as compiler
...

FROM python:3.9-slim as runner
...

builderrunner的基础也是一样的


看起来python:3.9.5-slim-bustergcr.io/distroless/python3都是基于 Debian 的,应该兼容,但可能不完全兼容。

您将端点更改为ENTRYPOINT [ "sleep" , "600"] 这将允许容器运行 10 分钟。 之后附加到正在运行的容器: docker exec -it container_name bash并检查python可执行文件是否存在: ls -l /app/venv/bin/

或者只是像我之前所说的那样在没有venv的情况下使用它

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM