# Node.js 部署

URL: https://caijiao.org/hono/05-deploy/01-nodejs
Source: docs/hono/05-deploy/01-nodejs.md
Description: 学习 Hono 在 Node.js 中的启动方式、端口配置、优雅关闭、Docker 和反向代理部署要点。

Hono 在 Node.js 中通过 `@hono/node-server` 运行。部署时重点关注端口、进程管理、优雅关闭、日志和反向代理。

## 启动入口

```ts
import { serve } from '@hono/node-server'
import { Hono } from 'hono'

const app = new Hono()

app.get('/health', (c) => c.json({ ok: true }))

const port = Number(process.env.PORT ?? '3000')

const server = serve({
  fetch: app.fetch,
  port,
})

console.log(`Server is running on http://localhost:${port}`)
```

## 优雅关闭

Node.js 中 `serve()` 返回底层 server 实例。收到退出信号时应主动关闭：

```ts
process.on('SIGINT', () => {
  server.close()
  process.exit(0)
})

process.on('SIGTERM', () => {
  server.close((err) => {
    if (err) {
      console.error(err)
      process.exit(1)
    }

    process.exit(0)
  })
})
```

这能减少部署重启时的连接中断和未完成请求。

## package.json 脚本

```json
{
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "build": "tsc",
    "start": "node dist/index.js"
  }
}
```

生产环境不要直接用 watch 命令启动。

## Docker 示例

```dockerfile
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile

FROM node:22-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN corepack enable && pnpm build

FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY package.json pnpm-lock.yaml ./
COPY --from=deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/index.js"]
```

如果项目依赖原生模块，构建镜像和运行镜像的系统环境要保持兼容。

## Nginx 反向代理

```nginx
server {
  listen 80;
  server_name api.example.com;

  location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}
```

反向代理层可以处理 HTTPS、压缩、访问日志和限流。应用层仍然应该做好鉴权和输入验证。

## 部署检查清单

- `PORT`、数据库连接、JWT 密钥等配置已通过环境变量提供。
- `/health` 或 `/ready` 健康检查可用。
- 进程收到 `SIGTERM` 可以优雅退出。
- 日志包含请求方法、路径、状态码、耗时和错误信息。
- 反向代理正确传递 `Host`、`X-Forwarded-*` 头。
