Dockerfile 指令的最佳实践

这些建议旨在帮助您创建一个高效且可维护的Dockerfile。

一、FROM

尽可能使用当前的官方镜像作为镜像的基础。Docker推荐Alpine镜像,因为它受到严格控制,体积小(目前不到6 MB),同时仍然是一个完整的Linux发行版。


FROM [--platform=<platform>] <image> [AS <name>]

or

FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]

or

FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]

FROM指令初始化新的构建阶段,并为后续指令设置基本镜像。因此,有效的Dockerfile必须以FROM指令开头。

镜像可以是任何有效的镜像——从公共存储库中提取镜像尤其容易:

  • ARG是Dockerfile中FROM之前的唯一指令
  • FROM可以在单个Dockerfile中多次出现,以创建多个镜像,或者将一个构建阶段用作另一个的依赖项。只需在每条新的FROM指令之前记下提交输出的最后一个镜像ID即可。每个FROM指令都会清除先前指令创建的任何状态。
  • 可选地,可以通过将AS名称添加到FROM指令来为新的构建阶段指定名称。该名称可以在随后的FROM和COPY-FROM=<name>指令中使用,以引用在此阶段构建的镜像。
  • 标记值或摘要值是可选的。如果省略其中任何一个,则默认情况下构建器将采用最新的标记。如果生成器找不到标记值,则返回一个错误。

可选的--platform标志可用于在FROM引用多平台映像的情况下指定镜像的平台。例如,linux/amd64、linux/arm64或windows/amd64。默认情况下,将使用构建请求的目标平台。全局构建参数可以用于此标志的值,例如,自动平台ARG允许您将阶段强制到本机构建平台(--platform=$BUILDPORM),并使用它交叉编译到阶段内的目标平台。 

二、LABEL

您可以在镜像中添加标签,以帮助按项目组织镜像、记录许可信息、帮助实现自动化或出于其他原因。对于每个标签,添加一行,以label开头,包含一个或多个键值对。以下示例显示了不同的可接受格式。解释性意见包括在内。
带空格的字符串必须加引号或转义空格。还必须转义内部引号字符(“)。例如: 

# Set one or more individual labels
LABEL com.example.version="0.0.1-beta"
LABEL vendor1="ACME Incorporated"
LABEL vendor2=ZENITH\ Incorporated
LABEL com.example.release-date="2015-02-12"
LABEL com.example.version.is-production=""

一个镜像可以有多个标签。在Docker 1.10之前,建议将所有标签合并为一个LABEL指令,以防止创建额外的层。这不再是必要的,但仍然支持组合标签。例如:

# Set multiple labels on one line
LABEL com.example.version="0.0.1-beta" com.example.release-date="2015-02-12"

上面的例子也可以写成:

# Set multiple labels at once, using line-continuation characters to break long lines
LABEL vendor=ACME\ Incorporated \com.example.is-beta= \com.example.is-production="" \com.example.version="0.0.1-beta" \com.example.release-date="2015-02-12"

三、RUN

将长的或复杂的RUN语句拆分到多行,用反斜杠分隔,使Dockerfile更具可读性、可理解性和可维护性。

1、apt-get

RUN最常见的用例可能是apt-get的应用程序。因为它安装了软件包,RUN-apt-get命令有几个反直觉的行为需要注意。
总是在同一个RUN语句中结合RUN apt-get-update和apt-get-install。例如:

