Docker入门系列——DockerFile的使用

alt

前面了解了Docker的基本概念,今天来认识一下DockerFile。

Dockerfile 是一个文本文件,包含一系列指令来组装 Docker 镜像。每个指令执行一个特定动作,例如安装包、复制文件或定义启动命令。正确使用 Dockerfile 指令对于构建高效容器至关重要。

关键 Dockerfile 指令

  • FROM:设置新镜像的基础镜像。
  • RUN:在当前镜像之上的新层执行命令并提交结果。
  • CMD:指定容器启动时默认运行的命令。
  • COPY:从构建上下文复制文件和目录到容器文件系统。
  • ADD:与 COPY 类似,但具有解压归档等附加功能。
  • ENV:设置环境变量。
  • EXPOSE:告知 Docker 容器在运行时监听的端口。
  • ENTRYPOINT:配置容器作为可执行文件运行。
  • VOLUME:为外部存储卷创建挂载点。
  • WORKDIR:设置后续指令的工作目录。

Dockerfile精华知识点

使用最小基础镜像

基础镜像是您的 Docker 镜像的基础。选择轻量级基础镜像可以显著减少最终镜像大小并最小化攻击面。

  • Alpine Linux:一个流行的最小镜像,大约 5 MB 大小。
FROM alpine:latest

优点:体积小、安全性高、下载速度快。

缺点:可能需要额外配置;一些包可能缺失或因使用 musl 而不是 glibc 而表现不同。

  • Scratch:一个空镜像,适合可以编译静态二进制文件的语言(Go、Rust)。
FROM scratch
COPY myapp /myapp
CMD ["/myapp"]

减少层数

每个 RUNCOPYADD 指令都会向您的镜像添加一个新层。合并命令有助于减少层数和整体镜像大小。

低效:

RUN apt-get update
RUN apt-get install -y python
RUN apt-get install -y pip

高效:

