docker
  • docker教程
  • advanced
    • Docker 构建缓存指南
    • Docker分配CPU资源
    • Dockerfile+Maven插件构建SpringBoot镜像(推荐)
    • Dockerfile构建SpringBoot镜像
    • idea配置docker
    • Docker Jenkins进阶配置
    • 基于jenkins容器部署SpringBoot应用构建镜像(基于Dockerfile+Maven插件构建)
    • Maven插件构建SpringBoot镜像(二)
    • 基于Maven插件为SpringBoot应用构建镜像并推送到远程_私人仓库(Docker Hub)
    • Maven插件构建SpringBoot镜像(一)
    • Docker MongoDB进阶配置
    • Docker 多阶段构建指南
    • Docker MySql进阶配置
    • Docker network进阶配置
    • Docker Nginx进阶配置
    • Docker空(none)镜像处理
    • Docker pip install --no-cache-dir
    • Docker redis进阶配置
  • concepts
    • docker、docker engine和docker desktop区别
    • 架构
    • 什么是容器?
    • 什么是镜像?
    • 什么是Docker?
    • 什么是仓库?
  • docker-compose
    • Docker Compose 锚点的用法
    • docker-compose 编排多服务
    • docker-compose 常用命令
    • docker-compose 部署jenkins
    • docker-compose安装mySql
    • docker-compose网络配置
    • docker-compose安装nginx
    • docker-compose安装redis
    • docker Compose 示例1
  • docker-hub
    • Docker Hub账号服务说明
  • install
    • CentOS Docker 安装
    • Debian Docker 安装
    • Docker 安装 Apache
    • Docker 安装 CentOS
    • Docker 安装 Elasticsearch
    • Docker 安装 GitLab
    • Docker 安装 Jenkins
    • Docker 安装 MongoDB
    • Docker 安装 MySQL
    • Docker 安装 Nginx
    • Docker 安装 Node.js
    • Docker 安装 PHP
    • Docker 安装 Portainer
    • Docker Python 官方镜像使用说明(TAG说明)
    • Docker 安装 Python
    • Docker 安装 Redis
    • Docker 安装 Tomcat
    • Docker 安装 Ubuntu
    • Docker 安装 Wordpress
    • Docker 国内镜像加速
    • MacOS Docker 安装
    • Ubuntu Docker 安装
    • Windows Docker 安装
  • manual
    • Docker attach 命令
    • Docker build 命令
    • Docker 清理命令
    • Docker命令大全
    • Docker commit 命令
    • docker-compose-run-command
    • Docker cp 命令
    • Docker create 命令
    • Docker diff 命令
    • Docker rm 命令
    • Docker exec 命令
    • Docker export 命令
    • Docker history 命令
    • Docker images 命令
    • Docker import 命令
    • Docker info 命令
    • Docker inspect 命令
    • Docker kill 命令
    • Docker load 命令
    • Docker login/logout 命令
    • Docker logs 命令
    • Docker network 命令
    • Docker pause/unpause 命令
    • Docker port 命令
    • Docker 常见问题
    • Docker ps 命令
    • Docker pull 命令
    • Docker push 命令
    • Docker rename 命令
    • docker-resources
    • Docker rm 命令
    • Docker rm 命令
    • Docker run 命令
    • Docker save 命令
    • Docker search 命令
    • Docker start/stop/restart 命令
    • Docker stats 命令
    • Docker tag 命令
    • Docker top 命令
    • Docker version 命令
    • Docker version 命令
    • Docker wait 命令
    • diff
      • Docker Compose 和 docker-compose 区别
      • Docker import、export 与 save、load 命令 区别
  • usage
    • Docker docker-compose 使用
    • Docker 容器连接
    • Docker 容器使用
    • Docker Dockerfile Ptyhon实战配置-1
    • Docker Dockerfile Ptyhon实战配置之多阶段构建-2
    • Docker Dockerfile
    • Docker 镜像使用
    • Docker Machine
    • Docker 仓库管理
    • Swarm集群管理
  • assets
    • mysql
      • my.cnf
Powered by GitBook
On this page
  • 什么是多阶段构建?
  • 为什么使用多阶段构建?
  • 基本概念
  • 示例:使用多阶段构建
  • 示例 Dockerfile
  • 解析 Dockerfile
  • 使用 --from 指令
  • 多阶段构建的好处
  • 1. 减小镜像体积
  • 2. 提高构建速度
  • 3. 清晰的构建步骤
  • 4. 灵活性
  • 高级用法:缓存共享
  • 示例:避免重复安装依赖
  • 总结

Was this helpful?

  1. advanced

Docker 多阶段构建指南

PreviousDocker MongoDB进阶配置NextDocker MySql进阶配置

Last updated 26 days ago

Was this helpful?

什么是多阶段构建?

多阶段构建(Multi-Stage Builds)是一种 Docker 构建技巧,它允许你在 Dockerfile 中定义多个 FROM 指令,每个阶段都可以用不同的基础镜像和构建步骤。这种方法可以有效地减小 Docker 镜像的大小,并且使得构建过程更加高效。

