Skip to content

NestJS 部署

NestJS 应用在构建阶段编译 TypeScript,生产镜像只保留编译产物和生产依赖。

监听地址

容器内的应用必须监听 0.0.0.0,否则宿主机无法通过端口映射访问服务:

ts
import { NestFactory } from '@nestjs/core'
import { AppModule } from './app.module'

async function bootstrap() {
  const app = await NestFactory.create(AppModule)

  app.enableShutdownHooks()

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

  await app.listen(port, host)
}

void bootstrap()

Dockerfile

在项目根目录创建 Dockerfile

dockerfile
FROM node:24-alpine AS base

ENV PNPM_HOME=/pnpm
ENV PATH=$PNPM_HOME:$PATH

RUN corepack enable

WORKDIR /app

FROM base AS deps

COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile

FROM deps AS builder

COPY . .
RUN pnpm build

FROM base AS production-deps

COPY package.json pnpm-lock.yaml ./
RUN pnpm install --prod --frozen-lockfile

FROM node:24-alpine AS runner

WORKDIR /app

ENV NODE_ENV=production
ENV HOST=0.0.0.0
ENV PORT=3000

COPY --from=production-deps --chown=node:node /app/node_modules ./node_modules
COPY --from=builder --chown=node:node /app/dist ./dist
COPY --chown=node:node package.json ./

USER node

EXPOSE 3000

CMD ["node", "dist/main.js"]

Nest CLI 的常见入口是 dist/main.js。monorepo 或修改过 tsconfig.build.json 的项目可能生成其他路径,应以实际构建结果为准。

.dockerignore

bash
node_modules
dist
coverage
.git
.env*
*.log

Docker Compose

将项目代码放入部署目录并进入:

bash
mkdir -p ~/apps/nest-api
cd ~/apps/nest-api

创建 compose.yml

yaml
services:
  api:
    build:
      context: .
    image: nest-api
    container_name: nest-api
    restart: unless-stopped
    init: true
    env_file:
      - .env
    ports:
      - '127.0.0.1:3000:3000'

启动服务:

bash
docker compose up -d

绑定到宿主机 127.0.0.1 适用于由同一台服务器上的 Nginx 反向代理访问。需要直接公开端口时改为 3000:3000,并同时配置防火墙和访问控制。

部署注意事项

  • 数据库迁移应在启动新版本前独立执行,失败时不替换正在运行的版本。
  • Prisma、Playwright 等包含生成文件或系统依赖的工具,需要将对应产物和运行库加入生产镜像。
  • 容器停止时,enableShutdownHooks() 可让应用接收终止信号并释放数据库、队列和长连接资源。
  • 日志写入标准输出和标准错误,由 Docker 或日志平台统一收集。

参考

基于 MIT 许可发布