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

Docker 镜像构建的最佳做法

一、镜像分层

使用docker image history命令,可以看到用于在镜像中创建每个层的命令。

 1、 使用docker image history命令查看创建的入门镜像中的层。

docker image history getting-started

您应该得到如下所示的输出:

IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
a78a40cbf866        18 seconds ago      /bin/sh -c #(nop)  CMD ["node" "src/index.j⦠   0B                  
f1d1808565d6        19 seconds ago      /bin/sh -c yarn install --production            85.4MB              
a2c054d14948        36 seconds ago      /bin/sh -c #(nop) COPY dir:5dc710ad87c789593⦠  198kB               
9577ae713121        37 seconds ago      /bin/sh -c #(nop) WORKDIR /app                  0B                  
b95baba1cfdb        13 days ago         /bin/sh -c #(nop)  CMD ["node"]                 0B                  
<missing>           13 days ago         /bin/sh -c #(nop)  ENTRYPOINT ["docker-entry⦠  0B                  
<missing>           13 days ago         /bin/sh -c #(nop) COPY file:238737301d473041⦠  116B                
<missing>           13 days ago         /bin/sh -c apk add --no-cache --virtual .bui⦠  5.35MB              
<missing>           13 days ago         /bin/sh -c #(nop)  ENV YARN_VERSION=1.21.1      0B                  
<missing>           13 days ago         /bin/sh -c addgroup -g 1000 node     && addu⦠  74.3MB              
<missing>           13 days ago         /bin/sh -c #(nop)  ENV NODE_VERSION=12.14.1     0B                  
<missing>           13 days ago         /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B                  
<missing>           13 days ago         /bin/sh -c #(nop) ADD file:e69d441d729412d24⦠  5.59MB   

每条线表示镜像中的一个层。此处的显示在底部显示底部,最新层在顶部。使用此选项,您还可以快速查看每个层的大小,帮助诊断大型镜像。

2、您将注意到有几行被截断。如果添加--no trunc标志,则将获得完整的输出。

docker image history --no-trunc getting-started

二、图层缓存

现在您已经看到了分层的作用,有一个重要的教训需要学习,以帮助减少容器映像的构建时间。一旦层更改,也必须重新创建所有下游层。
请查看您为入门应用程序创建的以下Dockerfile。

# syntax=docker/dockerfile:1
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]

回到镜像历史记录输出,您会看到Dockerfile中的每个命令都成为镜像中的新层。您可能记得,当您对镜像进行更改时,必须重新安装纱线依赖项。每次构建时都围绕相同的依赖项进行交付是没有多大意义的。
要修复它,您需要重新构造Dockerfile,以帮助支持依赖项的缓存。对于基于节点的应用程序,这些依赖项在package.json文件中定义。您可以首先只复制该文件,安装依赖项,然后复制其他所有文件。然后,只有在package.json发生更改时,才重新创建纱线依赖项。

1、更新Dockerfile以首先在package.json中复制,安装依赖项,然后复制中的所有其他内容。

# syntax=docker/dockerfile:1
FROM node:18-alpine
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --production
COPY . .
CMD ["node", "src/index.js"]

2、在与Dockerfile相同的文件夹中创建一个名为.dockerignore的文件,其中包含以下内容。
node_modules
.dockerignore文件是一种简单的方法,可以选择性地仅复制与映像相关的文件。你可以在这里关于这方面的内容。在这种情况下,应该在第二个COPY步骤中省略node_modules文件夹,因为否则,它可能会覆盖由RUN步骤中的命令创建的文件。
3、使用docker Build构建新镜像。

docker build -t getting-started .

您应该看到如下输出。

[+] Building 16.1s (10/10) FINISHED
=> [internal] load build definition from Dockerfile
=> => transferring dockerfile: 175B
=> [internal] load .dockerignore
=> => transferring context: 2B
=> [internal] load metadata for docker.io/library/node:18-alpine
=> [internal] load build context
=> => transferring context: 53.37MB
=> [1/5] FROM docker.io/library/node:18-alpine
=> CACHED [2/5] WORKDIR /app
=> [3/5] COPY package.json yarn.lock ./
=> [4/5] RUN yarn install --production
=> [5/5] COPY . .
=> exporting to image
=> => exporting layers
=> => writing image     sha256:d6f819013566c54c50124ed94d5e66c452325327217f4f04399b45f94e37d25
=> => naming to docker.io/library/getting-started

4、现在,对src/static/index.html文件进行更改。例如,将<title>更改为“the Awesome Todo App”。
5、现在使用Docker Build-t getting started构建Docker镜像。再次。这一次,您的输出应该看起来有点不同。

