- 撤销(Ctrl+Z)
- 重做(Ctrl+Y)
- 清空
- H 标题(Ctrl+1~6)
- 一级标题
- 二级标题
- 三级标题
- 四级标题
- 五级标题
- 六级标题
- 插入提示
- 提示
- 注意
- 警告
- 详细信息
- 粗体(Ctrl+B)
- 斜体(Ctrl+I)
- 删除线
- 插入引用(Ctrl+Q)
- 无序列表(Ctrl+U)
- 有序列表(Ctrl+O)
- 表格
- 插入分割线
- 插入链接(Ctrl+L)
- 插入图片
- 添加图片链接
- 插入代码块
- 关闭同步滚动
- 全屏(按ESC还原)
- 开启预览
<div class="markdown_body"><p>在服务端一般使用 node 来运行 js ,除了 node 外流行的还有 bun/deno 。</p> <p>但这三个运行时的打包体积都不小,在精简的情况下也在 50 mb 以上,我在这里记录一下我是如何将一个原来使用 node 开发的服务迁移为 3.78MB 的 docker 镜像。</p> <p><img alt="image-20240831145324-mzsh9nq" class="embedded_image" loading="lazy" referrerpolicy="no-referrer" rel="noreferrer" src="https://shenzilong.cn/assets/image-20240831145324-mzsh9nq.png"></p> <p><a href="https://hub.docker.com/layers/llej0/web-font/latest/images/sha256-ebb8bb18d33844f27ca02d632c2ebf584435fffae28be2c9416baa86a8de45be?context=repo" rel="nofollow">https://hub.docker.com/layers/llej0/web-font/latest</a></p> <h2>选择 js 运行时 (<a href="https://github.com/awslabs/llrt" rel="nofollow">llrt</a>)</h2> <p>要实现这么小的镜像肯定不能再使用 node 这种等级的 js 运行时了,现在最流行的轻量级 js 运行时可以锁定为 <a href="https://github.com/quickjs-zh/QuickJS" rel="nofollow">QuickJS</a></p> <p>我要迁移的项目是我之前写的一个字体裁剪工具 <a href="https://github.com/2234839/web-font" rel="nofollow">web-font</a> , 它除了纯 js 的部分外还涉及到文件读写和 http server 部分的 api ,QuickJS 作为纯粹的解释器是没有这方面的 api 的。</p> <p>现有的比较成熟的基于 QuickJS 实现的微型 js 运行时有 <a href="https://github.com/saghul/txiki.js" rel="nofollow">txiki.js</a> 和 <a href="https://github.com/awslabs/llrt" rel="nofollow">llrt</a> , 经过实践发现 llrt 可以完美运行在 docker 中 ,txiki.js 则没那么方便 (按照文档编译出来的 tjs 还会依赖其他库)</p> <p>所以我选择使用 llrt 来作为运行时。</p> <h2>迁移遇到的问题</h2> <p>主要问题是 llrt 没有提供 http 模块( tixiki.js 也是), 幸运的是它提供了 net 模块</p> <p>所以我基于 net.createServer 手搓了一个<a href="https://github.com/2234839/web-font/blob/new/backend/server/tcp_server.ts" rel="nofollow">简易 http 服务</a>和洋葱路由 <a href="https://github.com/2234839/web-font/blob/new/backend/server/server.ts" rel="nofollow">server.ts</a> 。</p> <p>这期间还发现了 llrt 一个 cpu 占用异常:<a href="https://github.com/awslabs/llrt/issues/546" rel="nofollow">https://github.com/awslabs/llrt/issues/546</a></p> <h2>打包微小体积的 docker 镜像</h2> <h3>1. 代码打包</h3> <p>这方面我使用的是 tsup 将 ts 源码打包为一个 js 文件。</p> <p>然后使用 llrt compile 命令将 js 文件编译为 .lrt 文件(这一步也能减少差不多 30%的体积)</p> <h3>2. Dockerfile</h3> <p>得益于 llrt ,可以不用依赖任何环境,直接使用 <code>FROM scratch</code> 来得到最小的 docker 镜像体积</p> <pre><code class="language-dockerfile">FROM scratch WORKDIR /home/ COPY dist_backend/app.lrt /home/app.lrt COPY llrt /home/llrt COPY dist/ /home/dist/ CMD ["/home/llrt", "/home/app.lrt"] </code></pre> <p>再经过 docker 的压缩后就得到了 3.78MB 这个数字。</p> <h2>使用情况</h2> <p>llrt 的运行速度比 node 还是慢了许多,在我这个场景下它比 node 要慢上两倍,gc 的运行速度也要慢许多。</p> <p>但初始内存占用和启动速度是碾压 node 的。</p> <p>由于运行时还不是特别完善的问题,很容易踩坑,所以除非你急需压缩 js 的运行内存占用/冷启动速度或者和我一样就是想要这么做,还是建议直接使用 node 吧。</p> </div>
在服务端一般使用 node 来运行 js ,除了 node 外流行的还有 bun/deno 。
但这三个运行时的打包体积都不小,在精简的情况下也在 50 mb 以上,我在这里记录一下我是如何将一个原来使用 node 开发的服务迁移为 3.78MB 的 docker 镜像。

