【问题标题】:How to split pip install into steps in Dockerfile?如何将 pip install 拆分为 Dockerfile 中的步骤?
【发布时间】:2018-05-30 12:15:15
【问题描述】:

在我的 Dockerfile 中有:

FROM python:3.6-alpine

RUN apk add --no-cache --virtual .fetch-deps \
    zlib-dev \
    jpeg-dev \
    geoip-dev

ENV PYTHONUNBUFFERED 1

RUN mkdir /src
WORKDIR /src
ADD requirements.txt /src/

RUN pip install -r requirements.txt

如果在requirements.txt 中下载或安装依赖项有任何问题,当我再次开始构建时pip install 会再次下载所有内容。

在这种情况下,Dockerfile 的最佳实践是什么?有必要拆分需求吗?使用单独的卷?或者除了RUN 之外还有专门针对这种情况的指令吗?

【问题讨论】:

  • 好吧,如果我理解正确的话,那就是使用 docker 的全部想法。每当您从头开始构建映像时,您都会使用 dockerfile 创建一个全新的映像。我现在正在运行一个 python 项目我所做的是我在容器内运行 pip install 然后如果库可以安装到 docker 映像然后我放入需求文件然后我再次构建我的映像

标签: python docker pip dockerfile


【解决方案1】:

您在构建时添加到 Dockerfile 中的每条指令都会为构建添加一个新层。对于构建时运行的每条指令,映像层将该层的内容缓存在其他层之上。如果预期结果每次都相同,则可以在构建之间缓存层。

在您的情况下,如果构建需求文件的步骤失败,则该步骤将不会被视为完成,这意味着下次您运行构建时,它将重新开始该步骤(这将为requirements.txt)。

您可以做的一件事是引入多阶段构建,其中第一阶段安装需求,第二阶段运行您的应用程序;这样,运行第一阶段需求的唯一时间是当您更改 requirements.txt 时。

# FROM x as y
# will name this stage of the build as "dependencies"
FROM python:3.6-alpine as dependencies

RUN apk add --no-cache --virtual .fetch-deps \
    zlib-dev \
    jpeg-dev \
    geoip-dev

ENV PYTHONUNBUFFERED 1

RUN mkdir /src
WORKDIR /src
ADD requirements.txt /src/

RUN pip install -r requirements.txt

# This is the next stage of the build building off your dependencies
FROM dependencies as application

RUN my_application.py

【讨论】:

    【解决方案2】:

    听起来您正在对 Dockerfile 构建进行故障排除。如果在构建时抛出错误,该层将不会应用于映像,因此必须从头开始重新构建它 - 这正是 Docker 的工作原理。

    如果您希望在对构建进行故障排除时缩短反馈循环,您可以将 pip 安装拆分为多个文件,甚至可以执行到容器中并手动 pip 安装要求,但一旦您让它工作,我会将所有 pip 安装放在一个命令中以保持 Dockerfile 优化。

    【讨论】:

    • 不仅是调试,有时由于网络错误导致包下载失败。或者说,在开发阶段我尝试了不同的包,我想在需求中添加一个新的依赖项,不希望它加快构建时间
    猜你喜欢
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-20
    相关资源
    最近更新 更多