当前位置: 首页 > article >正文

第三部分-Dockerfile与镜像构建——15. 多阶段构建

15. 多阶段构建1. 多阶段构建概述多阶段构建是 Docker 17.05 引入的特性允许在单个 Dockerfile 中使用多个 FROM 语句每个阶段可以独立构建最终只选择需要的文件复制到最终镜像中从而大幅减小镜像体积。┌─────────────────────────────────────────────────────────────┐ │ 多阶段构建流程 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 阶段1: 构建阶段builder │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ FROM golang:1.17 AS builder │ │ │ │ COPY . . │ │ │ │ RUN go build -o myapp │ │ │ │ 体积: 800MB │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ 阶段2: 运行阶段runtime │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ FROM alpine:latest │ │ │ │ COPY --frombuilder /app/myapp /myapp │ │ │ │ 体积: 10MB │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ 最终镜像: 10MB (而非 800MB) │ │ │ └─────────────────────────────────────────────────────────────┘2. 基础用法2.1 简单多阶段构建# 多阶段构建示例 # 阶段1编译阶段 FROM golang:1.17-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED0 GOOSlinux go build -a -installsuffix cgo -o main . # 阶段2运行阶段 FROM alpine:latest RUN apk --no-cache add ca-certificates COPY --frombuilder /app/main /app/main ENTRYPOINT [/app/main]2.2 命名阶段# 阶段命名 FROM node:14-alpine AS dependencies WORKDIR /app COPY package*.json ./ RUN npm ci --onlyproduction FROM node:14-alpine AS build WORKDIR /app COPY --fromdependencies /app/node_modules ./node_modules COPY . . RUN npm run build FROM nginx:alpine AS runtime COPY --frombuild /app/dist /usr/share/nginx/html3. 复制文件3.1 从指定阶段复制# 从命名阶段复制 FROM alpine AS stage1 RUN echo hello /file1.txt FROM alpine AS stage2 RUN echo world /file2.txt FROM alpine # 从不同阶段复制文件 COPY --fromstage1 /file1.txt / COPY --fromstage2 /file2.txt /3.2 从外部镜像复制# 从外部镜像复制文件 FROM alpine:latest # 从官方 nginx 镜像复制配置文件 COPY --fromnginx:latest /etc/nginx/nginx.conf /etc/nginx/nginx.conf # 从本地镜像复制 COPY --frommyapp:builder /app/dist /app/dist3.3 使用构建上下文# 使用构建上下文作为源 FROM alpine # 从构建上下文复制文件 COPY . /src4. 实战示例4.1 Go 应用多阶段构建# Go 应用 FROM golang:1.17-alpine AS builder # 安装 git如果需要 RUN apk add --no-cache git WORKDIR /app # 复制 go mod 文件 COPY go.mod go.sum ./ RUN go mod download # 复制源代码 COPY . . # 编译 RUN CGO_ENABLED0 GOOSlinux GOARCHamd64 go build \ -ldflags-s -w \ -o /app/myapp \ ./cmd/myapp # 运行阶段 FROM scratch # 复制编译好的二进制文件 COPY --frombuilder /app/myapp /myapp # 复制时区信息 COPY --frombuilder /usr/share/zoneinfo /usr/share/zoneinfo # 复制 SSL 证书 COPY --frombuilder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ EXPOSE 8080 ENTRYPOINT [/myapp]4.2 Node.js 多阶段构建# Node.js 应用 # 阶段1依赖安装 FROM node:14-alpine AS deps WORKDIR /app COPY package*.json ./ RUN npm ci --onlyproduction # 阶段2构建 FROM node:14-alpine AS builder WORKDIR /app COPY --fromdeps /app/node_modules ./node_modules COPY . . RUN npm run build # 阶段3生产运行 FROM node:14-alpine RUN addgroup -g 1001 -S nodejs \ adduser -S nodejs -u 1001 WORKDIR /app COPY --frombuilder --chownnodejs:nodejs /app/dist ./dist COPY --frombuilder --chownnodejs:nodejs /app/node_modules ./node_modules COPY --frombuilder --chownnodejs:nodejs /app/package.json ./ USER nodejs EXPOSE 3000 CMD [node, dist/server.js]4.3 Python 多阶段构建# Python 应用 # 阶段1依赖安装 FROM python:3.9-slim AS builder WORKDIR /app COPY requirements.txt ./ RUN pip install --no-cache-dir --user -r requirements.txt # 阶段2运行 FROM python:3.9-slim RUN useradd -m -u 1000 appuser WORKDIR /app # 从构建阶段复制依赖 COPY --frombuilder --chownappuser:appuser /root/.local /home/appuser/.local # 复制应用代码 COPY --chownappuser:appuser . . USER appuser ENV PATH/home/appuser/.local/bin:$PATH EXPOSE 8000 CMD [python, app.py]4.4 Java 多阶段构建# Java 应用 # 阶段1编译 FROM maven:3.8-openjdk-11-slim AS builder WORKDIR /app COPY pom.xml . RUN mvn dependency:go-offline COPY src ./src RUN mvn package -DskipTests # 阶段2运行 FROM openjdk:11-jre-slim RUN addgroup --system --gid 1000 appgroup \ adduser --system --uid 1000 --gid 1000 appuser WORKDIR /app COPY --frombuilder --chownappuser:appgroup /app/target/*.jar app.jar USER appuser EXPOSE 8080 ENTRYPOINT [java, -jar, app.jar]4.5 React 多阶段构建# React 应用 # 阶段1构建 FROM node:14-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # 阶段2Nginx 服务 FROM nginx:alpine # 复制构建产物 COPY --frombuilder /app/build /usr/share/nginx/html # 复制自定义 Nginx 配置 COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 CMD [nginx, -g, daemon off;]5. 高级技巧5.1 停止特定阶段# 只构建到指定阶段dockerbuild--targetbuilder-tmyapp:builder.# 只构建运行阶段dockerbuild--targetruntime-tmyapp:latest.# 多目标构建dockerbuild--targetbuilder-tmyapp:dev.dockerbuild--targetruntime-tmyapp:prod.5.2 并行阶段构建# 启用 BuildKit 自动并行构建exportDOCKER_BUILDKIT1dockerbuild-tmyapp.# 构建图并行处理# 不互相依赖的阶段可以并行执行5.3 使用外部阶段# 引用外部镜像作为阶段 FROM alpine:latest AS base RUN apk add --no-cache curl FROM node:14-alpine # 从外部阶段复制 COPY --frombase /usr/bin/curl /usr/bin/curl6. 体积对比# 单阶段构建 vs 多阶段构建 # 单阶段构建体积~800MB FROM golang:1.17-alpine WORKDIR /app COPY . . RUN go build -o myapp CMD [./myapp] # 多阶段构建体积~10MB FROM golang:1.17-alpine AS builder WORKDIR /app COPY . . RUN go build -o myapp FROM alpine:latest COPY --frombuilder /app/myapp /myapp CMD [/myapp]7. 常见应用场景语言/框架构建阶段运行阶段体积减少Gogolang:alpinealpine/scratch90%Node.jsnode:alpinenode:alpine-slim60%Pythonpython:slimpython:slim50%Javamaven:jdkopenjdk:jre70%Reactnode:alpinenginx:alpine80%8. 最佳实践✅ 推荐做法# 1. 为阶段命名 FROM golang:1.17 AS builder # 2. 使用别名引用 FROM alpine AS runtime COPY --frombuilder /app/bin /app/bin # 3. 清理不需要的文件 RUN go mod download go build -o myapp rm -rf /root/.cache # 4. 使用 .dockerignore # 排除不需要的文件 # 5. 利用构建缓存 # 先复制依赖文件再复制源代码❌ 避免做法# ❌ 在最终阶段包含构建工具 FROM alpine RUN apk add --no-cache gcc make # 不需要 # ❌ 复制整个目录而不是特定文件 COPY --frombuilder /app /app # 包含源码 # ✅ 只复制必要文件 COPY --frombuilder /app/bin/myapp /app/myapp9. 调试技巧# 1. 构建到指定阶段并进入调试dockerbuild--targetbuilder-tmyapp:builder.dockerrun-itmyapp:buildersh# 2. 查看各阶段大小dockerbuild--progressplain.# 3. 使用 dive 分析dive myapp:latest# 4. 保存中间阶段dockerbuild--targetbuilder-tmyapp:cache.10. 常见问题Q1: 多阶段构建可以有多少个阶段理论上无限制但建议不超过 10 个阶段。Q2: 如何重用其他项目的阶段# 从其他项目镜像复制 COPY --fromotherproject:latest /app/bin /app/binQ3: 多阶段构建如何利用缓存# 阶段依赖层级 FROM base AS stage1 # 缓存命中 RUN command1 # 变化导致后续全部失效 FROM stage1 AS stage2 RUN command211. 小结多阶段构建大幅减小镜像体积使用AS为阶段命名使用COPY --fromstage跨阶段复制可以引用外部镜像作为阶段支持--target构建特定阶段不同阶段可并行构建BuildKit适合编译型语言Go、Java、Rust和前端项目运行时阶段应最小化内容