https://hub.docker.com/layers/llej0/web-font/latest
选择 js 运行时 (llrt)
要实现这么小的镜像肯定不能再使用 node 这种等级的 js 运行时了,现在最流行的轻量级 js 运行时可以锁定为 QuickJS
我要迁移的项目是我之前写的一个字体裁剪工具 web-font , 它除了纯 js 的部分外还涉及到文件读写和 http server 部分的 api ,QuickJS 作为纯粹的解释器是没有这方面的 api 的。
现有的比较成熟的基于 QuickJS 实现的微型 js 运行时有 txiki.js 和 llrt , 经过实践发现 llrt 可以完美运行在 docker 中 ,txiki.js 则没那么方便 (按照文档编译出来的 tjs 还会依赖其他库)
所以我选择使用 llrt 来作为运行时。
迁移遇到的问题
主要问题是 llrt 没有提供 http 模块( tixiki.js 也是), 幸运的是它提供了 net 模块
所以我基于 net.createServer 手搓了一个简易 http 服务和洋葱路由 server.ts 。
这期间还发现了 llrt 一个 cpu 占用异常:https://github.com/awslabs/llrt/issues/546
打包微小体积的 docker 镜像
1. 代码打包
这方面我使用的是 tsup 将 ts 源码打包为一个 js 文件。
然后使用 llrt compile 命令将 js 文件编译为 .lrt 文件(这一步也能减少差不多 30%的体积)
2. Dockerfile
得益于 llrt ,可以不用依赖任何环境,直接使用 FROM scratch 来得到最小的 docker 镜像体积
FROM scratch
WORKDIR /home/
COPY dist_backend/app.lrt /home/app.lrt
COPY llrt /home/llrt
COPY dist/ /home/dist/
CMD ["/home/llrt", "/home/app.lrt"]
再经过 docker 的压缩后就得到了 3.78MB 这个数字。
使用情况
llrt 的运行速度比 node 还是慢了许多,在我这个场景下它比 node 要慢上两倍,gc 的运行速度也要慢许多。
但初始内存占用和启动速度是碾压 node 的。
由于运行时还不是特别完善的问题,很容易踩坑,所以除非你急需压缩 js 的运行内存占用/冷启动速度或者和我一样就是想要这么做,还是建议直接使用 node 吧。
user1 • • 目录导航
|
user2 • • 目录导航
|
user3 • • 目录导航
|
user1 • • 目录导航
|
@nt0p https://stackoverflow.com/questions/65181012/does-alpine-have-known-dns-issue-within-kubernetes
还有 https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/dns-debugging-resolution/
<br>如果你使用 Alpine 3.17 或更早版本作为你的基础镜像,DNS 可能会由于 Alpine 的设计问题而无法工作。 在 musl 1.24 版本之前,DNS 存根解析器都没有包括 TCP 回退, 这意味着任何超过 512 字节的 DNS 调用都会失败。请将你的镜像升级到 Alpine 3.18 或更高版本。<br>这个问题应该已经修复了