Docker Compose 部署 Node.js 项目
Docker Compose 是部署 Node.js 项目的理想工具,它可以通过一个简单的 YAML 文件定义和运行多容器应用。下面我将详细介绍如何使用 Docker Compose 部署 Node.js 项目,包括基础配置、开发与生产环境优化以及常见问题解决方案。
1. 项目准备与基础配置
1.1 项目结构准备
一个典型的 Node.js 项目结构如下:
my-node-app/
├── src/
│ └── app.js # 应用入口文件
├── package.json # 项目依赖
├── Dockerfile # 构建镜像配置
└── docker-compose.yml # 服务编排配置
1.2 创建基础 Node.js 应用
在src/app.js
中添加一个简单的 Express 应用示例:
javascript
const express = require("express");
const app = express();
const PORT = process.env.PORT || 3000;
app.get("/", (req, res) => {
res.send("Node.js in Docker with Compose!");
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
在package.json
中配置脚本和依赖:
json
{
"name": "nodejs-docker",
"version": "1.0.0",
"main": "src/app.js",
"scripts": {
"start": "node src/app.js",
"dev": "nodemon src/app.js"
},
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^3.1.0"
}
}
2. Docker 相关配置
2.1 创建 Dockerfile
在项目根目录创建Dockerfile
,建议使用多阶段构建优化镜像大小:
dockerfile
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build # 如果有构建步骤
# 生产阶段
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/dist ./dist # 如果有构建产物
COPY --from=builder /app/src ./src # 复制源代码
EXPOSE 3000
CMD ["npm", "start"]
2.2 创建 docker-compose.yml
在项目根目录创建docker-compose.yml
文件:
yaml
version: "3.8"
services:
node-app:
build: .
container_name: my-node-app
ports:
- "3000:3000"
environment:
- NODE_ENV=development
- TZ=Asia/Shanghai
volumes:
- ./src:/app/src # 开发时代码同步
- /app/node_modules # 避免覆盖容器内的依赖
restart: unless-stopped
command: npm run dev # 开发时使用nodemon
3. 启动与验证
3.1 启动容器
运行以下命令构建并启动容器:
bash
docker-compose up --build -d
3.2 验证运行
查看日志确认应用是否正常启动:
bash
docker-compose logs -f
访问http://localhost:3000
应该能看到"Node.js in Docker with Compose!"的响应。
4. 环境配置优化
4.1 开发环境配置
对于开发环境,可以启用热更新和调试支持:
yaml
services:
node-app:
# ...其他配置
volumes:
- ./:/app # 挂载整个项目目录
- /app/node_modules
command: npm run dev
environment:
- NODE_ENV=development
- DEBUG=express:*
ports:
- "3000:3000"
- "9229:9229" # Node.js调试端口
4.2 生产环境配置
创建docker-compose.prod.yml
用于生产环境:
yaml
version: "3.8"
services:
node-app:
build:
context: .
dockerfile: Dockerfile.prod # 专门的生产Dockerfile
ports:
- "80:3000"
environment:
- NODE_ENV=production
restart: always
deploy:
resources:
limits:
cpus: "0.5"
memory: 512M
对应的Dockerfile.prod
:
dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --only=production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
5. 高级配置选项
5.1 添加数据库服务
在docker-compose.yml
中添加 PostgreSQL 服务:
yaml
services:
# ...node-app配置
postgres:
image: postgres:15
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
POSTGRES_DB: mydb
volumes:
- postgres-data:/var/lib/postgresql/data
ports:
- "5432:5432"
networks:
- app-network
volumes:
postgres-data:
networks:
app-network:
driver: bridge
5.2 使用 PM2 管理 Node 进程
修改Dockerfile.prod
的 CMD 指令:
dockerfile
RUN npm install -g pm2
CMD ["pm2-runtime", "start", "processes.json"]
5.3 多服务组合部署
完整示例包含前端、后端和数据库:
yaml
version: "3.8"
services:
frontend:
build: ./frontend
ports:
- "80:80"
depends_on:
- backend
backend:
build: ./backend
ports:
- "3000:3000"
environment:
- DB_HOST=postgres
depends_on:
- postgres
postgres:
image: postgres
environment:
POSTGRES_PASSWORD: example
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
postgres-data:
6. 常见问题与解决方案
6.1 依赖安装问题
- 问题:容器内依赖安装失败
- 解决方案:确保
package.json
和package-lock.json
已复制到容器,并在安装前执行:
dockerfile
COPY package*.json ./
RUN npm install
6.2 端口冲突
- 问题:端口已被占用
- 解决方案:修改
docker-compose.yml
中的端口映射:
yaml
ports:
- "4000:3000" # 宿主机4000映射到容器3000
6.3 文件权限问题
- 问题:容器内文件权限错误
- 解决方案:在 Dockerfile 中使用非 root 用户:
dockerfile
RUN adduser -D appuser && chown -R appuser /app
USER appuser
7. 生产环境最佳实践
使用轻量级基础镜像:如
node:18-alpine
而非完整版 Node 镜像多阶段构建:分离构建环境和运行环境,减少最终镜像大小
环境变量管理:使用
.env
文件管理敏感信息:
yaml
services:
node-app:
env_file:
- .env
日志管理:配置日志轮转和外部日志收集
健康检查:添加容器健康检查:
yaml
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
8. 常用命令参考
命令 | 描述 |
---|---|
docker-compose up -d | 启动服务(后台模式) |
docker-compose down | 停止并移除容器 |
docker-compose logs -f | 查看实时日志 |
docker-compose ps | 查看服务状态 |
docker-compose exec node-app sh | 进入容器 shell |
docker-compose restart node-app | 重启指定服务 |
通过以上配置和最佳实践,你可以高效地使用 Docker Compose 部署 Node.js 项目,无论是开发环境还是生产环境。根据项目需求,可以灵活扩展数据库、缓存等其他服务。