Chapter 10

生产部署与生态

把 Bun 应用稳稳部署到容器化生产环境——镜像、多进程、内存控制、监控,一并拉通。

10.1 官方 Docker 镜像

Bun 提供官方镜像 oven/bun

tag说明体积
oven/bun:1最新 stable,基于 Debian~120MB
oven/bun:1-slim瘦身版 Debian~80MB
oven/bun:1-alpineAlpine(实验,小但 DNS 等有差异)~55MB
oven/bun:1-distroless无 shell,极简,安全~60MB
oven/bun:canary每日构建

10.2 最小 Dockerfile

FROM oven/bun:1 AS base
WORKDIR /app

# 先装依赖(层缓存)
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile

# 拷贝源码
COPY . .

ENV NODE_ENV=production
EXPOSE 3000
CMD ["bun", "src/server.ts"]

10.3 多阶段构建:只留产物

FROM oven/bun:1 AS builder
WORKDIR /app
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile
COPY . .
RUN bun build src/server.ts --target=bun --outdir dist

FROM oven/bun:1-distroless
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["bun", "dist/server.js"]

10.4 --smol:低内存模式

容器跑在内存受限环境(Cloud Run、Fly.io、低配 VPS)时加 --smol

CMD ["bun", "--smol", "dist/server.js"]

效果:使用更激进的 GC,牺牲少量吞吐换取更低的驻留内存(RSS 降低 30-50%)。

10.5 多进程:node:cluster

要利用多核:

import cluster from "node:cluster";
import os from "node:os";

if (cluster.isPrimary) {
  for (let i = 0; i < os.availableParallelism(); i++) {
    cluster.fork();
  }
  cluster.on("exit", (w) => {
    console.error(`worker ${w.process.pid} died, restarting`);
    cluster.fork();
  });
} else {
  await import("./server.ts");
}

Bun 1.2 起 Bun.serve 支持 reusePort: true 让多进程共享端口,内核层面负载均衡。

10.6 docker-compose 示例

services:
  api:
    image: my-api:latest
    build: .
    ports: ["3000:3000"]
    env_file: .env.production
    restart: unless-stopped
    deploy:
      resources:
        limits: { cpus: '1.0', memory: 512M }

  redis:
    image: redis:7-alpine
    restart: unless-stopped

10.7 健康检查

HEALTHCHECK --interval=10s --timeout=3s --retries=3 \
  CMD bun -e 'fetch("http://localhost:3000/health").then(r=>process.exit(r.ok?0:1))' || exit 1

10.8 生态框架

ElysiaJS

TS 原生、端到端类型安全、插件生态丰富,类 tRPC + Hono 的组合体:

import { Elysia, t } from "elysia";

const app = new Elysia()
  .get("/", () => "hi")
  .post("/users", ({ body }) => ({ created: body }), {
    body: t.Object({ name: t.String(), age: t.Number() }),
  })
  .listen(3000);

export type App = typeof app;    // 客户端可复用这个类型

Hono

多运行时(Bun/Node/Deno/Workers/Lambda),极简 API:

import { Hono } from "hono";
const app = new Hono()
  .get("/", (c) => c.text("hi"))
  .get("/json", (c) => c.json({ hello: "world" }));

export default { port: 3000, fetch: app.fetch };

其他值得关注

10.9 监控与观测

OpenTelemetry 支持已有,但成熟度低于 Node。生产推荐:

10.10 何时选 Bun(决策清单)

强烈推荐

谨慎评估

先别换

10.11 全书总结

至此 10 章内容完成。Bun 正在重塑整条 JavaScript 工具链——越早用越享受启动秒级、测试毫秒级、部署单文件的现代体验。