相关文章:

第三部分-Dockerfile与镜像构建——15. 多阶段构建

15. 多阶段构建 1. 多阶段构建概述 多阶段构建是 Docker 17.05 引入的特性,允许在单个 Dockerfile 中使用多个 FROM 语句,每个阶段可以独立构建,最终只选择需要的文件复制到最终镜像中,从而大幅减小镜像体积。 ┌────────…...

AI赋能辐射防护:从智能预测到自主决策的工程实践

1. 项目概述:当AI遇见看不见的风险在核能、医疗、工业探伤乃至太空探索等众多领域,辐射防护是一个关乎生命安全与健康底线的核心议题。传统的辐射防护体系,依赖于物理屏蔽、时间控制、距离管理以及人员剂量监测等经典手段。然而,面…...

AI偏见如何演变为网络安全威胁:大语言模型的蝴蝶效应与防御策略

1. 项目概述:当AI的“偏见”成为攻击者的“弹药”最近和几个做安全研究的老朋友聊天,话题总绕不开大语言模型。大家一边惊叹于它写代码、做摘要的效率,一边又隐隐感到不安——这种不安并非空穴来风。我们讨论的核心,正是“AI偏见”…...

彻底清理Windows右键菜单:ContextMenuManager可视化管理指南

彻底清理Windows右键菜单:ContextMenuManager可视化管理指南 【免费下载链接】ContextMenuManager 🖱️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager 你是否曾为Windows右键菜单的臃肿而烦恼…...

