前端打包镜像优化
前端应用部署时应该尽量减少镜像体积,这样才能让前端应用真正落实轻量的概念,下面总结一下我们能够想到的优化方案。
使用 node:slim 作为基础镜像
使用 node:slim 压缩后的镜像体积为 50M 左右,但是却包含 node, npm, yarn 等 node 应用所需的基本依赖,对于纯 node 应用使用该镜像是完全没问题的。
但是该镜像为了最小体积把一些有用的命令行工具也给删除了,例如 ps, ping, dig 基础调试诊断工具,所以可以基于 node:slim 加一些基础工具集封装成自己的基础镜像。
Dockerfile 分步打包
众所周知镜像的文件系统是写时复制的,这意味着在打包镜像时镜像体积只能增加不能删除。
所以下面这段代码第三行并不能减少镜像体积,反而还会因为增加镜像层数而增加。
FROM node:slim
RUN npm install && npm run build
RUN rm -rf .git node_modules
但是分步打包能够让我们在构建镜像时执行一些额外的命令,清除临时文件,并且不会增加镜像的层数。
下面这段代码才是真正减少体积的代码
FROM node:slim as temp
RUN npm install && npm run build
RUN rm -rf .git node_modules
FROM node:slim
COPY --from=temp /app /app
分步打包官方文档: docs.docker.com/develop/dev…
只安装 dependences 而不安装 devDependences
同样众所周知 node 端代码运行时只依赖 dependences 而不依赖 devDependences 。目前使用的打包方式如下。
FROM node:slim as temp
RUN npm install
RUN npm run build
RUN rm -rf .git
RUN npm prune --production
FROM node:slim
COPY --from=temp /app /app
这里使用 npm prune --production 移除 devDependenes 的包,可以极大的减少文件体积,但是也需要项目有一个良好约束的 deps, devDeps 的习惯,只将运行时依赖安装在 deps 里,运行时不依赖的包才安装到 devDeps 里。
前端容器提供的服务约定
为了减少不必要的配置成本有一些约定还是需要统一,下面是一些很直观的约定。
容器提供服务为标准的80端口
80 端口为原本的 HTTP 服务端口,我们应用大部分都是 HTTP 应用,所以使用 80 端口应该理直气壮。
在第一条基础上使用 EXPOSE 80 声明服务端口
EXPOSE 指令并不会影响容器的执行,只是一条便签式的指令,用此可以描述我们前端容器服务端口。
使用 CMD 作为程序入口而不是ENTRYPOINT
原因是 CMD 我们可以很容易在本地重写启动脚本,ENTRYPOINT则比较麻烦,而且ENTRYPOINT原生也不是用来做 app 的启动脚本这件事的。但是由于 ENTRYPOINT 也能达到启动脚本的功能,所以依然有人使用 ENTRYPOINT,如果有人弄不懂其中区别还是将此条记录在本篇里。
总结
发现前端方面镜像优化的文章很少,所以稍微总结了一下能够想到的优化方向。