这篇文章我们将以官方的配置文件作为基础二次修改,将应用的构建过程放在当前系统环境来完成,最后将产物打包成 Docker 镜像,以实现大小优化。
修改配置
想着之前自己部署 NuxtJS 的时候发现它在生产环境下最终运行的是一个 server.mjs
文件,这意味着我或许并不需要安装一大堆 node_modules
依赖,然后再执行 pnpm build && pnpm start
的方式来启动服务。这些最终构建好的代码,小到不足 50MB。
那么 NextJS 可以吗,简单搜索看了下,它是可以做到的。我是从它们官方提供的 Dockerfile 里面找到的这个设置项 output,比较隐蔽。
Next.js can automatically create a
standalone
folder that copies only the necessary files for a production deployment including select files innode_modules
.To leverage this automatic copying you can enable it in your
next.config.js
:
修改成这种模式后,意味着项目生产环境的启动方式不再是 pnpm start
了,继续这样操作的时候 NextJS 的命令行工具也会对此进行提示。
旧版 Dockerfile
那么在此之前我是怎么做的呢,这是项目之前的 Dockerfile
,可以看到构建、运行应用的过程均在里面完成(并非阶段构建),也因此导致最后的镜像略大。
调整后的 Dockerfile
考虑到我司已经在使用 CircleCI 负责构建应用,K8S 只负责打包并运行构建结果即可,我根据官方的 Dockerfile
最终整理出了一份自己的,供各位参考:
这份 Dockerfile
相较于前面的版本,他多出了一个复制 static
(位于项目内 .next/static
) 和 public
(位于项目内 /public
)文件的步骤,据官方描述说是这些文件应由 CDN 处理,但实际情况我们用的 CDN 属于融合 CDN(不知道是不是这么说,类似 CloudFlare 那种自动缓存和回源的),因此不需要额外处理单独托管的静态文件。
因为没有在 Dockerfile
里面安装依赖和构建应用了,因此需要在当前的系统环境下,已经通过 pnpm build
完成 NextJS 的构建过程。
使用 Jenkins 或其他方式
我自己的服务器并没有强大的资源和性能,只有一个机器跑多个服务的使用场景。如果改用传统 Jenkins + SSH + PM2 的部署方式,也是一样轻松了不少,以往需要在运行机器上执行极其缓慢的 pnpm build
也将提前在 Jenkins 机器上完成。通过 SCP 的方式传输构建产物,到运行机器上只需替换掉对应的资源,重启 PM2 就能完成,这里就不再具体提供实现过程了,有需要建议自行尝试摸索。
本文作者:Paul
暂无评论!