[+] Building 1.2s (10/10) FINISHED
=> [internal] load build definition from Dockerfile
=> => transferring dockerfile: 37B
=> [internal] load .dockerignore
=> => transferring context: 2B
=> [internal] load metadata for docker.io/library/node:18-alpine
=> [internal] load build context
=> => transferring context: 450.43kB
=> [1/5] FROM docker.io/library/node:18-alpine
=> CACHED [2/5] WORKDIR /app
=> CACHED [3/5] COPY package.json yarn.lock ./
=> CACHED [4/5] RUN yarn install --production
=> [5/5] COPY . .
=> exporting to image
=> => exporting layers
=> => writing image     sha256:91790c87bcb096a83c2bd4eb512bc8b134c757cda0bdee4038187f98148e2eda
=> => naming to docker.io/library/getting-started

首先,您应该注意到构建速度快得多。并且,您将看到几个步骤正在使用以前缓存的层。推拉此镜像以及对其的更新也将快得多。

三、多阶段构建

多阶段构建是一个非常强大的工具,可以帮助使用多个阶段来创建镜像。它们有几个优点:

  • 将构建时依赖项与运行时依赖项分离
  • 通过仅传送应用程序运行所需的内容来减少总体镜像大小

1、Maven/Tomcat示例

在构建基于Java的应用程序时,需要JDK将源代码编译为Java字节码。然而,生产中不需要JDK。此外,您可能正在使用Maven或Gradle等工具来帮助构建应用程序。在最终的镜像中也不需要这些。多阶段构建帮助。 

# syntax=docker/dockerfile:1
FROM maven AS build
WORKDIR /app
COPY . .
RUN mvn packageFROM tomcat
COPY --from=build /app/target/file.war /usr/local/tomcat/webapps 

在这个例子中,您使用一个阶段(称为构建)来使用Maven执行实际的Java构建。在第二个阶段(从FROM tomcat开始),从构建阶段复制文件。最终镜像只是正在创建的最后一个阶段,可以使用--target标志覆盖它。

2、React示例

在构建React应用程序时,需要一个Node环境来将JS代码(通常是JSX)、SASS样式表等编译为静态HTML、JS和CSS。如果不进行服务器端渲染,则生产构建甚至不需要节点环境。您可以在静态nginx容器中运送静态资源。

# syntax=docker/dockerfile:1
FROM node:18 AS build
WORKDIR /app
COPY package* yarn.lock ./
RUN yarn install
COPY public ./public
COPY src ./src
RUN yarn run buildFROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html

在前面的Dockerfile示例中,它使用node:18镜像执行构建(最大化层缓存),然后将输出复制到nginx容器中。

相关文章:

Docker 镜像构建的最佳做法

一、镜像分层 使用docker image history命令&#xff0c;可以看到用于在镜像中创建每个层的命令。 1、 使用docker image history命令查看创建的入门镜像中的层。 docker image history getting-started 您应该得到如下所示的输出&#xff1a; IMAGE CREATED…...

工作上Redis安装及配置

下载redis软件 第一步&#xff1a;解压压缩包 tar -zxvf redis-7.0.14.tar.gz 第二步&#xff1a;移动redis存放目录&#xff08;结合个人需求而定&#xff01;&#xff09; redis-7.0.14&#xff1a;解压后的文件路径 /usr/local&#xff1a;移动后的文件路径 mv redis-7.0.…...

电商项目之Web实时消息推送(附源码)

文章目录 1 问题背景2 前言3 什么是消息推送4 短轮询5 长轮询5.1 demo代码 6 iframe流6.1 demo代码 7 SSE7.1 demo代码7.2 生产环境的应用 &#xff08;重要&#xff09; 8 MQTT 1 问题背景 扩宽自己的知识广度&#xff0c;研究一下web实时消息推送 2 前言 文章参考自Web 实时消…...

上机实验四 哈希表设计 西安石油大学数据结构

实验名称&#xff1a;哈希表设计 &#xff08;1&#xff09;实验目的&#xff1a;掌握哈希表的设计方法及其冲突解决方法。 &#xff08;2&#xff09;主要内容&#xff1a; 已知一个含有10个学生信息的数据表&#xff0c;关键字为学生“姓名”的拼音&#xff0c;给出此表的一…...

Ubuntu22.04 交叉编译mp4V2 for Rv1106

一、配置工具链环境 sudo vim ~/.bashrc在文件最后添加 export PATH$PATH:/opt/arm-rockchip830-linux-uclibcgnueabihf/bin 保存&#xff0c;重启机器 二、下载mp4v2 下载路径&#xff1a;MP4v2 | mp4v2 三、修改CMakeLists.txt 四、执行编译 mkdir build cd buildcmak…...

缓存穿透、击穿、雪崩

