我使用Jenkins作业构建了一个带有多级Docker的python Web应用程序,在Jenkins作业的一个阶段,builder
将所有deps安装到一个文件夹中(即pip install --target deps
)。这些将被复制到Docker映像中,并具有相应的ENV PYTHONPATH=deps:.
。但是,当我想启动PATH
上的某个程序(例如uvicorn
)时,错误消息是:sh uvicorn not found
,当我用Python应用程序启动Docker映像时。我甚至将deps/bin
添加到PATH中,但它仍然失败。我做错了什么?构建映像而不使用deps stage,只需安装一个venv就可以解决整个问题。
为了理解它,Makefile和Dockerfile的相关代码如下
FROM Python:3.9-slim as base
ENV PYTHONPATH=deps:.
FROM base as builder
RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=locked \
apt-get update && apt-get --no-install-recommends install -y build-essential
FROM base
COPY deps deps
COPY app app
CMD [uvicorn, app.main:app, --host 0.0.0.0, --port 8000]
生成文件如下
x一个一个一个一个x一个一个二个x
项目结构草图如下所示
│ requirements.txt
├── app
│ ├── models
│ │ └── registry
│ ├── api_router.py
│ ├── configuration.py
│ ├── main.py
│ ├── schemas
│ │
│ └── tests
│ └── unit
└── docs
然而,仅仅将deps文件夹添加到ENV PYTHONPATH = deps:.
并没有帮助。当提示pip list -v
时,没有找到依赖项,但是对于pip freeze
,它们被列出了。
1条答案
按热度按时间uz75evzq1#
这个Dockerfile有很多问题。
1.初始
FROM
行使用了错误的图像名称;如果您尝试从此Dockerfile构建映像,则会失败,并显示:1.正如在评论中所讨论的,有一堆毫无意义的构建阶段,它们对构建过程没有任何贡献,可以被删除。
1.语法
CMD [uvicorn, app.main:app, --host 0.0.0.0, --port 8000]
不正确。尝试从该映像运行容器时,将失败,并显示:我们需要写它与适当的引用(见下文)。
1.因为你在容器 * 外部 * 安装依赖项,脚本(比如
deps/bin/uvicorn
)可能会有错误的Python解释器路径。如果我们解决了上述所有问题,我们最终得到的Dockerfile如下所示:
如果我们从这个Dockerfile构建一个映像并运行它,它会工作:
虽然上面的方法有效,但这并不是通常停靠Python应用程序的方式,更典型的设置是在容器内部安装依赖项(这将消除与路径相关的问题),例如,我们可以使用以下布局: