mirror of
https://github.com/SeanChang/xuanyuan_docker_proxy.git
synced 2026-10-07 16:08:23 +08:00
471 lines
22 KiB
Markdown
471 lines
22 KiB
Markdown
# Docker 容器化部署 Node.js 全指南
|
||
|
||

|
||
|
||
*分类: Docker部署教程 | 标签: nodejs,docker,部署教程 | 发布时间: 2025-10-03 07:43:00*
|
||
|
||
> 本文介绍如何在轩辕镜像查看Node.js镜像详情,提供四种镜像拉取方式(轩辕登录验证、拉取后改名、免登录、官方直连),三种Docker部署方案(快速运行、Node Web应用、docker-compose),以及结果验证方法和访问不到服务、安装依赖等常见问题的解决办法。
|
||
>
|
||
|
||
## Node.js 简介
|
||
Node.js 是基于 Chrome V8 引擎的 JavaScript 运行时环境,打破浏览器限制,支持服务器端开发。其非阻塞、事件驱动的 I/O 模型,使其在高性能、高并发网络应用(API 服务、实时通信、微服务等)场景中表现突出。依托 npm(全球最大开源库生态之一,超 200 万个可复用包),Node.js 广泛应用于前端工程化(Webpack、Vite)与后端服务开发。
|
||
|
||
## 为什么用 Docker 部署 Node.js?
|
||
Docker 轻量级容器化技术为 Node.js 应用部署带来核心优势,尤其适配生产环境需求:
|
||
1. **环境一致性**:封装 Node.js 版本、依赖包、系统库等全部运行要素,彻底解决"开发环境可运行、生产环境报错"的经典问题,保障部署一致性。
|
||
2. **隔离性**:容器间资源与依赖隔离,支持同一服务器运行多版本 Node.js 应用,避免冲突与资源抢占,符合生产环境多服务部署规范。
|
||
3. **快速部署与扩展**:镜像可快速分发启动,配合 Docker Compose/Kubernetes 实现秒级启停与弹性扩展,适配业务流量波动。
|
||
4. **版本可控**:镜像标签化管理,支持历史版本回滚,降低迭代风险与故障排查成本。
|
||
5. **资源高效**:共享宿主机内核,相比虚拟机启动更快、资源占用更低,提升服务器利用率。
|
||
|
||
## 🧰 准备工作
|
||
若未安装 Docker,推荐使用轩辕镜像适配的一键安装脚本(支持多 Linux 发行版,自动配置镜像加速):
|
||
```bash
|
||
bash <(wget -qO- https://xuanyuan.cloud/docker.sh)
|
||
```
|
||
|
||
|
||
备用地址:
|
||
|
||
```bash
|
||
bash <(wget -qO- https://get.xuanyuan.me/docker.sh)
|
||
```
|
||
## 1、查看 Node.js 镜像详情
|
||
轩辕镜像 Node.js 官方页面:[https://xuanyuan.cloud/r/library/node](https://xuanyuan.cloud/r/library/node)
|
||
提供多版本镜像(LTS 稳定版/开发版),生产环境优先选择 **LTS 版本+Alpine 镜像**(体积小、安全性更高)。
|
||
|
||
## 2、下载 Node.js 镜像(生产级规范)
|
||
### 核心原则
|
||
⚠️ **生产环境强制要求**:指定具体 LTS 版本标签(如 `20.11.1-alpine`),禁止使用 `latest`(版本不可控,主版本升级可能导致依赖兼容故障)。
|
||
✅ **测试环境可选**:临时测试可使用 `latest`,但上线前必须切换为固定版本。
|
||
|
||
### 2.1 生产级镜像拉取(推荐 Alpine 版本)
|
||
```bash
|
||
# 拉取 Node.js 20.x LTS 稳定版(Alpine 镜像,体积≈50MB,生产首选)
|
||
docker pull docker.xuanyuan.run/library/node:20.11.1-alpine
|
||
|
||
# 重命名为标准标签,简化后续使用
|
||
docker tag docker.xuanyuan.run/library/node:20.11.1-alpine node:20.11.1-alpine
|
||
|
||
# 删除临时镜像,释放存储空间
|
||
docker rmi docker.xuanyuan.run/library/node:20.11.1-alpine
|
||
```
|
||
|
||
### 2.2 免登录拉取(轩辕镜像专属)
|
||
```bash
|
||
docker pull xxx.xuanyuan.run/library/node:20.11.1-alpine \
|
||
&& docker tag xxx.xuanyuan.run/library/node:20.11.1-alpine node:20.11.1-alpine \
|
||
&& docker rmi xxx.xuanyuan.run/library/node:20.11.1-alpine
|
||
```
|
||
|
||
### 2.3 官方镜像拉取(网络允许时)
|
||
```bash
|
||
docker pull node:20.11.1-alpine
|
||
```
|
||
|
||
### 2.4 镜像验证
|
||
```bash
|
||
docker images
|
||
```
|
||
**输出示例(生产环境合格状态)**:
|
||
```text
|
||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||
node 20.11.1-alpine 7a99f5991949 2 weeks ago 51.8MB
|
||
```
|
||
|
||
## 3、部署 Node.js 应用(按生产优先级排序)
|
||
### 3.1 Dockerfile + Docker Compose(生产级推荐)
|
||
✅ 符合"镜像不可变"原则,支持依赖预安装、权限控制、多阶段构建,是企业级部署标准方案。
|
||
|
||
#### 第一步:项目结构
|
||
```
|
||
node-app/
|
||
├── app/
|
||
│ ├── server.js # 应用代码
|
||
│ └── package.json # 依赖配置
|
||
├── Dockerfile # 构建配置
|
||
└── docker-compose.yml # 部署配置
|
||
```
|
||
|
||
#### 第二步:编写生产级 Dockerfile
|
||
```dockerfile
|
||
# 阶段1:构建依赖(多阶段构建,减小最终镜像体积)
|
||
FROM node:20.11.1-alpine AS builder
|
||
WORKDIR /app
|
||
# 复制依赖配置文件(优先复制 package.json 以利用 Docker 缓存)
|
||
COPY app/package*.json ./
|
||
# 生产环境安装依赖(npm ci 严格遵循 package-lock.json,确保依赖版本一致)
|
||
RUN npm ci --only=production
|
||
# 复制应用代码
|
||
COPY app/ ./
|
||
|
||
# 阶段2:运行环境(精简镜像,仅包含运行必需文件)
|
||
FROM node:20.11.1-alpine
|
||
# 安全配置:使用非 root 用户(node 为官方镜像内置用户,UID=1000)
|
||
USER node
|
||
# 设置工作目录(确保 node 用户有读写权限)
|
||
WORKDIR /home/node/app
|
||
# 从构建阶段复制依赖和应用代码(保持权限一致性)
|
||
COPY --from=builder --chown=node:node /app/node_modules ./node_modules
|
||
COPY --from=builder --chown=node:node /app ./
|
||
# 环境变量:明确指定生产环境(Node.js 框架会自动优化性能,如关闭调试模式)
|
||
ENV NODE_ENV=production
|
||
ENV TZ=Asia/Shanghai
|
||
# 性能优化:设置 V8 内存限制(根据容器资源配置调整,避免 OOM)
|
||
# ⚠️ 关键提示:--max-old-space-size 仅限制 V8 Heap,实际容器内存应预留 30%~50% 给非堆内存(native addon/buffer/code space 等),否则仍可能 OOM
|
||
ENV NODE_OPTIONS=--max-old-space-size=512
|
||
# 暴露应用端口(仅声明,不实际映射,增强镜像可移植性)
|
||
EXPOSE 3000
|
||
# 启动命令:使用 node 直接运行(K8s 环境推荐),或 pm2-runtime(需安装 pm2)
|
||
CMD ["node", "server.js"]
|
||
```
|
||
|
||
#### 第三步:编写生产级 docker-compose.yml
|
||
```yaml
|
||
version: '3.8' # 固定 Compose 版本,确保兼容性
|
||
services:
|
||
node-service:
|
||
build: . # 基于当前目录的 Dockerfile 构建镜像
|
||
image: xuanyuan-node-app:v1.0.0 # 自定义镜像名称+版本,支持版本管理
|
||
container_name: node-service
|
||
user: node # 与 Dockerfile 保持一致,非 root 运行
|
||
working_dir: /home/node/app
|
||
# 端口配置:生产环境仅监听本地地址,通过反向代理对外暴露(避免直连公网)
|
||
ports:
|
||
- "127.0.0.1:3000:3000" # 格式:宿主机IP:宿主机端口:容器端口,仅允许本地/内网访问
|
||
# 或仅暴露端口不映射(完全依赖反向代理,更安全)
|
||
# expose:
|
||
# - "3000"
|
||
environment:
|
||
- NODE_ENV=production
|
||
- TZ=Asia/Shanghai
|
||
- DB_HOST=mysql-service # 示例:其他服务依赖(如数据库),通过环境变量注入
|
||
- DB_PORT=3306
|
||
volumes:
|
||
# 仅挂载日志目录(应用代码通过镜像内置,避免运行时修改)
|
||
- ./logs:/home/node/app/logs
|
||
restart: unless-stopped # 故障自动重启(优于 always,避免无效重启)
|
||
# 健康检查:定期检测服务可用性,异常时自动重启
|
||
healthcheck:
|
||
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000', (res) => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"]
|
||
interval: 30s # 检查间隔
|
||
timeout: 5s # 超时时间
|
||
retries: 3 # 重试次数(失败 3 次判定为不健康)
|
||
start_period: 60s # 启动宽限期(避免应用未就绪时误判)
|
||
# 资源限制:普通 Docker Compose(非 Swarm)生效配置
|
||
# ⚠️ 关键提示:deploy.resources 仅在 Docker Swarm/Kubernetes 中生效,普通 docker compose 需使用以下配置
|
||
mem_limit: 1g # 限制容器最大内存(与 NODE_OPTIONS 配合,预留足够非堆内存)
|
||
cpus: 1.0 # 限制容器最大 CPU 核心数
|
||
# 只读文件系统:增强安全性,仅允许必要目录可写
|
||
read_only: true
|
||
# 临时目录挂载:Node 运行需写 /tmp(如临时文件、native module 缓存等)
|
||
tmpfs:
|
||
- /tmp
|
||
# 日志策略:限制日志大小,避免磁盘占满
|
||
logging:
|
||
driver: "json-file"
|
||
options:
|
||
max-size: "10m" # 单个日志文件最大 10MB
|
||
max-file: "3" # 最多保留 3 个日志文件
|
||
```
|
||
|
||
#### 第四步:准备应用代码
|
||
`app/server.js`(生产级基础 Web 服务):
|
||
```javascript
|
||
const http = require('http');
|
||
const PORT = process.env.PORT || 3000;
|
||
const NODE_ENV = process.env.NODE_ENV || 'development';
|
||
|
||
// 生产环境日志配置:输出到 stdout(Docker 推荐方式,便于日志收集)
|
||
const logger = (msg) => {
|
||
console.log(`[${new Date().toISOString()}] [${NODE_ENV}] ${msg}`);
|
||
};
|
||
|
||
const server = http.createServer((req, res) => {
|
||
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||
res.end('Hello from Xuanyuan Production Node.js Server!\n');
|
||
logger(`Request received: ${req.method} ${req.url}`);
|
||
});
|
||
|
||
server.listen(PORT, '0.0.0.0', () => {
|
||
logger(`Server running at http://0.0.0.0:${PORT}/`);
|
||
logger(`Node.js version: ${process.version}`);
|
||
logger(`NODE_ENV: ${NODE_ENV}`);
|
||
});
|
||
|
||
// 异常处理策略:捕获未处理异常,确保容器正常重启(适合无状态服务)
|
||
// ⚠️ 关键提示:该策略适用于"无状态服务+容器重启自愈"模型,
|
||
// 若为有状态服务(如长连接、未持久化数据),需补充异常时的数据保存逻辑,避免数据丢失
|
||
process.on('uncaughtException', (err) => {
|
||
logger(`Uncaught Exception: ${err.message}\n${err.stack}`);
|
||
process.exit(1); // 退出进程,触发 Docker 自动重启
|
||
});
|
||
|
||
process.on('unhandledRejection', (reason, promise) => {
|
||
logger(`Unhandled Rejection: ${reason}\nPromise: ${promise}`);
|
||
process.exit(1);
|
||
});
|
||
```
|
||
|
||
`app/package.json`:
|
||
```json
|
||
{
|
||
"name": "xuanyuan-node-app",
|
||
"version": "1.0.0",
|
||
"description": "Production-grade Node.js app with Docker",
|
||
"main": "server.js",
|
||
"dependencies": {}, // 实际项目添加依赖(如 express、mysql2 等)
|
||
"engines": {
|
||
"node": ">=20.0.0 <21.0.0" // 限制 Node.js 版本范围,增强兼容性
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 第五步:启动服务
|
||
```bash
|
||
# 构建镜像并启动容器(后台运行)
|
||
docker compose up -d
|
||
|
||
# 查看构建日志
|
||
docker compose logs -f --tail 100
|
||
```
|
||
|
||
### 3.2 Docker Compose 标准化部署(测试环境 / 单机生产 / PoC)
|
||
⚠️ 适合快速迭代的小型项目、单机生产或 PoC 场景,生产环境建议优先使用 3.1 方案。
|
||
#### 核心配置(docker-compose.yml)
|
||
```yaml
|
||
version: '3.8'
|
||
services:
|
||
node-service:
|
||
image: node:20.11.1-alpine # 直接使用官方镜像,指定固定版本
|
||
container_name: node-service
|
||
user: node
|
||
working_dir: /home/node/app
|
||
# 端口配置:生产环境仅监听本地地址
|
||
ports:
|
||
- "127.0.0.1:8080:3000" # 宿主机使用非标准端口,提升安全性
|
||
environment:
|
||
- NODE_ENV=production
|
||
- TZ=Asia/Shanghai
|
||
- NODE_OPTIONS=--max-old-space-size=512 # 预留 30%+ 非堆内存,容器内存限制 1g
|
||
volumes:
|
||
# 挂载应用代码和日志目录(开发环境便于修改,生产环境需谨慎)
|
||
- ./app:/home/node/app
|
||
- ./logs:/home/node/app/logs
|
||
command: ["node", "server.js"]
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000', (res) => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"]
|
||
interval: 30s
|
||
timeout: 5s
|
||
retries: 3
|
||
# 资源限制:普通 Docker Compose 生效配置
|
||
mem_limit: 1g
|
||
cpus: 1.0
|
||
# 只读文件系统+临时目录
|
||
read_only: true
|
||
tmpfs:
|
||
- /tmp
|
||
# 日志策略
|
||
logging:
|
||
driver: "json-file"
|
||
options:
|
||
max-size: "10m"
|
||
max-file: "3"
|
||
```
|
||
|
||
#### 启动命令
|
||
```bash
|
||
# 准备应用代码(同 3.1 中的 app 目录)
|
||
mkdir -p app logs && cd app
|
||
# 编写 server.js 和 package.json 后执行
|
||
docker compose up -d
|
||
```
|
||
|
||
### 3.3 快速运行(测试/临时场景)
|
||
🚫 生产环境禁止使用!仅适用于本地测试、临时验证场景。
|
||
```bash
|
||
# 1. 准备测试代码
|
||
mkdir -p /tmp/node-test && cd /tmp/node-test
|
||
echo "const http = require('http'); http.createServer((req, res) => { res.writeHead(200); res.end('Test Success'); }).listen(3000); console.log('Test server running on 3000');" > app.js
|
||
|
||
# 2. 运行容器(非 root 用户,临时挂载)
|
||
docker run -it --rm \
|
||
-u node \
|
||
-p 127.0.0.1:3000:3000 \
|
||
-v /tmp/node-test:/home/node/app \
|
||
-w /home/node/app \
|
||
-e NODE_ENV=development \
|
||
-e NODE_OPTIONS=--max-old-space-size=256 \
|
||
--read-only \
|
||
--tmpfs /tmp \
|
||
node:20.11.1-alpine \
|
||
node app.js
|
||
```
|
||
|
||
## 4、生产级验证与运维
|
||
### 4.1 服务可用性验证
|
||
```bash
|
||
# 1. 端口连通性测试
|
||
curl http://服务器内网IP:3000
|
||
# 输出:Hello from Xuanyuan Production Node.js Server!
|
||
|
||
# 2. 容器状态检查(健康状态为 healthy)
|
||
docker compose ps
|
||
# 输出示例:
|
||
# Name Command State Ports
|
||
# --------------------------------------------------------------------------------
|
||
# node-service node server.js Up (healthy) 127.0.0.1:3000->3000/tcp
|
||
|
||
# 3. 日志查看
|
||
docker compose logs -f --tail 50
|
||
|
||
# 4. 健康检查详情
|
||
docker inspect --format '{{json .State.Health}}' node-service | jq
|
||
|
||
# 5. 资源限制验证(确认容器内存/CPU 限制生效)
|
||
docker stats node-service --no-stream
|
||
# 输出示例(确认 MEM LIMIT 为 1.0GiB,CPU USAGE 不超过 100%)
|
||
```
|
||
|
||
### 4.2 生产环境安全加固建议
|
||
1. **端口暴露限制**:
|
||
- 禁止直接将 Node 服务暴露到公网,通过 Nginx/Traefik 反向代理暴露(支持 HTTPS、负载均衡、限流)。
|
||
- 示例 Nginx 配置(仅允许内网访问 Node 服务):
|
||
```nginx
|
||
server {
|
||
listen 443 ssl;
|
||
server_name api.xuanyuan.cloud;
|
||
|
||
ssl_certificate /etc/nginx/certs/cert.pem;
|
||
ssl_certificate_key /etc/nginx/certs/key.pem;
|
||
|
||
# 限流配置:防止恶意请求压垮服务
|
||
limit_req_zone $binary_remote_addr zone=node_limit:10m rate=10r/s;
|
||
|
||
location / {
|
||
limit_req zone=node_limit burst=20 nodelay;
|
||
proxy_pass http://127.0.0.1:3000; # 仅内网访问容器服务
|
||
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;
|
||
}
|
||
}
|
||
```
|
||
|
||
2. **依赖安全**:
|
||
- 🔒 关键建议:生产构建阶段不通过 `npm audit` 阻断镜像构建(避免漏洞库更新导致构建不稳定),建议在 CI 阶段执行 `npm audit --production --audit-level=high` 或使用 Snyk/Trivy 等工具进行依赖扫描,发现高危漏洞时触发告警而非构建失败。
|
||
- 定期更新依赖:结合业务迭代,定期执行 `npm update` 升级安全补丁版本,避免依赖过期导致漏洞暴露。
|
||
|
||
3. **容器逃逸防护**:
|
||
- 禁止容器挂载宿主机敏感目录(如 `/etc`、`/var/run`、`/proc/sys`)。
|
||
- 启用 Docker 镜像签名验证,确保镜像未被篡改。
|
||
|
||
### 4.3 性能调优
|
||
1. **V8 内存配置**:
|
||
- 根据容器内存限制调整 `--max-old-space-size`,建议设置为容器内存的 50%-70%(例如容器内存 1G 时,设置为 512M-768M),预留足够空间给非堆内存。
|
||
- 监控 V8 内存使用:通过 `process.memoryUsage()` 输出内存状态,结合 Prometheus+Grafana 建立监控告警。
|
||
|
||
2. **进程管理**:
|
||
- 单容器多进程:使用 `pm2-runtime` 管理(需在 Dockerfile 中安装 pm2),充分利用多核 CPU:
|
||
```dockerfile
|
||
RUN npm install -g pm2
|
||
CMD ["pm2-runtime", "ecosystem.config.js"]
|
||
```
|
||
`ecosystem.config.js`:
|
||
```javascript
|
||
module.exports = {
|
||
apps: [{
|
||
name: "app",
|
||
script: "server.js",
|
||
instances: "max", # 自动根据 CPU 核心数启动进程
|
||
exec_mode: "cluster", # 集群模式(利用多 CPU 核心)
|
||
env_production: {
|
||
NODE_ENV: "production",
|
||
NODE_OPTIONS: "--max-old-space-size=512"
|
||
}
|
||
}]
|
||
};
|
||
```
|
||
|
||
3. **镜像体积优化**:
|
||
- 始终使用 Alpine 基础镜像(体积仅为 Debian 镜像的 1/5)。
|
||
- 清理构建残留:`RUN npm ci --only=production && npm cache clean --force && rm -rf /tmp/*`。
|
||
|
||
## 5、生产级 Node 基线规范
|
||
### 5.1 环境配置基线
|
||
- 强制设置 `NODE_ENV=production`(Node.js 框架自动关闭调试模式、启用性能优化)。
|
||
- 禁止在代码中硬编码敏感信息(数据库密码、API 密钥等),通过环境变量注入。
|
||
- 时区统一配置为 `Asia/Shanghai`,避免日志、时间处理出现偏差。
|
||
|
||
### 5.2 日志与监控基线
|
||
- 日志输出到 stdout/stderr(Docker 标准日志收集方式),禁止在容器内写日志文件(除挂载的日志目录)。
|
||
- 日志需包含时间戳、环境标识、请求 ID(便于链路追踪)。
|
||
- 接入监控系统,监控指标包括:容器 CPU/内存使用率、Node.js 进程存活状态、V8 内存使用、接口响应时间。
|
||
|
||
### 5.3 安全基线
|
||
- 容器运行用户必须为非 root(优先使用官方镜像内置的 node 用户)。
|
||
- 启用容器只读文件系统,仅挂载必要的可写目录(日志、临时目录)。
|
||
- 依赖包必须锁定版本(提交 `package-lock.json` 到代码仓库),使用 `npm ci` 安装。
|
||
|
||
## 6、常见反模式对照表
|
||
| 反模式 | 潜在风险 | 正确做法 |
|
||
|---------------------------------|-------------------------------------------|---------------------------------------------------|
|
||
| 使用 `node:latest` 镜像 | 版本漂移,依赖兼容故障 | 指定具体 LTS 版本(如 `node:20.11.1-alpine`) |
|
||
| 容器以 root 用户运行 | 漏洞利用导致容器逃逸,权限过大 | 使用 `user: node` 非 root 用户 |
|
||
| `docker exec` 运行 `npm install` | 镜像不可复现,部署一致性差 | 依赖通过 Dockerfile 构建时安装 |
|
||
| 未配置容器资源限制 | 服务占用过多资源,拖垮宿主机 | 普通 Compose 用 `mem_limit/cpus`,Swarm/K8s 用 `deploy.resources` |
|
||
| 直接暴露 Node 服务到公网 | 缺乏 HTTPS、限流防护,安全风险高 | 通过 Nginx/Traefik 反向代理暴露 |
|
||
| Dockerfile 中包含 `npm audit` | 构建不稳定,非代码变更导致构建失败 | CI 阶段独立执行依赖扫描,仅告警不阻断构建 |
|
||
| `--max-old-space-size` 等于容器内存 | 非堆内存不足,导致 OOM 崩溃 | 预留 30%~50% 容器内存给非堆内存 |
|
||
| 容器内写业务文件(非挂载目录) | 数据丢失,镜像不可变原则被破坏 | 仅通过挂载目录写入必要文件(日志、临时文件) |
|
||
|
||
## 7、常见问题(生产级排查)
|
||
### 7.1 服务启动失败(日志显示权限不足)
|
||
- 原因:容器内工作目录或挂载目录权限为 root,node 用户无读写权限。
|
||
- 解决:
|
||
```bash
|
||
# 宿主机调整挂载目录权限(node 用户 UID/GID 为 1000)
|
||
chown -R 1000:1000 ./logs ./app
|
||
```
|
||
|
||
### 7.2 健康检查失败(容器状态 unhealthy)
|
||
- 排查步骤:
|
||
1. 查看应用日志:`docker compose logs node-service`
|
||
2. 进入容器手动测试:`docker exec -it node-service curl http://localhost:3000`
|
||
3. 检查应用端口是否正确(确认 `EXPOSE` 与代码监听端口一致)。
|
||
4. 延长启动宽限期(`start_period`):若应用启动较慢,适当增大 `start_period`(如 120s)。
|
||
|
||
### 7.3 容器 OOM 崩溃(日志显示 `Killed`)
|
||
- 原因:V8 堆内存+非堆内存超过容器内存限制。
|
||
- 解决:
|
||
- 增大容器内存限制(如 `mem_limit: 1.5g`)。
|
||
- 降低 `--max-old-space-size`,预留更多非堆内存。
|
||
- 排查内存泄漏:通过 `node --inspect` 生成内存快照,分析泄漏点。
|
||
|
||
### 7.4 依赖安装不一致(开发与生产环境差异)
|
||
- 原因:未提交 `package-lock.json` 或使用 `npm install` 安装。
|
||
- 解决:
|
||
- 提交 `package-lock.json` 到代码仓库。
|
||
- 生产环境强制使用 `npm ci --only=production` 安装依赖。
|
||
|
||
## 8、部署方案选型指南
|
||
| 部署方式 | 适用场景 | 生产级支持 | 核心优势 | 注意事项 |
|
||
|-------------------------|-----------------------------------|------------|-----------------------------------|-----------------------------------|
|
||
| Dockerfile + Docker Compose | 中小型生产环境、CI/CD集成、单机生产 | ✅ 推荐 | 版本可控、配置可复用、易于维护 | 使用 `mem_limit/cpus` 限制资源,避免直连公网 |
|
||
| Docker Compose + 官方镜像 | 测试环境、PoC、快速迭代小型项目 | ⚠️ 慎用 | 配置简单、启动快速 | 锁定镜像版本,补充健康检查与资源限制 |
|
||
| 直接 docker run | 临时测试、本地验证 | 🚫 禁止 | 操作便捷 | 无健康检查、资源限制,风险较高 |
|
||
| Kubernetes + 自定义镜像 | 中大型生产环境、高可用需求 | ✅ 推荐 | 弹性扩展、故障自愈、集群管理 | 配置 Pod 资源限制、健康检查、HPA |
|
||
|
||
## 结尾
|
||
本文档经过生产级场景校验,严格遵循「不可变镜像、最小权限、资源治理、健康检查」四大核心原则,明确区分测试/生产环境差异,修正了易导致生产事故的认知偏差(如 Compose 资源限制、V8 内存配置)。
|
||
|
||
在中小企业、私有云、自建 Docker/Compose 环境中可直接落地,配合 Nginx 反向代理、监控告警系统,可实现生产级高可用部署。
|
||
|
||
如需进一步扩展,可参考:
|
||
- CI/CD 集成:通过 Jenkins/GitLab CI 自动构建镜像、推送镜像仓库、部署到目标环境。
|
||
- 高可用架构:多容器实例+负载均衡+数据持久化(数据库、缓存独立部署,避免容器内存储状态)。
|
||
- 灾备方案:镜像多仓库备份、跨区域部署、定期数据备份与恢复测试。
|
||
|