缓存穿透&#xff1a; 指的是恶意用户或攻击者通过请求不存在于缓存和后端存储中的数据来使得所有请求都落到后端存储上&#xff0c;导致系统瘫痪。 解决方案&#xff1a; 通常包括使用布隆过滤器或者黑白名单等方式来过滤掉无效请求&#xff0c;以及在应用程序中加入缓存预热…...

(1w字一篇理解透Unsafe类)Java魔法类:Unsafe详解

Java魔法类 Unsafe 文章导读&#xff1a;(约12015字&#xff0c;阅读时间大约1小时)1. Unsafe介绍2. Unsafe创建3. Unsafe功能3.1内存操作3.2 内存屏障3.3 对象操作3.4 数组操作3.5 CAS操作3.6 线程调度3.7 Class操作3.8 系统信息 4. 总结 JUC源码中的并发工具类出现过很多次 …...

Python的正则表达式使用

Python的正则表达式使用 定义使用场景查替换分割 常用的正则表达符号查原字符英文状态的句号点 .反斜杠 \英文的[]英文的()英文的?加号 星号 *英文状态的大括号 {} 案例 定义 正则表达式是指专门用于描述或刻画字符串内在规律的表达式。 使用场景 无法通过切片&#xff0c;…...

Elasticsearch:评估 RAG - 指标之旅

作者&#xff1a;Quentin Herreros&#xff0c;Thomas Veasey&#xff0c;Thanos Papaoikonomou 2020年&#xff0c;Meta发表了一篇题为 “知识密集型NLP任务的检索增强生成” 的论文。 本文介绍了一种通过利用外部数据库将语言模型 (LLM) 知识扩展到初始训练数据之外的方法。 …...

【2023.12.4练习】数据库知识点复习测试

概论 数据表&#xff1a;用于存储现实中数据的联系。 储存信息联系。 字段&#xff1a;又称列&#xff0c;如姓名、年龄、编号等。 记录&#xff1a;又称元组&#xff0c;为数据表中的一行&#xff0c;代表了一个实体的信息。 数据库&#xff08;DB&#xff09;&#xff1…...

【wvp】测试记录

ffmpeg 这是个莫名其妙的报错&#xff0c;通过排查&#xff0c;应该是zlm哪个进程引起的 会议室的性能 网络IO也就20M...

【若依框架实现上传文件组件】

若依框架中只有个人中心有上传图片组件&#xff0c;但是这个组件不适用于el-dialog中的el-form表单页面 于是通过elementui重新写了一个上传组件&#xff0c;如图是实现效果 vue代码 <el-dialog :title"title" v-model"find" width"600px"…...

玩转大数据5:构建可扩展的大数据架构

1. 引言 随着数字化时代的到来&#xff0c;大数据已经成为企业、组织和个人关注的焦点。大数据架构作为大数据应用的核心组成部分&#xff0c;对于企业的数字化转型和信息化建设至关重要。我们将探讨大数据架构的基本要素和原则&#xff0c;以及Java在大数据架构中的角色&…...

【华为数据之道学习笔记】非数字原生企业的特点

非数字原生企业的数字化转型挑战 软件和数据平台为核心的数字世界入口&#xff0c;便捷地获取和存储了大量的数据&#xff0c;并开始尝试通过机器学习等人工智能技术分析这些数据&#xff0c;以便更好地理解用户需求&#xff0c;增强数字化创新能力。部分数字原生企业引领着云计…...

Kubernetes学习笔记-Part.01 Kubernets与docker

目录 Part.01 Kubernets与docker Part.02 Docker版本 Part.03 Kubernetes原理 Part.04 资源规划 Part.05 基础环境准备 Part.06 Docker安装 Part.07 Harbor搭建 Part.08 K8s环境安装 Part.09 K8s集群构建 Part.10 容器回退 第一章 Kubernets与docker Docker是一种轻量级的容器…...

k8s学习

文章目录 前言一、k8s部署方式二、学习k8s的方式今天主要配置k8s环境的方式今天遇到的是一个在k8s进行初始化的方式&#xff0c;但是发现k8s不能正常初始化总是出现错误&#xff0c;或者在错误中有问题的方式&#xff0c;在网上查询挺多资料需要重新启动kub文件&#xff0c;删除…...

测试:JMeter和LoadRunner比较

比较 JMeter和LoadRunner是两款常用的软件性能测试工具&#xff0c;它们在功能和性能上有一定的相似性和差异。下面从几个方面对它们进行比较&#xff1a; 1. 架构和原理&#xff1a; JMeter和LoadRunner的架构和原理基本相同&#xff0c;都是通过中间代理监控和收集并发客户…...

(C语言)通过循环按行顺序为一个矩阵赋予1,3,5,7,9,等奇数,然后输出矩阵左下角的值。