RUN apt-get update && apt-get install -y \package-bar \package-baz \package-foo  \&& rm -rf /var/lib/apt/lists/*

在RUN语句中单独使用apt-get-update会导致缓存问题和随后的apt-get-install指令失败。例如,此问题将出现在以下Dockerfile中:

# syntax=docker/dockerfile:1FROM ubuntu:22.04
RUN apt-get update
RUN apt-get install -y curl

构建镜像后,所有层都在Docker缓存中。假设您稍后通过添加一个额外的包来修改apt-get-install,如以下Dockerfile所示:

# syntax=docker/dockerfile:1FROM ubuntu:22.04
RUN apt-get update
RUN apt-get install -y curl nginx

Docker认为初始指令和修改后的指令是相同的,并重用前面步骤中的缓存。因此,由于构建使用了缓存版本,所以不会执行apt-get更新。因为apt-get更新没有运行,所以您的构建可能会得到curl和nginx包的过时版本。
使用RUN apt-get-update&&apt-get-install-y确保您的Dockerfile安装最新的软件包版本,无需进一步编码或手动干预。这种技术被称为缓存破坏。您还可以通过指定包版本来实现缓存破坏。这就是所谓的版本固定。例如:

RUN apt-get update && apt-get install -y \package-bar \package-baz \package-foo=1.3.*

版本固定强制构建检索特定版本,而不管缓存中有什么。这种技术还可以减少由于所需软件包中的意外变化而导致的故障。
下面是一个格式良好的RUN说明,演示了所有的apt-get建议。

RUN apt-get update && apt-get install -y \aufs-tools \automake \build-essential \curl \dpkg-sig \libcap-dev \libsqlite3-dev \mercurial \reprepro \ruby1.9.1 \ruby1.9.1-dev \s3cmd=1.1.* \&& rm -rf /var/lib/apt/lists/*

s3cmd参数指定版本1.1.*。如果映像以前使用的是旧版本,则指定新版本会导致apt-get-update的缓存中断,并确保安装新版本。在每行列出包也可以防止包重复中的错误。
此外,当您通过删除/var/lib/apt/lists来清理apt缓存时,它会减小镜像大小,因为apt缓存不是存储在层中的。由于RUN语句以apt-get-update开始,因此总是在安装apt-get之前刷新包缓存。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/263388.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win11 powershell conda 激活环境后不显示环境名称

win11 powershell conda 激活环境后不显示环境名称 问题现象解决方法 问题现象 安装 Anaconda 后在 powershell 中激活环境后&#xff0c;命令行前面不显示环境名称 解决方法 在 powershell 中执行 conda init 重新打开 poweshell 出现以下问题&#xff0c;请参考 win11 p…

05-详解调用服务时负载均衡的配置及其原理

负载均衡 负载均衡的原理(通用) LoadBalanced注解用来拦截它所标记的RestTemplate发起的http请求, 底层是利用了一个名为Ribbon的组件来实现负载均衡功能(Cloud高版本已经弃用) LoadBalancerInterceptor的intercept方法会对RestTemplate的请求进行拦截 public class LoadBal…

Java - CAS在Java中的应用、CAS的三大问题

什么是CAS CAS&#xff08;Compare-and-Swap&#xff09;是一种乐观锁的实现方式&#xff0c;全称为“比较并交换”&#xff0c;是一种无锁的原子操作。 在并发编程中&#xff0c;我们都知道i操作是非线程安全的&#xff0c;这是因为 i操作不是原子操作 i语句只需要执行一条指令…

111.am40刷机折腾记4-firefly镜像-dp正常显示

1. 平台&#xff1a; rk3399 am40 4g32g 2. 内核&#xff1a;firefly的内核&#xff08;整体镜像&#xff09; 版本&#xff1a; linux4.4.194 3. 交叉编译工具 &#xff1a;暂时不编译 4. 宿主机&#xff1a;ubuntu18.04 5. 需要的素材和资料&#xff1a;boot-am40-202…

python的Pandas库介绍

&#x1f388; 博主&#xff1a;一只程序猿子 &#x1f388; 博客主页&#xff1a;一只程序猿子 博客主页 &#x1f388; 个人介绍&#xff1a;爱好(bushi)编程&#xff01; &#x1f388; 创作不易&#xff1a;喜欢的话麻烦您点个&#x1f44d;和⭐&#xff01; &#x1f388;…

JavaScript中冷门但有用的String.raw

文章梗概 本文讲解的String.raw&#xff0c;作为JavaScript中的静态方法&#xff0c;用来获取模板字符串的原始字符串形式&#xff0c;需要注意的是与字符串模板搭配时候的事项。 介绍 String.raw() 静态方法是模板字符串的标签函数。它的作用类似于 Python 中的 r 前缀或 C#…

mmdetection里的测速脚本

由于大论文里需要对各个算法进行测速&#xff0c;因此抛开官方文档的使用说明&#xff0c;记录一下我是怎么使用mmdetection里的脚本进行测速的。 mmdetection版本&#xff1a;2.23.0 一、新版本benchmark.py&#xff08;需要分布式&#xff09; 打开tools/analysis_tools/b…

在Deepin中安装x11vnc工具并结合内网穿透软件实现远程访问桌面

文章目录 1. 安装x11vnc2. 本地远程连接测试3. Deepin安装Cpolar4. 配置公网远程地址5. 公网远程连接Deepin桌面6. 固定连接公网地址7. 固定公网地址连接测试 x11vnc是一种在Linux系统中实现远程桌面控制的工具&#xff0c;它的原理是通过X Window系统的协议来实现远程桌面的展…

Docker部署开源分布式任务调度平台DolphinScheduler并实现远程访问办公

文章目录 前言1. 安装部署DolphinScheduler1.1 启动服务 2. 登录DolphinScheduler界面3. 安装内网穿透工具4. 配置Dolphin Scheduler公网地址5. 固定DolphinScheduler公网地址 前言 本篇教程和大家分享一下DolphinScheduler的安装部署及如何实现公网远程访问&#xff0c;结合内…

Java连接数据库增删改查-MyBatis

准备工作&#xff1a; 1.创建一个springboot项目&#xff0c;并添加四个依赖 分别是&#xff0c;MyBatis的启动依赖和安装依赖&#xff0c;SQL的依赖&#xff0c;测试依赖&#xff0c;如下&#xff1a; 2.然后创建一张至少两条数据的表 &#xff08;表可以用各种图形化工具创…

[c]零钱兑换

题目比较简单&#xff0c;看答案就能看懂什么意思 #include<stdio.h> int main() {int count 0;int n;scanf("%d", &n);for (int i 0; i < n; i){for (int k 0; k <n/2; k){for (int j 0; j < n/5 ; j){if (i 2 * k 5 * j n){count;}}}}p…

【图片版】计算机组成原理考前复习题【第3章 存储系统-2(Cache)】

目录 前言 考前复习题&#xff08;必记&#xff09; 结尾 前言 在计算机组成原理的学习过程中&#xff0c;我们深入探索了计算机系统概述这一重要领域。计算机系统作为现代科技的核心&#xff0c;是整个计算机科学的基石。我们将学到的知识与理论转化为了能够解决现实问题…