楼层: 首页/ 软件技术/ Node.js 全栈实战/ 部署与生产环境:从跑起来到扛住流量
10

部署与生产环境:从跑起来到扛住流量

Deployment & Production

本地跑通不算本事,放到公网上、半夜三点挂了能自动重启、被人攻击能扛住,才算上线。这一章讲进程管理、容器化、环境变量、安全清单和反向代理。

PM2:Node 生产进程管理器

你在终端跑 node app.js,一关终端程序就死了。PM2 是个"保姆":让程序在后台常驻、挂了自动重启、帮你开多个进程利用多核、还能看日志和监控。

# 全局装一次 npm i -g pm2 # 后台启动你的应用,起个名字叫 api pm2 start app.js --name api pm2 list # 看现在跑着哪些进程、状态如何 pm2 logs api # 实时看日志 pm2 restart api # 改完代码重启 pm2 stop api # 停掉 pm2 monit # 看 CPU、内存监控面板

更正式的做法是写一个 ecosystem.config.js 配置文件,把进程数、环境变量、日志路径都写进去,pm2 start ecosystem.config.js 一把起。生产上常用 exec_mode: "cluster" 让 PM2 按 CPU 核数开多个进程,充分利用多核——这就是 Node 单机扩容的关键。

容器化:Docker 一键打包

"我电脑上能跑"的经典难题,Docker 用"把代码+运行环境+依赖整个打包成一个镜像"来解决。核心是一个 Dockerfile:

# Dockerfile —— 多阶段构建,最终镜像很小 FROM node:22-alpine AS build WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # 最终运行镜像,只装生产依赖,用 alpine 极小 FROM node:22-alpine WORKDIR /app COPY --from=build /app . EXPOSE 3000 CMD ["node", "app.js"]

记三个 Docker 要点

① 用 node:alpine:基于极简 Linux 发行版,镜像从 1GB 缩到一两百 MB。

② 一定写 .dockerignore:把 node_modules、.env 排除掉——别把本地 node_modules 打进镜像,里面是按你本机平台编译的,换环境必崩,镜像里重新 npm ci 才对。

③ 多阶段构建:第一阶段装依赖、构建,第二阶段只拷贝成品,镜像干净又小。

环境变量:把密码从代码里抠出去

数据库密码、JWT 密钥这些绝不能写死在代码里——代码一提交到 GitHub,全世界都能看到。正确做法是放环境变量,用 dotenv 包读 .env 文件:

# .env 文件(这个文件要加进 .gitignore,别提交!) # PORT=3000 # DATABASE_URL="mysql://root:密码@localhost/blog" # JWT_SECRET="一串很长的随机字符串" // 代码里这样读(项目最顶部先 import "dotenv/config") import "dotenv/config"; const dbUrl = process.env.DATABASE_URL; const port = process.env.PORT || 3000;
安全底线

① .env 永不进 git,仓库里只放一个 .env.example 示范格式;② 不同环境(开发/测试/生产)用不同的环境变量值;③ 密码这类敏感信息,生产上用云平台的密钥管理服务,而不是明文文件。

生产安全清单:这几条别偷懒

要做的事怎么做
密码绝不明文存用 bcrypt 哈希后再存,登录时比对哈希。千万别自己造加密算法。
认证用 JWT登录后发个 token,后续请求带上,后端验签。配合 Nest 守卫或 Express 中间件。
输入一律校验用 zod 或 class-validator 校验前端传来的每个字段,别信任何用户输入。
防 SQL 注入用占位符/ORM,不拼字符串 SQL(第 8 章讲过)。
防暴力破解用 express-rate-limit 给接口限流,比如一分钟最多 100 次。
安全响应头helmet 中间件一键配齐。
依赖体检定期跑 npm audit,别用过时的有漏洞的包。

性能优化与 Nginx 反向代理

集群模式 cluster → 用满多核
Node 单线程吃不满多核 CPU。用 PM2 cluster 模式开多个进程,或用内置 cluster 模块。
大白话:一台 8 核服务器,开 8 个 Node 进程,吞吐量直接翻几倍。
Redis 缓存 → 别让数据库累死
热点查询结果存 Redis,下次直接从内存拿,不查库。
读多写少的接口,这一招立竿见影。
Nginx 挡在 Node 前面 → 反向代理
公网请求先到 Nginx,它负责:静态文件直接返回、给 Node 做负载均衡、终止 SSL(HTTPS)。
为什么不让 Node 直接面对公网:Nginx 处理静态文件、HTTPS、并发连接远比 Node 专业,还能防 Node 进程被直接暴露。这是标准架构。
记
本章小结

① 上线用 PM2 管进程(挂了自动重启),用 Docker 打包环境,密码走 .env 环境变量。

② 安全红线:密码 bcrypt 哈希、参数化查询、输入校验、限流、helmet。

③ 标准架构:公网 → Nginx(HTTPS/静态/负载均衡)→ PM2 cluster(多个 Node 进程)→ Redis + 数据库。