docker - Dockerfile - 缓存包以更快地重建?
问题描述
我有一个构建 RESTApi 的 Dockerfile。每当我更改代码中的一行代码并想要重建容器时,所有内容都会从 0 开始安装(代码位于 app 文件夹中)。这是我的 Dockerfile:
# Use the Python3.7.2 image
FROM python:3.7.2-stretch
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# grab the key that LLVM use to GPG-sign binary distributions
RUN apt-get update && \
apt-get install -y software-properties-common && \
rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y apt-utils && apt-get install -y curl
RUN apt -y install clang
# Install Mono (careful: Docker image runs on Debian 9)
RUN apt -y install apt-transport-https dirmngr gnupg ca-certificates
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
RUN echo "deb https://download.mono-project.com/repo/debian stable-stretch main" | tee /etc/apt/sources.list.d/mono-official-stable.list
RUN apt update
RUN apt -y install mono-complete
## Install python libraries
RUN apt-get -y install python3-pip
RUN pip install -r requirements.txt
RUN mono /app/pythonnet/tools/nuget/nuget.exe update -self
RUN git config --global http.proxy http://my.proxy.address:port
RUN /usr/bin/python3 -m pip install -U pycparser --user
RUN /usr/bin/python3 -m pip install -U pythonnet --user
# run the command to start uWSGI
CMD ["uwsgi", "app.ini"]
构建此映像需要很长时间,而且由于我只更改了几行代码,因此完全重建是一种不受欢迎的行为。
我跑来docker build -t flask_app .
构建图像。无论如何只重新安装仅在我的代码库中进行更改的某些软件包?
解决方案
docker build
使用可以避免重建部分图像的层缓存。这里的基本规则是,一旦您COPY
(或ADD
)更改了文件,Dockerfile 中该行之后的所有内容将始终重复。指令之前的内容COPY
,或者如果 Docker 可以告诉正在COPY
编辑的文件没有更改,将被跳过(之前构建的层被重用)。
为了支持这一点,一个典型的 Dockerfile 布局如下:
FROM some-base-image
RUN commands to install OS-level dependencies
WORKDIR /app
COPY only files that declare language-level dependencies ./
RUN commands to install language-level dependencies
COPY . ./
RUN commands to build the application
CMD the single command to launch the application
请注意两个单独的COPY
命令。RUN
如果命令的文本没有更改,则重用操作系统级别的依赖项;如果特定文件未更改,则重用语言级别的依赖项;并且应用程序本身通常总是被重建。
在 Dockerfile 的上下文中,您应该让所有RUN apt-get ...
命令在您执行任何操作之前COPY
运行。(最好只有一个apt-get install
; 重要的是让它与一个命令在同一个RUN
命令中。apt-get update
)然后只requirements.txt
复制文件和RUN pip install
; 然后复制应用程序的其余部分。
FROM python:3.7.2-stretch
# Rearrange this so there is only one apt-get install line
# (Do you need all of these dependencies?)
RUN apt-get update && \
apt-get install -y \
apt-transport-https \
apt-utils \
ca-certificates \
clang \
curl \
dirmngr \
gnupg \
software-properties-common
# Similarly install Mono (is it actually needed?)
# Copy and install just Python dependencies
WORKDIR /app
COPY requirements.txt .
# There are no requirements that aren't in the requirements.txt file
RUN pip install -r requirements.txt
# Copy the rest of the app in
COPY . .
# Standard runtime metadata
EXPOSE 8000
CMD ["uwsgi", "app.ini"]
推荐阅读
- python - 使用 python 脚本(数据库 URI)连接到 postgresql,但将“conn”检测为字符串
- spss - 为相同的变量值添加相同的数据(即 ID)
- sql - 从 TSQL 中的表列表中检查表是否为空
- python - 如何使用循环数进行计算但不计算python
- amazon-web-services - 将 Cognito Authorizer 添加到 CDK 中的 Api Gateway LambdaRestAPI
- django - Django过滤没有ManyToManyField“通过”关系的多对多关系
- android - 如何编写单元测试用例 Volley API?
- r - 将 R 中不太常见的因子级别合并到“其他”中
- amadeus - 我如何找出任何酒店的hotelId?
- docker - 如何在 docker 中为多个微服务创建集中式身份验证服务器