RUN apt-get update && apt-get install -y \
    python \
    pip \
 && rm -rf /var/lib/apt/lists/*

优化层缓存

Docker 使用层缓存来加快构建速度。指令的顺序影响缓存效率。

  • 先复制依赖文件:先复制变化较少的文件(如 package.jsonrequirements.txt),然后再复制其余的源代码。
COPY package.json .
RUN npm install
COPY . .
  • 最小化早期层的变化:早期层的变化会使所有后续层的缓存失效。

明智地安装依赖

安装包后删除临时文件和缓存以减少镜像大小。

RUN pip install --no-cache-dir -r requirements.txt

谨慎管理密钥

永远不要在您的 Dockerfile 中包含敏感数据(密码、API 密钥)。

  • 使用环境变量:在运行时使用环境变量传递密钥。
  • 利用 Docker 密钥:使用 Docker Swarm 或 Kubernetes 机制管理密钥。

优化镜像大小

  • 删除不必要的文件:在同一 RUN 命令中清理缓存、日志和临时文件。这确保这些临时文件不会在任何中间层中持久存在,有效减少最终镜像大小。
RUN apt-get update && apt-get install -y --no-install-recommends package \
      && apt-get clean && rm -rf /var/lib/apt/lists/*

  • 最小化安装的包:使用 --no-install-recommends 等标志只安装所需的包。这避免了不必要的依赖项,进一步减小镜像大小。
RUN apt-get install -y --no-install-recommends package

注意:为了最大化减少镜像大小,请将此安装与清理命令结合在同一个 RUN 语句中,如上所示。

  • 使用优化工具:利用 Docker Slim 等工具可以自动分析和优化您的 Docker 镜像,通过移除不必要的组件和减小大小而不改变功能。

利用 .dockerignore

.dockerignore 文件允许您排除构建上下文中的文件和目录,减少发送到 Docker 守护进程的数据量,并保护敏感信息。

示例 .dockerignore:

.git
node_modules
Dockerfile
.dockerignore

采用多阶段构建

多阶段构建允许您使用中间镜像,并将仅必要的构件复制到最终镜像中。

Go 应用程序的示例:

# 构建阶段
FROM golang:1.16-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

# 最终镜像
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]

以非根用户运行

为了增强安全性,避免以 root 用户运行应用程序。

RUN adduser -D appuser
USER appuser

扫描漏洞

  • 使用扫描工具TrivyAnchoreClair 等工具可以帮助识别已知漏洞。
  • 定期更新镜像:保持基础镜像和依赖项更新。

日志和监控

  • 将日志导向 STDOUT/STDERR:这允许更容易地收集和分析日志。
  • 集成监控系统:使用 Prometheus 或 ELK Stack 等工具监控容器健康。

案例

下面来看一下Node.js 应用程序的优化 Dockerfile 示例

# 使用基于 Alpine Linux 的官方 Node.js 镜像
FROM node:14-alpine

# 设置工作目录
WORKDIR /app

# 复制包文件并安装依赖
COPY package*.json ./
RUN npm ci --only=production

# 复制其余的应用程序代码
COPY . .

# 创建非根用户并切换到它
RUN addgroup appgroup && adduser -S appuser -G appgroup
USER appuser

# 暴露应用程序端口
EXPOSE 3000

# 定义运行应用程序的命令
CMD ["node""app.js"]

其他建议

  • 固定版本:使用基础镜像和包的特定版本以确保构建的可重现性。
FROM node:14.17.0-alpine
  • 保持更新:定期更新依赖项和基础镜像以包含安全补丁。
  • 使用元数据:添加 LABEL 指令以提供镜像元数据。
LABEL maintainer="yourname@example.com"
  • 设置适当的权限:确保文件和目录具有适当的权限。
  • 避免使用根用户:始终切换到非根用户运行应用程序。

结论

创建高效的 Docker 镜像既是一门艺术,也是一门科学。通过遵循编写 Dockerfile 的最佳实践,您可以显著提高容器的性能、安全性和管理性。不断更新您的知识,了解容器化生态系统中的新工具和方法。记住,优化是一个持续的过程,总有改进的空间。

本文由 mdnice 多平台发布

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

2-146 基于matlab的双摆杆系统建模分析

基于matlab的双摆杆系统建模分析。连接方式为铰接,两杆均视为均质杆,动态输出摆杆末端轨迹。程序已调通,可直接运行。 下载源程序请点链接:2-146 基于matlab的双摆杆系统建模分析

基于java+SpringBoot+Vue的美发门店管理系统设计与实现

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: Springboot mybatis Maven mysql5.7或8.0等等组成&#x…

基于vue框架的的楼盘销售管理系统6n60a(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 用户,房源类型,员工,房源信息,购房预订,购房合同 开题报告内容 基于Vue框架的楼盘销售管理系统开题报告 一、研究背景 随着房地产市场的蓬勃发展,楼盘销售行业的竞争日益激烈。传统的销售管理方式依赖于人工记录和纸质文档,效率低下…

值得一看的小模型技术全面总结及RAG文档处理及切分小模型工具

、 本文还是来看看RAG,不过是从另一个角度,从小模型(其实这个小不太好说,7B或者以下?)角度; 因此,讲两件事,一个是回顾下小模型,推荐一个写的很好的小模型进展技术总结综述&#xf…

大模型好书案例——《BERT基础教程:Transformer大模型实战》(附PDF)

《BERT基础教程:Transformer大模型实战》是一本关于自然语言处理(NLP)的书籍,专注于谷歌公司开发的BERT模型。这本书由印度作者苏达哈尔桑拉维昌迪兰(Sudharsan Ravichandiran)撰写,周参翻译。 …

关于Markdown的一点疑问,为什么很多人说markdown比word好用?

markdown和word压根不是一类工具,不存在谁比谁好,只是应用场景不一样。 你写博客、写readme肯定得markdown,但写合同、写简历肯定word更合适。 markdown和word类似邮箱和微信的关系,这两者都可以通信,但微信因为功能…

ASR 点屏

ASR翱捷科技 ASR kernel 5.10 android14 ASR EVB平台 以gc7202 jd9365这两块屏为例 新旧DTBO点屏配置是有区别的,主要差异是体现在 asr\kernel\u-boot\board\asr\dove\dovc.c这个文件上 旧DTBO: 新DTBO: 目前我们的代码已经合入新的DTBO 以前在没有合入asr新的DTBO时点亮…

Ubuntu24.04网络异常与应对方案记录

PS: 参加过408改卷的ZJU ghsongzju.edu.cn 开启嘲讽: 你们知道408有多简单吗,操作系统真实水平自己知道就行~~ Requested credits of master in UWSC30,in ZJU24,domestic master is too simple dmesg dmesg 是一个用…

【Zynq FPGA】基于 Zynq FPGA 的雷龙 SD NAND 测试

对于芯片正常读写的测试结果,还是很让人满意的,芯片的价格也很合理。并且LGA-8封装更适合无卡槽的嵌入式开发板设计,在一定的应用领域有着简化硬件设计、减小硬件面积的功能。贴上测试工程的链接,还迎复现实验: https://gitee.com…

【PyTorch][chapter31][transformer-5] MQA,CQA, GQA

前言: Trans 翻译 《Variants of Multi-head attention: Multi-query (MQA) and Grouped-query attention (GQA) 为例兼顾性能,和模型的效率Google 又陆续提出了三种注意力架构. 当一个模型训练过度时,它会过度拟合或记忆训练数据,从而降低…

数据结构之排序--选择排序详解

选择排序 每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。 直接选择排序: 在元素集合 array[i]--array[n-1] 中选择关键码最大 ( 小 ) 的数据元素 若它不是这组元…

spring组件介绍

1. Spring Core(Spring核心): • BeanFactory:Spring IoC容器的基础接口,提供了配置框架和基本的功能,用于管理任何类型的对象。 • ApplicationContext:BeanFactory的子接口,提供了…

软件测试基础:单元测试与集成测试

单元测试的重要性 单元测试是软件开发过程中的必要步骤。它通过针对软件的最小可测试单元进行测试,可以及早发现代码中的逻辑错误和缺陷。根据统计数据显示,单元测试可以在软件开发初期就发现约70%的错误,从而减少了后期修改的成本和时间消耗…

sql专题 之 常用命令

文章目录 查询基础语法查询全表查询选择查询&#xff1a;常量和运算&#xff1a; 条件查询where运算符&#xff1a;、 !、<、>空值&#xff1a;null模糊查询&#xff1a;like逻辑运算&#xff1a;and or not 去重&#xff1a;distinct排序&#xff1a;order by截断和偏移…

LocalSend:开源跨平台文件传输工具,让设备互通无阻

在现代社会中&#xff0c;文件共享和设备之间的互联互通已经成为日常生活中不可或缺的一部分。无论是在工作中分享文档&#xff0c;还是在朋友间传输照片和视频&#xff0c;快速而便捷的文件传输工具都显得尤为重要。通常情况下&#xff0c;我们依赖互联网或蓝牙进行文件传输&a…

解决 Vue3、Vite 和 TypeScript 开发环境下跨域的问题,实现前后端数据传递

引言 本文介绍如何在开发环境下解决 Vite 前端&#xff08;端口 3000&#xff09;和后端&#xff08;端口 80&#xff09;之间的跨域问题&#xff1a; 在开发环境中&#xff0c;前端使用的 Vite 端口与后端端口不一致&#xff0c;会产生跨域错误提示&#xff1a; Access to X…

C/C++/PYTHON 改变 console terminal cmd 字体输出颜色

C代码 #include <stdio.h>// 定义一些常用颜色的转义序列 #define RED "\x1b[31m" #define GREEN "\x1b[32m" #define YELLOW "\x1b[33m" #define BLUE "\x1b[34m" #define RESET "\x1b[0m"int main() {// 在控制台输…

android studio 更改gradle版本方法(备忘)

如果出现类似以下&#xff1a; Your build is currently configured to use Java 17.0.11 and Gradle 6.1.1. 或者类似&#xff1a; Failed to calculate the value of task ‘:app:compileDebugJavaWithJavac‘ property ‘options.generatedSo 消息时需要修改gradle版本&…

游戏引擎学习第一天

视频参考: https://www.bilibili.com/video/BV1zGDCYHErA/ 创建一个保存项目的路径 VS的安装略过&#xff0c;个人自行百度 1. vs 创建第一个CMAKE的窗口项目 game.cpp 修改如下的代码 到https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-winmain 去…

基于Spring Boot的养老保险管理系统的设计与实现,LW+源码+讲解

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统养老保险管理系统信息管理难度大&#xff0c;容错率低&a…