主题
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*
*.logDocker 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 或日志平台统一收集。
