我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Docker多阶段构建最佳实践

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Docker多阶段构建最佳实践


Docker目前在容器市场可以说是占领了大部分市场,Docker掀起了容器革命,同时也改变了现代化云平台的构建方式。尽管Docker很强大,但使用过程当中也遇到了一些问题。比如说我想要构建一个编译型语言镜像,需要先在一个Dockerfile中编译,然后再使用另外一个Dockerfile把编译好的文件放到镜像中。这样无形当中就增大了CI/CD的复杂度。

Docker多阶段构建是17.05以后引入的新特性,旨在解决编译和构建复杂的问题。减小镜像大小。因此要使用多阶段构建特性必须使用高于或等于17.05的Docker。

多阶段构建出现之前

构建镜像最具挑战性的一点是使镜像大小尽可能的小。Dockerfile中的每条指令都为图像添加了一个图层,您需要记住在移动到下一层之前清理任何不需要的工件。

为了编写一个真正高效的Dockerfile,传统上需要使用shell技巧和其他逻辑来保持层尽可能小,并确保每个层都具有前一层所需的工件而不是其他任何东西。

实际上,有一个Dockerfile用于开发(包含构建应用程序所需的所有内容),以及用于生产环境的精简版Dockerfile,它只包含您的应用程序以及运行它所需的内容。这被称为“建造者模式”。维护两个Dockerfiles并不理想。

这是一个Dockerfile.build和Dockerfile的例子,它遵循上面的模式:

Dockerfile.build:

FROM golang:1.7.3
WORKDIR /go/class="lazy" data-src/github.com/alexellis/href-counter/
COPY app.go .
RUN go get -d -v golang.org/x/net/html \
  && CGO_ENABLED= GOOS=linux go build -a -installsuffix cgo -o app .

请注意,此示例使用Bash &&运算符人为压缩两个RUN命令,以避免在image中创建其他层。这很容易出错并且难以维护。

Dockerfile:

FROM alpine:latest 
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY app .
CMD ["./app"]

build.sh:

#!/bin/sh
echo Building alexellis2/href-counter:build
docker build --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy \ 
    -t alexellis2/href-counter:build . -f Dockerfile.build
docker container create --name extract alexellis2/href-counter:build 
docker container cp extract:/go/class="lazy" data-src/github.com/alexellis/href-counter/app ./app 
docker container rm -f extract
echo Building alexellis2/href-counter:latest
docker build --no-cache -t alexellis2/href-counter:latest .
rm ./app

当您运行build.sh脚本时,它需要构建第一个image,从中创建容器以复制工件,然后构建第二个image。

多阶段构建大大简化了这种情况!

使用多阶段构建

对于多阶段构建,您可以在Dockerfile中使用多个FROM语句。每个FROM指令可以使用不同的基础,并且每个指令都开始一个新的构建。您可以选择性地将工件从一个阶段复制到另一个阶段,从而在最终image中只留下您想要的内容。

为了说明这是如何工作的,让我们调整上述示例的Dockerfile以使用多阶段构建。

Dockerfile:

FROM golang:1.7.3
WORKDIR /go/class="lazy" data-src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html 
COPY app.go .
RUN CGO_ENABLED= GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest 
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from= /go/class="lazy" data-src/github.com/alexellis/href-counter/app .
CMD ["./app"]
您只需要单个Dockerfile。您也不需要单独的构建脚本。只需运行docker build:
$ docker build -t app:latest .

最终结果是产生与之前相同大小的image,复杂性显著降低。您不需要创建任何中间image,也不需要将任何artifacts提取到本地系统。

它是如何工作的?第二个FROM指令以alpine:latest image为基础开始一个新的构建阶段。

COPY –from = 0行仅将前一阶段的构建文件复制到此新阶段。Go SDK和任何中间层都被遗忘,而不是保存在最终image中。

为多构建阶段命名

默认情况下,阶段未命名,您可以通过整数来引用它们,从第0个FROM指令开始。

但是,您可以通过向FROM指令添加as NAME来命名您的阶段。此示例通过命名阶段并使用COPY指令中的名称来改进前一个示例。

这意味着即使稍后重新排序Dockerfile中的指令,COPY也不会中断。

FROM golang:1.7.3 as builder
WORKDIR /go/class="lazy" data-src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html 
COPY app.go    .
RUN CGO_ENABLED= GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest 
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/class="lazy" data-src/github.com/alexellis/href-counter/app .
CMD ["./app"]

停在特定的构建阶段

构建映像时,不一定需要构建整个Dockerfile每个阶段。

可以指定目标构建阶段。以下命令假定您使用的是以前的Dockerfile,但在名为builder的阶段停止:

$ docker build --target builder -t alexellis2/href-counter:latest .

使用此功能可能的一些非常适合的场景是:

◾调试特定的构建阶段
◾在debug阶段,启用所有调试或工具,而在production阶段尽量精简
◾在testing阶段,您的应用程序将填充测试数据,但在production阶段则使用生产数据

使用外部镜像作为stage

使用多阶段构建时,您不仅可以从Dockerfile中创建的镜像中进行复制。

您还可以使用COPY –from指令从单独的image中复制,使用本地image名称,本地或Docker注册表中可用的标记或标记ID。

如有必要,Docker会提取image并从那里开始复制。

语法是:

COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf

原文链接:https://wilhelmguo.tk/blog/post/william/Docker构建之多阶段构建


 

 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Docker多阶段构建最佳实践

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Docker多阶段构建最佳实践

Docker目前在容器市场可以说是占领了大部分市场,Docker掀起了容器革命,同时也改变了现代化云平台的构建方式。尽管Docker很强大,但使用过程当中也遇到了一些问题。比如说我想要构建一个编译型语言镜像,需要先在一个Dockerfile
2023-06-03

