Dockerfile 最佳实践

简介: Dockerfile 最佳实践

Dockerfile 是用来构建 docker 镜像的配置文件,语法简单上手容易,你可以很轻松的就编写一个能正常使用的 Dockerfile ,但是它很有可能还不够好,本文将会从细节上介绍一些 tips 助你实现最佳实践。


--------------------------



1、注意构建顺序

ROM debian 
COPY . ./app 
RUN apt-get update 
RUN apt-get -y install cron vim ssh 
COPY . ./app

图中第二步一旦本地文件发生了变化将会导致包括此后步骤的缓存全部失效,必须重新构建,尤其是在开发环境,这将会增加你构建镜像的耗时。构建步骤的排序很重要,改变小的步骤放前面,改变大的步骤放后面,这有助于你优化使用缓存加速整个构建过程。



2、使用更精确的 COPY

只 copy 真正需要的文件,比如 node_modules 或者其它一些对于构建镜像毫无作用的文件一定要忽略掉(写入 .dockerignore 文件),这些无用的文件百害而无一利。



3、合并指令

RUN apt-get update  
RUN apt-get -y install cron vim ssh
RUN apt-get update \
  && apt-get -y install cron vim ssh

像这种 apt-get 升级和安装分为两个步骤毫无必要,反之统一为一个步骤更有利于缓存。你如果仔细观察各种官方镜像的 Dockerfile 是怎么写的,你肯定会发现他们单条 RUN 指令的内容相当的冗长也不会拆分,这样写是有道理的。



4、移除不必要的依赖

RUN apt-get update \   
   && apt-get -y install cron vim ssh
RUN apt-get update \
   && apt-get -y install --no-install-recommends  cron 

只安装必须的依赖,某些 debug 的工具不要在构建的时候安装,首先线上 debug 的频率应该是很低的,其次真的要用的时候另外再安装就好了。另外 apt-get 这种包管理器可能会多安装一些额外推荐的东西,加上 --no-install-recommends 不要安装它们,如果某些工具是需要的则必须显示声明。



5、移除包管理器的缓存

