深入解析Multi-stage构建多阶段镜像

一、Multi-stage概述

Multi-stage是Docker自17.05版本引入的新特性。它允许在一个Dockerfile中定义多个镜像构建阶段,并针对当前阶段选择不同的基础镜像,从而减小镜像大小,提高构建效率。

Multi-stage的实现依赖于Docker buildkit,可以通过设置DOCKER_BUILDKIT环境变量来启用。另外需要注意的是,Multi-stage对镜像的命名并无强制要求,可以根据需求任意命名。

二、基础用法

Multi-stage最基础的用法就是使用多个FROM语句定义多个阶段,比如以下例子:

FROM golang:1.15 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine
COPY --from=builder /app/app .
CMD ["./app"]

这个Dockerfile定义了两个阶段,第一个阶段使用golang:1.15镜像作为基础镜像,将当前目录下的所有文件复制到/app目录下,然后使用go build构建应用程序。第二个阶段使用alpine镜像作为基础镜像,只包含Glibc运行库和基础命令,将第一个阶段构建的应用程序复制到当前目录,并设置启动命令为”./app”。

三、多阶段链式调用

Multi-stage还可以链式调用,将一个阶段的输出作为下一个阶段的输入,从而实现更复杂的构建过程。下面是一个简单的例子:

FROM golang:1.15 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM scratch
COPY --from=builder /app/app .
ENTRYPOINT ["/app"]

这个Dockerfile定义了两个阶段,第一个阶段与之前的例子相同,第二个阶段使用scratch空镜像作为基础镜像,意味着只包含一个空白文件系统。将第一个阶段构建的应用程序复制到当前目录下,设置启动命令为”/app”。

四、减少镜像大小

Multi-stage可以帮助我们减小镜像大小,在构建应用程序的时候只保留必要的文件和运行时依赖库,避免不必要的文件和依赖导致镜像体积过大。

以Node.js应用为例,我们可以只保留应用程序和运行所需的依赖库,而不包含npm包管理器和应用的开发依赖库。下面是一个示例Dockerfile:

FROM node:14.16 AS build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM node:14.16-alpine
WORKDIR /app
COPY --from=build-stage /app/dist ./dist
COPY package*.json ./
RUN npm install --production
CMD ["npm", "run", "start"]

这个Dockerfile定义了两个阶段,第一个阶段使用node:14.16镜像作为基础镜像,安装应用程序的开发依赖库,构建应用程序。第二个阶段使用node:14.16-alpine镜像作为基础镜像,只包含Node.js运行时依赖库和基础命令,将第一个阶段构建的应用程序复制到当前目录下的dist目录,并安装生产依赖库,设置启动命令为”npm run start”。

五、交叉编译

Multi-stage还可以用于交叉编译应用程序,比如将应用程序编译为不同平台的二进制文件。下面是一个简单的例子:

FROM golang:1.15 AS builder
WORKDIR /app
COPY . .
RUN GOOS=linux GOARCH=amd64 go build -o app-linux-amd64 .
RUN GOOS=windows GOARCH=amd64 go build -o app-windows-amd64.exe .

FROM scratch
COPY --from=builder /app/app-linux-amd64 .
ENTRYPOINT ["/app-linux-amd64"]

这个Dockerfile定义了两个阶段,第一个阶段使用golang:1.15镜像作为基础镜像,将当前目录下的所有文件复制到/app目录下,分别使用GOOS和GOARCH环境变量交叉编译应用程序为Linux和Windows平台,输出两个二进制文件。

六、小结

Multi-stage是Docker非常实用的一个特性,可以帮助我们优化Docker镜像构建过程、减小镜像大小、提高构建效率。通过本文介绍的几个例子,相信大家已经掌握了Multi-stage的基础用法及更多高级用法,希望可以对大家的Docker实践有所帮助。

原创文章,作者:RXSLR,如若转载,请注明出处:https://www.506064.com/n/363836.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
RXSLRRXSLR
上一篇 2025-03-12 18:48
下一篇 2025-03-12 18:48

相关推荐

  • Python清华镜像下载

    Python清华镜像是一个高质量的Python开发资源镜像站,提供了Python及其相关的开发工具、框架和文档的下载服务。本文将从以下几个方面对Python清华镜像下载进行详细的阐…

    编程 2025-04-29
  • 现在镜像站不行了,怎么办?

    现在镜像站不行了是很常见的问题,本文将从多个方面对此问题进行详细阐述,为大家提供解决方案。 一、检查网络环境 镜像站不通常见的原因之一是网络问题,可能是个人网络不稳定,也可能是IS…

    编程 2025-04-29
  • 如何在Python中配置国内镜像源

    如果你使用Python进行开发,那么肯定会遇到下载模块或库速度慢的情况。这时,我们就可以配置国内镜像源来解决这一问题。本文将会从多个方面来介绍如何配置国内镜像源。 一、pip配置国…

    编程 2025-04-27
  • 深入解析Vue3 defineExpose

    Vue 3在开发过程中引入了新的API `defineExpose`。在以前的版本中,我们经常使用 `$attrs` 和` $listeners` 实现父组件与子组件之间的通信,但…

    编程 2025-04-25
  • 深入理解byte转int

    一、字节与比特 在讨论byte转int之前,我们需要了解字节和比特的概念。字节是计算机存储单位的一种,通常表示8个比特(bit),即1字节=8比特。比特是计算机中最小的数据单位,是…

    编程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什么是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一个内置小部件,它可以监测数据流(Stream)中数据的变…

    编程 2025-04-25
  • 深入探讨OpenCV版本

    OpenCV是一个用于计算机视觉应用程序的开源库。它是由英特尔公司创建的,现已由Willow Garage管理。OpenCV旨在提供一个易于使用的计算机视觉和机器学习基础架构,以实…

    编程 2025-04-25
  • 深入了解scala-maven-plugin

    一、简介 Scala-maven-plugin 是一个创造和管理 Scala 项目的maven插件,它可以自动生成基本项目结构、依赖配置、Scala文件等。使用它可以使我们专注于代…

    编程 2025-04-25
  • 深入了解LaTeX的脚注(latexfootnote)

    一、基本介绍 LaTeX作为一种排版软件,具有各种各样的功能,其中脚注(footnote)是一个十分重要的功能之一。在LaTeX中,脚注是用命令latexfootnote来实现的。…

    编程 2025-04-25
  • Docker镜像管理

    一、查看所有镜像 使用docker命令可以很轻松地查看所有已经构建好的镜像,命令如下: docker images 该命令将列出所有本地docker主机上所有的镜像: REPOSI…

    编程 2025-04-25

发表回复

登录后才能评论