mirror of
https://github.com/Estom/notes.git
synced 2026-04-10 06:18:46 +08:00
分阶段构建
This commit is contained in:
99
docker/12 分阶段构建.md
Normal file
99
docker/12 分阶段构建.md
Normal file
@@ -0,0 +1,99 @@
|
||||
## 多阶段构建
|
||||
### Docker多阶段构建的好处
|
||||
使用Docker多阶段构建有以下几个好处:
|
||||
|
||||
* 减小镜像大小:每个构建阶段只包含必要的依赖项和文件,从而减小了生成的镜像大小。这可以减少镜像的存储空间和传输时间。
|
||||
* 提高构建速度:每个构建阶段可以并行执行,因此可以提高构建速度。而且,每个构建阶段只构建所需的内容,从而减少了构建时间。
|
||||
* 简化Dockerfile:使用多个构建阶段可以将Dockerfile分解为更小的部分,从而使Dockerfile更加易于管理和维护。每个构建阶段都可以专注于特定的任务,而不必关注整个构建过程。
|
||||
* 提高安全性:使用多个构建阶段可以限制敏感信息的泄露。例如,在第一个构建阶段中,可以包含敏感信息,例如私有密钥或密码。而在第二个构建阶段中,可以只包含必要的文件和依赖项。
|
||||
|
||||
|
||||
### 单独执行rm并不会精简镜像体积
|
||||
|
||||
尽管在 Dockerfile 中使用 RUN rm -rf /tmp/* 删除了大量文件,但你可能会发现最终生成的 Docker 镜像的大小并没有显著变化。这是因为每个 Dockerfile 指令都会创建一个新的镜像层,而删除文件的操作并不会减少已有层的大小。 删除的文件其实仍然存在于之前的层中,导致镜像整体大小没有减少。
|
||||
|
||||
要优化镜像大小,你可以考虑以下几个方法:
|
||||
|
||||
合并命令以减少镜像层数。将相关的运行命令合并到一个 RUN 指令中,以减少镜像层数。例如,你可以将安装软件包和删除缓存文件的操作合并到一个 RUN 指令中:
|
||||
```
|
||||
FROM ubuntu:latest
|
||||
|
||||
# 更新包列表、安装软件包并删除缓存文件
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl vim \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
```
|
||||
通过这种方式,删除操作和安装操作在同一个层完成,避免了无用文件占用空间。
|
||||
|
||||
|
||||
|
||||
### 多阶段构建精简镜像体积
|
||||
多阶段构建是一种优化 Docker 镜像大小的方法,可以在构建过程中使用临时构建环境,并在最终镜像中只保留必要的部分。COPY --from复制之前镜像中执行的必要的结果。
|
||||
```
|
||||
# 第一阶段:构建环境
|
||||
FROM node:14 AS builder
|
||||
|
||||
# 在构建环境中执行构建操作
|
||||
WORKDIR /app
|
||||
COPY package.json .
|
||||
RUN npm install
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# 第二阶段:最终镜像
|
||||
FROM nginx:alpine
|
||||
|
||||
# 仅复制构建产物,并删除临时文件夹
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
# 删除不必要的目录
|
||||
RUN rm -rf /usr/share/nginx/html/temp
|
||||
|
||||
# 定义容器启动时运行的命令
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
```
|
||||
|
||||
|
||||
### 目录挂载精简镜像体积
|
||||
|
||||
在 Docker 构建过程中,通常是基于本地文件的路径进行操作的,但有时候可能需要从另一个镜像中获取文件。在 Docker 18.09 版本引入了 BuildKit 功能,其中一个特性是支持在 docker build 中使用挂载点(mounts)来访问其他镜像的文件。
|
||||
|
||||
以下是具体的方法和示例:
|
||||
|
||||
使用 BuildKit 进行挂载
|
||||
* --mount=type=bind 和 --mount=type=cache 是 BuildKit 支持的特性,其中 type=bind 可以用来挂载本地文件系统中的文件,而 type=cache 则常用于缓存构建依赖。但是要访问另一个镜像的文件,通常使用 --mount=type=bind 结合 COPY --from 的多阶段构建来实现。
|
||||
|
||||
启用 BuildKit
|
||||
首先确保 Docker Daemon 启用了 BuildKit。可以在环境变量中设置 DOCKER_BUILDKIT=1:
|
||||
```
|
||||
export DOCKER_BUILDKIT=1
|
||||
```
|
||||
或者在 Docker 运行时添加 --build-arg BUILDKIT_INLINE_CACHE=1 选项:
|
||||
```
|
||||
DOCKER_BUILDKIT=1 docker build .
|
||||
```
|
||||
示例
|
||||
```
|
||||
# Dockerfile 示例:使用 npm 缓存
|
||||
|
||||
# 基础镜像
|
||||
FROM node:14-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# 挂载缓存目录并安装依赖
|
||||
RUN --mount=type=cache,target=/root/.npm \
|
||||
npm install
|
||||
|
||||
# 添加应用程序源代码
|
||||
COPY . .
|
||||
|
||||
# 构建应用程序
|
||||
RUN npm run build
|
||||
|
||||
# 使用最小化的基础镜像
|
||||
FROM nginx:alpine
|
||||
|
||||
# 复制构建产物到最终镜像
|
||||
COPY --from=builder /app/build /usr/share/nginx/html
|
||||
```
|
||||
13
docker/13 覆盖原始命令.md
Normal file
13
docker/13 覆盖原始命令.md
Normal file
@@ -0,0 +1,13 @@
|
||||
如果你的 Dockerfile 中有如下定义:
|
||||
```
|
||||
ENTRYPOINT ["python"]
|
||||
CMD ["app.py"]
|
||||
```
|
||||
你可以在启动容器时使用 --entrypoint 选项来覆盖 ENTRYPOINT,并且提供新的命令来覆盖 CMD:
|
||||
```
|
||||
docker run --entrypoint /bin/sh <image>
|
||||
```
|
||||
或者同时覆盖 ENTRYPOINT 和 CMD:
|
||||
```
|
||||
docker run --entrypoint /bin/sh <image> -c "ls -la"
|
||||
```
|
||||
Reference in New Issue
Block a user