大模型架构拆解:从零件到整体,带你秒懂重复的精密艺术

本文通过拆解大模型架构,阐述了其重复但精密的结构特点。核心内容分为输入层、核心层和输出层三部分,其中核心层由N个标准模块重复堆叠构成,每个模块包含自注意力模块和MLP前馈网络,负责理解语言关系和深化语义。文章强调理解整体…...

大模型+Agent+Skills+MCP,到底啥关系?

一句话总览:大模型是大脑,Agent是带目标的执行者,Skills是可复用技能包,MCP是连接外部世界的标准接口。它们不是竞争,而是分层协作、越绑越紧的关系。一、四个概念,人话版解释概念人话核心能力大模型&#…...

无人搬运平台锂电池包完整设计方案要求【浩博电池】

无人搬运平台(Unmanned Transport Platform)锂电池广泛应用于港口无人运输车、厂区重载运输平台、矿山无人运输系统、智能工厂重型物流底盘、军工无人载重平台以及特种移动机器人底盘系统。该类平台的本质是“可扩展的重载移动能源动力底盘”&#xff0c…...

无人巡检车锂电池包完整设计方案要求【浩博电池】

无人巡检车(Unmanned Inspection Vehicle)锂电池广泛应用于电力线路巡检、变电站巡检、油气管线巡检、轨道交通巡检、园区安防巡逻、矿区巡检以及智慧城市基础设施巡检等场景。 该类车辆的核心特点是“长时间低速运行 多传感器负载 高频数据采集 复杂…...

