本文将以 Node 顺序展现如何优化 Docker 镜像(优化思想是通用的,不分顺序),主要处置镜像大小过大、CI/CD 构建镜像速度,本文演示如何一步步优化 Dockerfile 文件,优化的结果如下:
大小从 1.06G 到 73.4M
构建速度从 29.6 秒到 1.3 秒(比照的是第二次构建的速度)
Node 项目复杂写了一个本人用的 wechat-bot,接上去就以这个项目演示怎样去优化 Docker 镜像。
以下是我没有细心研讨 Docker 刚末尾写的 Dockerfile 文件。
FROM node:14.17.3
# 设置环境变量
ENV NODE_ENV=production
ENV APP_PATH=/node/app
# 设置任务目录
WORKDIR $APP_PATH
# 把以后目录下的一切文件拷贝到镜像的任务目录下 .dockerignore 指定的文件不会拷贝
COPY . $APP_PATH
# 安装依赖
RUN yarn
# 暴露端口
EXPOSE 4300
CMD yarn start
build 之后,如下图,我这个复杂的 Node 顺序镜像居然有 1G 多,接上去我们将逐渐去优化增加这个大小。
优化前言在优化之前,有些东西我们必须了解,处置成绩的第一步就是先找出招致成绩的缘由。
Dockerfile 文件,其内包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描画该层如何构建。
Docker 镜像并非只是一个文件,而是由一堆文件组成,最主要的文件是层(Layers)
镜像构建时,会一层层构建,前一层是后一层的基础每一层构建完就不会再发作改动,后一层上的任何改动只发作在本人这一层。比如,删除前一层文件的操作,实践不是真的删除前一层的文件,而是仅在以后层标记为该文件已删除。在最终容器运转的时分,虽然不会看到这个文件,但是实践上该文件会不断跟随镜像。
镜像层将会被缓存和复用(这也是从第二次末尾构建镜像时,速度会快的缘由,优化镜像构建速度的原理也是应用缓存原理来做)
当 Dockerfile 的指令修正了,操作的文件变化了,或许构建镜像时指定的变量不同了,对应的镜像层缓存就会失效
docker build 的缓存机制,Docker 是怎样知道文件变化的呢?
Docker 采取的策略是:获取 Dockerfile 下内容(包括文件的部分 inode 信息),计算出一个独一的 hash 值,若 hash 值未发作变化,则可以以为文件内容没有发作变化,可以运用缓存机制,反之亦然。
某一层的镜像缓存失效之后,它之后的镜像层缓存都会失效
镜像的每一层只记载文件变更,在容器启动时,Docker 会将镜像的各个层停止计算,最后生成一个文件系统当我知道这点时,我豁然开朗,我们运用的操作系统,比如安卓、iOS、Windows、macOS 等,其实就是一个文件系统,我们的软件界面交互等,其实就是在读写文件,我们网页写个弹框,操作 dom,就是在读写本地文件或许是读写内存里的数据,团体的一些见地不知道对不对,本人非半路出家的前端 coder。
参考材料:https://www.cnblogs.com/handwr ... .html
ok,我们曾经知道镜像是由多层文件系统组成,想要优化它的大小,就需求去增加层数、每一层尽量只包含该层需求的东西,任何额外的东西应该在该层构建完毕前清算掉,下面末尾注释。
优化 Dockerfile 优化第一层 FROM node:14.17.3 方案一:运用 Node 的 Alpine 版本这也是绝少数人知道的优化镜像手腕,Alpine 是一个很小的 Linux 发行版,只需选择 Node 的 Alpine 版本,就会有很大改良,我们把这一句改成指令改成 FROM node:14.17.4-alpine(可以去 Dockerhub 查看 Node 有哪些版本标签),build 后镜像大小如下图,瞬间从 1.06G 降到 238M,可以说是效果清楚。
还可以运用其它的基础小镜像,比如 mhart/alpine-node,这个还能再小,改成 FROM mhart/alpine-node:14.17.3 再试试,可以看到又小了 5M,虽然不多,但是秉着能压榨一点是一点的“老板准绳”,集腋成裘,极致压榨。
方案二:运用纯真 Alpine 镜像手动装 Node既然 Alpine 是最小的 Linux,那我们试下用纯真的 Alpine 镜像,本人再装 Node 试试。
FROM alpine:latest
# 运用 apk 命令安装 nodejs 和 yarn,假设运用 npm 启动,就不需求装 yarn
RUN apk add --no-cache --update nodejs=14.17.4-r0 yarn=1.22.10-r0
# ... 前面的步骤不变
build 后看下图,只要 174M 了,又小了不少。
结论就是不嫌费事追求极致就用方案二,从 1.06G 增加到 174M。
增加层数、不常常变动的层提到前面去ENV 指令是可以一次性设置多个环境变量,能一次指令执行完,就不用两次,多一个指令就多一层
EXPOSE 指令是暴露端口,其实也可以不用写这个指令,在启动容器的时分本人映射端口,假设写了这个指令的话,由于端口不常常变,所以把这个指令提早,写上这个指令有两个益处:
协助镜像运用者了解这个镜像效劳的守护端口,以方便配置映射
在运转时运用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口
(责任编辑:admin)