#include<stdio.h> int main() {int a[5][5];int n 1;for(int i 0;i < 5;i ){for(int j 0;j < 5;j ){a[i][j] n;n 2;}}for(int i 0;i < 5;i ){for(int j 0;j < i;j )printf("%-5d",a[i][j]);printf("\n");}return 0; } 运行截图…...

GitHub项目推荐-Deoldify

有小伙伴推荐了一个老照片上色的GitHub项目&#xff0c;看了简介&#xff0c;还不错&#xff0c;推荐给大家。 项目地址 GitHub - SpenserCai/sd-webui-deoldify: DeOldify for Stable Diffusion WebUI&#xff1a;This is an extension for StableDiffusions AUTOMATIC1111 w…...

微前端qiankun示例 Umi3.5

主应用配置&#xff08;基座&#xff09; 安装包 npm i umijs/plugin-qiankun -D 配置 qiankun 开启 {"private": true,"scripts": {"start": "umi dev","build": "umi build","postinstall": "…...

离散数学自然推理系统通关秘籍:从零开始手把手教你搞定Educoder所有证明题

离散数学自然推理系统通关秘籍&#xff1a;从零到精通的实战指南 1. 自然推理系统入门基础 对于初次接触离散数学自然推理系统的学习者来说&#xff0c;那些复杂的符号和规则往往让人望而生畏。但请记住&#xff0c;每个专家都曾是初学者。自然推理系统本质上是一种形式化的逻…...

终极指南:SSDD数据集在SAR舰船检测中的完整应用方案

终极指南&#xff1a;SSDD数据集在SAR舰船检测中的完整应用方案 【免费下载链接】Official-SSDD SAR Ship Detection Dataset (SSDD): Official Release and Comprehensive Data Analysis 项目地址: https://gitcode.com/gh_mirrors/of/Official-SSDD SSDD&#xff08;S…...

打通飞书与GitLab:基于Webhook的事件通知与精准@实践指南

1. 为什么需要打通飞书与GitLab的通知系统 在软件开发团队中&#xff0c;代码仓库的每一次变更都可能影响整个项目进度。传统的做法是开发人员手动在群里相关同事&#xff0c;或者依赖邮件通知&#xff0c;这种方式效率低下且容易遗漏重要信息。我曾经参与过一个跨时区协作项目…...

终极指南:如何在Windows电脑上免模拟器安装安卓APK文件

终极指南&#xff1a;如何在Windows电脑上免模拟器安装安卓APK文件 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer APK安装器是Windows用户的游戏规则改变者&#xff0…...

别再手动画封装了!用UltraLibrarian和3D ContentCentral搞定AD/Altium Designer的3D模型(附避坑技巧)

高效获取Altium Designer封装与3D模型的终极指南 在PCB设计领域&#xff0c;封装获取一直是工程师们日常工作中最耗时却又必不可少的环节。想象一下&#xff0c;当你正全神贯注于一个复杂的电路设计&#xff0c;突然发现某个关键元器件没有现成的封装可用&#xff0c;不得不停…...

长期项目使用Taotoken聚合API在稳定性与成本上的综合感受

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 长期项目使用Taotoken聚合API在稳定性与成本上的综合感受 在最近一个持续数月的实际开发项目中&#xff0c;我们选择将Taotoken作为…...

为什么你的Perplexity本地服务响应慢3.7倍?:NVIDIA驱动版本、vLLM推理后端与量化精度的隐性博弈

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;Perplexity本地服务查询 Perplexity 作为一款强调实时信息检索与引用溯源的 AI 工具&#xff0c;其官方未提供公开的本地化部署方案。但开发者可通过构建轻量级代理服务&#xff0c;将本地运行的大语言模型&a…...

meituan 民宿 mtgsig1.2

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;逆向分析cp execjs.compile(open(民宿-…...

从零到部署:在Linux服务器上用Python搭建并调用WPS地理处理服务

从零到部署&#xff1a;在Linux服务器上用Python搭建并调用WPS地理处理服务 当遥感影像分析遇上自动化处理流程&#xff0c;地理信息系统&#xff08;GIS&#xff09;开发者常面临一个关键挑战&#xff1a;如何将复杂的空间运算封装成可远程调用的标准化服务&#xff1f;这正是…...

云深处冲刺科创板:年营收3.4亿,净利2868万 拟募资25亿 又一杭州6小龙拟IPO

雷递网 雷建平 5月19日杭州云深处科技股份有限公司&#xff08;简称&#xff1a;“云深处”&#xff09;日前递交招股书&#xff0c;准备在科创板上市。云深处计划募资25亿元&#xff0c;其中&#xff0c;11.7亿元用于具身算法及模型研发项目&#xff0c;5.54亿用于机器人本体与…...