手把手教你在Node.js项目中如何优化docker镜像


当前第2页 返回上一页

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

FROM alpine:latest

 

# 使用 apk 命令安装 nodejs 和 yarn,如果使用 npm 启动,就不需要装 yarn

RUN apk add --no-cache --update nodejs=14.17.4-r0 yarn=1.22.10-r0

 

# 暴露端口

EXPOSE 4300

 

# 设置环境变量

ENV NODE_ENV=production \

    APP_PATH=/node/app

 

# 设置工作目录

WORKDIR $APP_PATH

 

# 拷贝 package.json 到工作跟目录下

COPY package.json .

 

# 安装依赖

RUN yarn

 

# 把当前目录下的所有文件拷贝到镜像的工作目录下 .dockerignore 指定的文件不会拷贝

COPY . .

 

# 启动命令

CMD yarn start

build 看下图,编译时间从 29.6s 到 1.3s,使用了缓存的层前面会有个 CACHED 字眼,仔细看下图可以看到

10.png

充分利用 docker 缓存特性是优化构建速度的利器

11.png

使用多阶段构建再次压榨镜像大小

多阶段构建这里不多说了,不了解的可以先搜相关资料了解

因为我们运行 node 程序是只需要生产的依赖和最终 node 可以运行的文件,就是说我们运行项目只需要 package.js 文件里 dependencies 里的依赖,devDependencies 依赖只是编译阶段用的,比如 eslint 等这些工具在项目运行时是用不到的,再比如我们项目是用 typescript 写的,node 是不能直接运行 ts 文件,ts 文件需要编译成 js 文件,运行项目我们只需要编译后的文件和 dependencies 里的依赖就可以运行,也就是说最终镜像只需要我们需要的东西,任何其他东西都可以删掉,下面我们使用多阶段改写 Dockerfile

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

# 构建基础镜像

    FROM alpine:3.14 AS base

 

    # 设置环境变量

    ENV NODE_ENV=production \

        APP_PATH=/node/app

     

    # 设置工作目录

    WORKDIR $APP_PATH

 

    # 安装 nodejs 和 yarn

    RUN apk add --no-cache --update nodejs=14.17.4-r0 yarn=1.22.10-r0

 

# 使用基础镜像 装依赖阶段

    FROM base AS install

 

    # 拷贝 package.json 到工作跟目录下

    COPY package.json ./

 

    # 安装依赖

    RUN yarn

 

# 最终阶段,也就是输出的镜像是这个阶段构建的,前面的阶段都是为这个阶段做铺垫

    FROM base

 

    # 拷贝 装依赖阶段 生成的 node_modules 文件夹到工作目录下

    COPY --from=install $APP_PATH/node_modules ./node_modules

 

    # 将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入镜像的工作目录下

    COPY . .

 

    # 启动

    CMD yarn start

细心的朋友会发现我这里有指定 alpine 版本,而上面都是用的 latest 版本,因为就在刚刚发现有个坑需要注意下,就是我们选择 alpine 版本的时候,最好不要选择 latest 版本,因为后面要装的软件版本可能会在 alpine 的 latest 版本没有对应软件的版本号,就会安装错误,我刚刚就翻车了,点击查看 alpine 版本下的包信息

12.png

build 后,我们看看镜像大小,上次的是 174M 再次降到 73.4M,极致压榨。镜像:”放过我把,我真的没有了“

13.png

讲解:

我把这个构建分成了三个阶段:

  • 第一阶段:构建基础镜像

    安装依赖、编译、运行等等阶段,就是所有阶段共用的东西都在第一阶段封到一个基础镜像里供其它阶段使用,比如设置环境变量、设置工作目录、安装 nodejs、yarn 等等

  • 第二阶段:装依赖阶段

    在这个阶段,装依赖,如果项目需要编译,可以在这个阶段装依赖编译好

    这里在说下装依赖的小细节,就是执行 yarn --production 加个 production 参数或者环境变量 NODE_ENVproduction,yarn 将不会安装 devDependencies 中列出的任何软件包,点我查看官方文档说明,因为我设置了环境变量所以就没加这个参数

  • 第三阶段:最终使用镜像

    拷贝第二阶段安装的好的依赖文件夹,然后在拷贝代码文件到工作目录,执行启动命令,第二阶段装依赖多出的一些垃圾我们不需要,我们就只拷贝我们要用的东西,大大减少镜像的大小

    如果项目需要编译,在拷贝编译后的文件夹,不需要拷贝编译前的代码,有编译后的代码和依赖就可以跑起项目

多阶段构建,最后生成的镜像只能是最后一个阶段的结果,但是,能够将前置阶段中的文件拷贝到后边的阶段中,这就是多阶段构建的最大意义。

最终优化成果:

  • 大小从 1.06G 到 73.4M

  • 构建速度从 29.6 秒到 1.3 秒(对比的是第二次构建的速度)

至此,压榨镜像手段就完了,如果各位老板还有压榨手段可以分享分享

镜像内心独白:”你礼貌吗?还来“

github 的 actions 构建镜像问题

github 提供的 actions,每次都是一个干净的实例,什么意思,就是每次执行,都是干净的机器,这会导致一个问题,会导致 docker 没法使用缓存,那有没有解决办法呢,我想到了两种解决办法:

  • docker 官方提供的 action 缓存方案

    我用的是 Github cache 方案

  • 自托管 actions 运行机器

    相当于 gitlab 的 runner 一样,自己提供运行器,自己提供的就不会每次都是干净的机器,详情看 actions 官方文档

参考资料:

  • 在 GitHub Actions 上使用 Docker 层缓存构建镜像

最后

项目仓库地址 https://github.com/iamobj/wechat-bot

文章有错误的地方欢迎指正,避免误人子弟

14.png

原文地址:https://juejin.cn/post/6991689670027542564

作者:iamc

更多编程相关知识,请访问:编程入门!!

以上就是手把手教你在Node.js项目中如何优化docker镜像的详细内容,更多文章请关注木庄网络博客

返回前面的内容

相关阅读 >>

手把手教你在node.js项目中如何优化docker镜像

更多相关阅读请进入《Node.js.优化docker镜像》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...