为什么使用多阶段构建?

  1. 减小镜像体积:通过仅保留最终所需的文件和依赖,可以避免将不必要的构建工具和临时文件包含到最终镜像中。

  2. 简化 Dockerfile:多阶段构建可以将不同的构建步骤分离开,使 Dockerfile 更加清晰和易于管理。

  3. 提高安全性:只将必要的文件和依赖打包到生产环境镜像中,减少潜在的安全风险。

基本概念

在 Dockerfile 中,你可以使用多个 FROM 指令,每个指令都标志着一个新的构建阶段。你可以从一个阶段复制文件到另一个阶段,这样可以在多个阶段之间共享文件。

每个阶段都可以有独立的基础镜像,而最终的镜像只会包含最后一个阶段的文件。

示例:使用多阶段构建

下面是一个常见的多阶段构建示例,它演示了如何构建一个 Node.js 应用,并确保最终镜像只有应用代码和必需的依赖,而没有开发工具和构建文件。

示例 Dockerfile

# 阶段 1:构建应用
FROM node:14 AS builder

# 设置工作目录
WORKDIR /app

# 将 package.json 和 package-lock.json 复制到容器中
COPY package.json package-lock.json ./

# 安装应用的依赖
RUN npm install

# 复制应用的源代码
COPY . .

# 构建应用(例如编译 TypeScript 或打包应用)
RUN npm run build

# 阶段 2:生产镜像
FROM node:14-slim

# 设置工作目录
WORKDIR /app

# 只从构建阶段复制需要的文件(比如构建后的应用代码)
COPY --from=builder /app/dist /app/dist
COPY --from=builder /app/node_modules /app/node_modules

# 启动应用
CMD ["node", "dist/app.js"]

解析 Dockerfile

  1. 阶段 1 - builder:

    • 使用 node:14 镜像作为基础镜像,安装项目依赖,构建源代码。

    • 在这一阶段,安装所有的开发依赖(如构建工具、TypeScript 等),并将构建后的文件保存在 /app/dist 目录中。

  2. 阶段 2 - 生产镜像:

    • 使用 node:14-slim 作为基础镜像,它比 node:14 镜像更小,去除了很多不必要的工具。

    • 从第一阶段(builder)复制构建后的代码(/app/dist)和生产依赖(/app/node_modules)。

    • 只有运行时所需的文件和依赖被包含在最终镜像中,避免了开发依赖和构建工具,从而减小了镜像体积。

使用 --from 指令

  • COPY --from=builder 用来从 builder 阶段复制文件到当前阶段。

  • 你可以选择指定从哪个阶段复制文件,只将你需要的文件带入最终镜像。

多阶段构建的好处

1. 减小镜像体积

通过将构建工具(如编译器、开发依赖等)保留在构建阶段,只将最终的应用和运行时依赖复制到生产镜像中,可以显著减少镜像的体积。

例如,在上面的示例中,构建工具和临时文件都不会包含在最终的镜像中,生产镜像仅包含应用代码和生产依赖。

2. 提高构建速度

当 Dockerfile 中包含多个阶段时,Docker 会缓存每个阶段的构建结果。如果某个阶段没有变化,Docker 会复用该阶段的缓存,从而避免不必要的重新构建。这使得后续构建更快。

3. 清晰的构建步骤

多阶段构建允许将不同的构建步骤分离到不同的阶段中。例如,安装依赖、构建应用、清理临时文件等,可以在不同的阶段进行处理,使 Dockerfile 更加易读和可维护。

4. 灵活性

每个构建阶段都可以使用不同的基础镜像,使得你可以灵活选择合适的镜像。例如,你可以在构建阶段使用 node:14 镜像,在生产阶段使用更小的 node:14-slim 镜像,确保最终镜像更小。

高级用法:缓存共享

在多阶段构建中,Docker 会缓存每个构建阶段的结果。如果你在某个阶段没有更改文件,Docker 会重用该阶段的缓存。你可以利用这一点来优化构建过程,尤其是在依赖不经常变化的情况下。

例如,如果你只修改了应用代码,而没有修改 package.json,Docker 会复用安装依赖的步骤,仅重新构建应用代码部分,从而加速构建过程。

示例:避免重复安装依赖

# 阶段 1:构建应用
FROM node:14 AS builder

WORKDIR /app

# 先安装依赖,这一步如果没有变动会被缓存
COPY package.json package-lock.json ./
RUN npm install

# 复制源代码并构建
COPY . .
RUN npm run build

# 阶段 2:生产镜像
FROM node:14-slim

WORKDIR /app

# 复制构建文件
COPY --from=builder /app/dist /app/dist
COPY --from=builder /app/node_modules /app/node_modules

CMD ["node", "dist/app.js"]
  • 如果你没有修改 package.json 和 package-lock.json,Docker 会跳过 RUN npm install 阶段,直接使用缓存的 node_modules,从而加快构建速度。

总结

  • 多阶段构建 通过将构建过程分成多个阶段,只将最终所需的文件复制到最终镜像中,从而减小了 Docker 镜像的大小。

  • 每个阶段可以有不同的基础镜像和构建步骤,可以在构建过程中实现更高效的依赖安装、构建和清理。

  • 通过使用 Docker 的缓存机制,可以加速构建过程,避免重复的安装和构建步骤。

多阶段构建是 Dockerfile 编写中的一项强大工具,可以帮助你构建更加高效、精简且易于维护的 Docker 镜像。


Docker 官方多阶段构建文档