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.txt
和 main.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 的隔离级别。 (至少我的 question 为什么我们需要在容器内使用 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"]
然而,如果您需要一些额外的 libraries/compile 工具(如 gcc
)来构建 python 库,那么 pip
安装它时 venv
可能用于仅移动生成的库二进制文件,而无需在容器内存储编译工具。
在这种情况下,您必须使用 相同(或兼容)python base at build
image 和结果图像(venv
" snapshot”应该应用于兼容的基础。
让我们看看this example:
FROM debian:11-slim AS build
...
FROM gcr.io/distroless/python3-debian11
...
两张图片至少 Debian
基于。
或another example:
FROM python:3.9-slim as compiler
...
FROM python:3.9-slim as runner
...
builder
和 runner
的基数相同
看起来 python:3.9.5-slim-buster
和 gcr.io/distroless/python3
都是 Debian based 并且应该兼容,但可能不完全兼容。
您将端点更改为 ENTRYPOINT [ "sleep" , "600"]
。这将允许容器 运行 保持 10 分钟。之后附加到 运行 容器:docker exec -it container_name bash
并检查是否存在 python
可执行文件:ls -l /app/venv/bin/
或者就像我之前说的那样,不用 venv
就直接使用它
我正在尝试为我的烧瓶应用程序创建一个 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.txt
和 main.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 的隔离级别。 (至少我的 question 为什么我们需要在容器内使用 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"]
然而,如果您需要一些额外的 libraries/compile 工具(如 gcc
)来构建 python 库,那么 pip
安装它时 venv
可能用于仅移动生成的库二进制文件,而无需在容器内存储编译工具。
在这种情况下,您必须使用 相同(或兼容)python base at build
image 和结果图像(venv
" snapshot”应该应用于兼容的基础。
让我们看看this example:
FROM debian:11-slim AS build
...
FROM gcr.io/distroless/python3-debian11
...
两张图片至少 Debian
基于。
或another example:
FROM python:3.9-slim as compiler
...
FROM python:3.9-slim as runner
...
builder
和 runner
的基数相同
看起来 python:3.9.5-slim-buster
和 gcr.io/distroless/python3
都是 Debian based 并且应该兼容,但可能不完全兼容。
您将端点更改为 ENTRYPOINT [ "sleep" , "600"]
。这将允许容器 运行 保持 10 分钟。之后附加到 运行 容器:docker exec -it container_name bash
并检查是否存在 python
可执行文件:ls -l /app/venv/bin/
或者就像我之前说的那样,不用 venv
就直接使用它