NodeJS 服务 Docker 镜像极致优化指北

这段时间在开发一个腾讯文档全品类通用的 HTML 动态服务,为了方便各品类接入的生成与部署,也顺应上云的趋势,考虑使用 Docker 的方式来固定服务内容,统一进行制品版本的管理。本篇文章就将我在服务 Docker 化的过程中积累起来的优化经验分享出来,供大家参考。

以一个例子开头,大部分刚接触 Docker 的同学应该都会这样编写项目的 Dockerfile,如下所示:

FROM node:14
WORKDIR /app

COPY . .
# 安装 npm 依赖
RUN npm install

# 暴露端口
EXPOSE 8000

CMD ["npm", "start"]

构建,打包,上传,一气呵成。然后看下镜像状态,卧槽,一个简单的 node web 服务体积居然达到了惊人的 1.3 个 G,并且镜像传输与构建速度也很慢:

docker 镜像优化前

要是这个镜像只需要部署一个实例也就算了,但是这个服务得提供给所有开发同学进行高频集成并部署环境的(实现高频集成的方案可参见我的 上一篇文章)。首先,镜像体积过大必然会对镜像的拉取和更新速度造成影响,集成体验会变差。其次,项目上线后,同时在线的测试环境实例可能成千上万,这样的容器内存占用成本对于任何一个项目都是无法接受的。必须找到优化的办法解决。

发现问题后,我就开始研究 Docker 的优化方案,准备给我的镜像动手术了。

node 项目生产环境优化

首先开刀的是当然是前端最为熟悉的领域,对代码本身体积进行优化。之前开发项目时使用了 Typescript,为了图省事,项目直接使用 tsc 打包生成 es5 后就直接运行起来了。这里的体积问题主要有两个,一个是开发环境 ts 源码并未处理,并且用于生产环境的 js 代码也未经压缩。

tsc 打包

另一个是引用的 node_modules 过于臃肿。仍然包含了许多开发调试环境中的 npm 包,如 ts-node,typescript 等等。既然打包成 js 了,这些依赖自然就该去除。

一般来说,由于服务端代码不会像前端代码一样暴露出去,运行在物理机上的服务更多考虑的是稳定性,也不在乎多一些体积,因此这些地方一般也不会做处理。但是 Docker 化后,由于部署规模变大,这些问题就非常明显了,在生产环境下需要优化的。

对于这两点的优化的方式其实我们前端非常熟悉了,不是本文的重点就粗略带过了。对于第一点,使用 Webpack + babel 降级并压缩 Typescript 源码,如果担心错误排查可以加上 sourcemap,不过对于 docker 镜像来说有点多余,一会儿会说到。对于第二点,梳理 npm 包的 dependencies 与 devDependencies 依赖,去除不是必要存在于运行时的依赖,方便生产环境使用 npm install --production 安装依赖。

优化项目镜像体积

使用尽量精简的基础镜像

我们知道,容器技术提供的是操作系统级别的进程隔离,Docker 容器本身是一个运行在独立操作系统下的进程,也就是说,Docker 镜像需要打包的是一个能够独立运行的操作系统级环境。因此,决定镜像体积的一个重要因素就显而易见了:打包进镜像的 Linux 操作系统的体积。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值