在我的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
下载或安装依赖项时出现任何问题RUN
会再次下载所有内容。
在这种情况下,Dockerfile的最佳做法是什么?是否有必要分割要求?使用单独的卷?或者是否有frontend
以外的指令仅用于此类情况?
答案 0 :(得分: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
答案 1 :(得分:0)
听起来您正在对Dockerfile构建进行故障排除。如果在构建时抛出错误,图层将不会应用于图像,因此必须从头开始重新构建它 - 这就是Docker的工作原理。
如果您希望在对构建进行故障排除时缩短反馈循环,可以将pip安装拆分为多个文件,甚至执行到容器中并手动pip安装需求,但是一旦有了工作我会将所有pip安装放在一个命令中,以保持Dockerfile的优化。