Docker多阶段镜像构建的实现方法

小编给大家分享一下Docker多阶段镜像构建的实现方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!从Docker版本 17.05.0-ce 开始,就支持了一种新
2023-06-07

多级树形分类存储结构最佳实践

TreeOne 一个适用性功能性极佳的多层级树型数据库存储结构设计模型最佳实践,可广泛用于项目开发任务中。 (以下示例环境默认均为MySQL) 表的字段数据结构 CREATE TABLE `tree` ( `id` int(11) NOT NULL, `
多级树形分类存储结构最佳实践
2016-10-09

无法使用 docker 多阶段构建执行 go 二进制文件

问题内容我尝试按如下方式构建 go 应用程序,我的 main.go 文件位于 cmd/app/main.go。但是,当我尝试运行 docker build --no-cache . 和 docker 运行 时。它给了我 exec .
无法使用 docker 多阶段构建执行 go 二进制文件
2024-02-06

Node.js WebSocket 的最佳实践:构建可靠的实时系统

构建可靠的 Node.js WebSocket 实时系统最佳实践
Node.js WebSocket 的最佳实践:构建可靠的实时系统
2024-03-12

Java建造者模式构建复杂对象的最佳实践

建造者模式,是一种对象构建模式 它可以将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同表现的对象。本文将通过示例讲解建造者模式,需要的可以参考一下
2023-05-18

使用 C++ 构建高性能服务器架构的最佳实践

遵循 c++++ 中构建高性能服务器架构的最佳实践可以创建可扩展、可靠且可维护的系统:使用线程池以重用线程,提高性能。利用协程减少上下文切换和内存开销,提升性能。通过智能指针和引用计数优化内存管理,避免内存泄漏和性能瓶颈。选择哈希表、数组和
使用 C++ 构建高性能服务器架构的最佳实践
2024-05-14

Docker中Dockerfile多阶段构建原理及使用场景的示例分析

小编给大家分享一下Docker中Dockerfile多阶段构建原理及使用场景的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!老版本Docker中为什么不支持多个 FROM 指令在17.05版本之前的Docker,只
2023-06-04

C++ 函数异常最佳实践:构建健壮的应用

c++++ 函数异常处理最佳实践包括:定义明确可层次的异常,使用异常规范强制编译时错误处理,通过 try-catch 块恰当处理异常,避免重复异常处理,遵循 raii 原则,以及不要掩盖异常,从而确保应用程序的健壮性。C++ 函数异常最佳实
C++ 函数异常最佳实践:构建健壮的应用
2024-05-03

构建安全的Web接口:Linux服务器的最佳实践

在Linux服务器上构建安全的Web接口至关重要。这篇指南提供了全面的最佳实践,涵盖操作系统、Web服务器、应用程序、数据库和一般安全措施。从定期更新到启用防火墙,从安全编程到加密数据,这些实践可最大限度地减少安全漏洞,保护服务器免受攻击和数据泄露。确保遵循这些指南并定期进行安全审计,以维护一个安全可靠的Web环境。
构建安全的Web接口:Linux服务器的最佳实践
2024-04-09

用PHP构建IP代理服务器的最佳实践指南

在网络数据传输中,IP代理服务器扮演着重要的角色,能够帮助用户隐藏真实IP地址,保护隐私、提升访问速度等。在本篇文章中,将介绍如何用PHP构建IP代理服务器的最佳实践指南,并提供具体的代码示例。什么是IP代理服务器?IP代理服务器是一种
用PHP构建IP代理服务器的最佳实践指南
2024-03-11

聊聊UniApp构建一个项目的流程和最佳实践

最近,UniApp作为一种跨平台开发框架,备受开发者青睐,被广泛应用到了App的开发中。UniApp是由DCloud团队推出的一款基于Vue.js框架和微信小程序语法的跨平台应用开发框架,开发者可以使用它开发出同时支持Android、iOS、H5和小程序等多个平台的应用。本文介绍UniApp构建一个项目的流程、注意点以及最佳实践。## 环境搭建1. 下载并安装HBuilderX
2023-05-14

构建安全的Web接口:Linux服务器的最佳实践

构建安全的Web接口是保护Web服务器和用户数据的关键。以下是在Linux服务器上实施的一些最佳实践:1. 使用防火墙:在服务器上配置防火墙以限制对Web接口的访问。只允许必要的端口打开,如80(HTTP)和443(HTTPS),并禁止不必
2023-10-18

构建安全的Linux服务器环境:最佳实践和技巧

构建安全的Linux服务器环境:最佳实践和技巧构建一个安全的Linux服务器环境需要采取全面的方法。通过实施以下最佳实践,管理员可以保护他们的服务器免受威胁,包括:身份和访问管理:使用强密码、两因素身份验证和权限最小化。防火墙和入侵检测:使用防火墙限制访问、部署IDS/IPS,并使用故障安全机制。软件更新和补丁:及时应用安全补丁,并使用版本控制进行跟踪。日志记录和监控:启用日志记录、集中管理日志,并实时监控服务器健康状况。网络安全:使用加密、部署WAF,并执行漏洞扫描。物理安全:限制物理访问、使用安全系统
构建安全的Linux服务器环境:最佳实践和技巧
2024-04-09

构建安全的Linux服务器环境:最佳实践和技巧

构建安全的Linux服务器环境是确保服务器数据和系统的完整性、机密性和可用性的关键步骤。下面是一些最佳实践和技巧,可帮助您构建安全的Linux服务器环境:1. 更新和维护系统:定期更新操作系统和软件包,以获取最新的安全补丁和修复程序。使用合
2023-10-18

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录