RUN apt-get update \    
   && apt-get -y install --no-install-recommends  cron \
   && rm -rf /var/lib/apt/lists/*

包管理器有它自己的缓存,记得删除这些文件。做这么多的目的其实就是精简镜像的大小(一个镜像几百M 上G的实在是有太多不需要的垃圾内容了),镜像越小部署起来越快。



6、使用官方镜像

比如,你需要一个 node.js 环境,你可以拉取一个 linux 基础镜像,然后自己一步一步安装,但是这样做毫无必要,你应该直接选择 node.js 官方的基础镜像,你要知道官方镜像一定是做了很多优化的。



7、使用清晰的 tag 标记

不要使用 FROM node:latest 这种,latest 标记鬼知道具体指向了哪个版本。



8、寻找合适大小的镜像

例如上面这三个基础镜像都是相同的 node 12.6.0 版本,但是镜像大小差别却很大,因为底层的系统是可以被裁剪的,镜像越小越好,但是要注意由于系统被裁剪可能出现兼容性问题。



9、在一致的环境中从源码构建



10、安装依赖

这里安装的依赖指的不是系统依赖,而是应用程序的依赖,在单独的步骤中进行。



11、多阶段构建

例如 go 语言,打包编译的操作是需要安装相关环境和工具的,但是运行的时候并不需要,这时候我们就可以使用多阶段构建。

FROM golang:1.12 AS builder 
WORKDIR /app 
COPY ./ ./ 
RUN go build -o myapp test.go 
FROM debian:stable-slim 
COPY --from=builder /app/myapp /
CMD ["./myapp"]

如上图所示,我们在第一阶段的构建拉取了完整的 go 环境,然后打包编译生成二进制可执行文件,在第二阶段则重新构造一个新的环境并选用精简的 debian 基础镜像,只把第一阶段编译好的可执行文件复制进来,而其它不需要的东西通通抛弃掉了,这样我们最终生成的镜像是非常小而精的。(多阶段构建要求 docker 版本 17.05 以上)



最后,我们所使用的语言和对环境的要求千差万别,注意不要生搬硬套,只有适合自己的才是最好的,希望本文所述的这些细节对你有所帮助。


目录
相关文章
|
监控 数据可视化 关系型数据库
PostgreSQL主备库搭建
pg主备库的搭建,首先需在2个节点安装pg软件,然后依次在2个节点配置主备。 本文采用os为CentOS7.6,pg版本使用14.2,以下为详细部署步骤。
1038 0
|
JavaScript 前端开发 测试技术
Vite2 + Vue3 + TypeScript + Pinia 搭建一套企业级的开发脚手架
Vite2 + Vue3 + TypeScript + Pinia 搭建一套企业级的开发脚手架
929 88
Vite2 + Vue3 + TypeScript + Pinia 搭建一套企业级的开发脚手架
|
监控 负载均衡 网络协议
Keepalived的原理和web服务高可用实践
Keepalived的原理和web服务高可用实践
Keepalived的原理和web服务高可用实践
|
机器学习/深度学习 SQL JSON
图解大数据 | 使用Spark分析挖掘零售交易数据@综合案例
电商与新零售是目前大数据与AI应用最广泛的场景之一,本案例以跨国在线零售业务为背景,讲解使用pyspark对HDFS存储的数据进行交易数据分析的过程,并且对分析结果使用echarts做了可视化呈现。
4568 1
图解大数据 | 使用Spark分析挖掘零售交易数据@综合案例
|
存储 消息中间件 缓存
ActiveMQ系列:ActiveMQ的持久化机制
为了避免意外宕机以后丢失信息,需要做到重启后可以恢复消息队列,消息系统一般都会采用持久化机制。ActiveMQ的消息持久化机制有JDBC,AMQ,KahaDB和LevelDB,无论使用哪种持久化方式,消息的存储逻辑都是一致的 就是在发送者将消息发送出去后,消息中心首先将消息存储到本地数据文件、内存数据库或者远程数据库等再试图将消息发送给接收者,成功则将消息从存储中删除,失败则继续尝试发送。
468 0
ActiveMQ系列:ActiveMQ的持久化机制
|
canal NoSQL Java
「从零单排canal 03」 canal源码分析大纲
「从零单排canal 03」 canal源码分析大纲
467 1
「从零单排canal 03」 canal源码分析大纲
|
测试技术 程序员 API
3个案例,详解如何选择合适的研发模式 | 研发效能提升36计
3个案例,详解如何选择合适的研发模式,研发模式的选择与产品形态、发布方式、团队规模、协作成熟度密切相关。本文我们将根据不同的团队场景,分析如何选择适合团队的研发模式。
1398 1
3个案例,详解如何选择合适的研发模式 | 研发效能提升36计
|
分布式计算 Kubernetes 大数据
阿里云容器服务差异化 SLO 混部技术实践
阿里巴巴在“差异化 SLO 混合部署”上已经有了多年的实践经验,目前已达到业界领先水平。所谓“差异化 SLO”,就是将不同类型的工作负载混合运行在同一节点,充分利用工作负载对资源 SLO 需求特征的不同,提升资源整体使用效率。本文将重点介绍相关技术细节和使用方法,让用户可以充分享受差异化 SLO 带来的技术红利。
阿里云容器服务差异化 SLO 混部技术实践
|
机器学习/深度学习 搜索推荐 算法
【推荐系统】美团外卖推荐场景的深度位置交互网络DPIN的突破与畅想
美团基础研发机器学习平台训练引擎团队,联合到家搜推技术部算法效能团队、NVIDIA DevTech团队,成立了联合项目组。目前在美团外卖推荐场景中进行了部署,多代模型全面对齐算法的离线效果,对比之前,优化后的CPU任务,性价比提升了2~4倍。
747 0
【推荐系统】美团外卖推荐场景的深度位置交互网络DPIN的突破与畅想
|
机器学习/深度学习 算法 TensorFlow
Py之imblearn:imblearn/imbalanced-learn库的简介、安装、使用方法之详细攻略
Py之imblearn:imblearn/imbalanced-learn库的简介、安装、使用方法之详细攻略
Py之imblearn:imblearn/imbalanced-learn库的简介、安装、使用方法之详细攻略