CANN/ops-transformer密集闪电索引Softmax算子

DenseLightningIndexerSoftmaxLse 【免费下载链接】ops-transformer 本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。 项目地址: https://gitcode.com/cann/ops-transformer 产品支持情况 产品是否支持Ascend 950PR/Ascend 950DTAt…...

从零构建实时聊天应用:WebSocket、Node.js与React全栈实践

1. 项目概述:极简主义聊天应用的精髓最近在GitHub上看到一个名为“TannerMidd/minimal-chat”的项目,光看名字就很有意思。作为一个在前后端领域摸爬滚打多年的开发者,我对“极简”这个词有着复杂的感情。一方面,它代表着清晰、高…...

机器学习高效工作流:ml-retreat深度工作法实战指南

1. 项目概述:当机器学习遇上“静修”最近在GitHub上闲逛,发现了一个挺有意思的项目,叫hesamsheikh/ml-retreat。初看这个标题,你可能会有点摸不着头脑:“ml”是机器学习(Machine Learning)没跑&…...

MySQL-基础篇-函数

函数函数是指一段可以直接被另一段程序调用的程序或代码。字符串函数 MySQL中内置了很多字符串函数,常用的几个如下:- 注意:数据库中使用SUBSTRING时,索引是从1开始的。数值函数 常见的数值函数如下:日期函数 常见的日…...

MySQL-基础篇-SQL

SQL通用语法 1、SQL语句可以单行或多行书写,以分号结尾。2、SQL语句可以使用空格/缩进来增强语句的可读性。3、MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。4、注释: 单行注释:-- 注释内容 或 # 注释内容(MySQL特有&am…...

基于Claude AI的ASO自动化审计:架构、实现与工程实践

1. 项目概述与核心价值最近在AI应用开发圈子里,一个名为“claude-aso-audit-skill”的项目引起了我的注意。这个项目标题直译过来是“Claude ASO审计技能”,乍一看可能有点抽象,但作为一名在移动应用增长和AI工具化领域摸爬滚打了十多年的从业…...

PCIe验证挑战与MVC解决方案解析

1. PCIe验证的挑战与MVC解决方案PCI Express(PCIe)作为现代计算系统中关键的高速串行总线标准,其协议栈的复杂性给验证工作带来了巨大挑战。一个典型的PCIe 3.0设备需要处理的事务类型超过50种,物理层状态机包含20多个状态转换路径…...

Video DownloadHelper CoApp终极指南:从零开始高效下载与转换视频

Video DownloadHelper CoApp终极指南:从零开始高效下载与转换视频 【免费下载链接】vdhcoapp Companion application for Video DownloadHelper browser add-on 项目地址: https://gitcode.com/gh_mirrors/vd/vdhcoapp Video DownloadHelper CoApp是一款功能…...

Python如何下载文件:从基础到进阶的完整指南

在Python中下载文件是一项常见任务,无论是从网页下载图片、文档,还是通过API获取数据,掌握文件下载技术都是开发者的必备技能。本文将系统介绍Python下载文件的多种方法,涵盖基础实现、高级技巧和常见问题解决方案。一、基础方法&…...

Nodejs后端服务如何接入Taotoken多模型API接口

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Node.js 后端服务如何接入 Taotoken 多模型 API 接口 对于 Node.js 后端开发者而言,将大模型能力集成到服务中已成为提…...

CANN/ops-nn CELU激活函数

aclnnCelu&aclnnInplaceCelu 【免费下载链接】ops-nn 本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。 项目地址: https://gitcode.com/cann/ops-nn 📄 查看源码 产品支持情况 产品是否支持Ascend 950PR/Ascend 950DTAt…...

CANN算子库FlashAttention反向梯度计算

aclnnFlashAttentionUnpaddingScoreGrad 【免费下载链接】ops-transformer 本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。 项目地址: https://gitcode.com/cann/ops-transformer 产品支持情况 产品是否支持Ascend 950PR/Ascend 9…...

Linux下Cursor编辑器试用重置脚本原理与风险分析

1. 项目概述与核心思路拆解 最近在折腾Linux下的代码编辑器,Cursor以其深度集成的AI能力确实吸引了不少开发者。但它的免费试用期结束后,弹窗提醒和功能限制就变得有些恼人。网上有不少关于如何“重置”或“延长”其使用状态的讨论,其中一种思…...

基于Alexa技能与无服务器架构的香港地铁实时查询系统开发实战

1. 项目概述与核心价值最近在折腾智能音箱的技能开发,发现一个挺有意思的开源项目:tomfong/hk-mtr-next-train-skill。这是一个为香港地铁(MTR)乘客量身定做的语音技能,让你动动嘴皮子,就能问出下一班车什么…...

AI智能体集成命令行交易:Rust CLI工具与Alpaca API实战指南

1. 项目概述:当AI智能体遇上命令行交易如果你是一名开发者,同时又对股票交易感兴趣,那么你很可能面临一个两难境地:一方面,你享受在终端里敲击命令、用脚本自动化一切的效率与掌控感;另一方面,主…...

CANN/catlass Swizzle策略说明

Swizzle策略说明 【免费下载链接】catlass 本项目是CANN的算子模板库,提供NPU上高性能矩阵乘及其相关融合类算子模板样例。 项目地址: https://gitcode.com/cann/catlass Swizzle策略决定了AI Core计算基本块的顺序。调整Swizzle策略有助于提高缓存命中率、减…...

dotai-cli:AI命令行工具的设计原理与工程实践

1. 项目概述:一个面向开发者的AI命令行工具最近在GitHub上看到一个挺有意思的项目,叫nbslabs/dotai-cli。光看名字,你可能会联想到.env文件或者dotfiles这类开发者常用的配置管理方式,没错,这个项目的核心思路就是把AI…...

CANN/ops-collections昇腾容器库

ops-collections 【免费下载链接】ops-collections ops-collections是基于昇腾硬件的高性能容器模板库,提供运行在NPU上的static_map、dynamic_map、set等容器。利用最新的SIMT并发能力,支持对容器的批量插入、查找等操作,提升整个系统的能力…...

基于Vue 3与Vite的现代化中后台前端解决方案:fast-soy-admin深度解析

1. 项目概述:一个为现代Web应用提速的“脚手架” 最近在折腾一个内部管理系统的重构,前端技术栈选型时,一个绕不开的话题就是“脚手架”。对于有一定规模的团队来说,从零开始配置Webpack、Vite、集成路由、状态管理、UI库、权限、…...

2026株洲AI床垫带来的超绝体验

床垫国标落地,大家都好奇2026年AI床垫能不能带来智能体验。我之前睡眠质量差,换了HEKA黑卡AI智能床垫后,睡眠改善不少,所以很有发言权。HEKA黑卡研发10年,内置230万组睡眠数据库,精准度有保障。它家成人床垫…...

基于Mirai与Spring Boot的QQ机器人开发实战:从零构建PCR公会战管理工具

1. 项目缘起与重生之路 作为一个在QQ机器人圈子里摸爬滚打了快十年的老玩家,我见证过不少框架的兴起与沉寂。最早自己捣鼓着用酷Q和PicqBotX框架,整合Spring写了个叫WMagicBot的小玩意儿,纯粹是自娱自乐。后来酷Q一夜之间停止服务&#xff0…...

GitHub仓库模板:现代软件项目的标准化起点与自动化实践

1. 项目概述:一个现代软件项目的“基因蓝图” 在软件开发的日常里,我们总会遇到一些重复性的“仪式感”工作:新建一个仓库,然后开始配置 .gitignore 、 README.md 、 LICENSE 、CI/CD流水线、代码规范检查工具……这些工作…...