1. 项目概述

最近在技术社区看到不少开发者询问Node.js项目部署的完整流程,特别是结合Docker和CI/CD的实践方案。作为一个经历过多次Node.js项目从开发到上线全周期的老手,我想分享一套经过实战检验的标准部署流程。

这个方案涵盖了从本地开发环境准备到最终生产环境上线的完整链路,包含Docker容器化、持续集成与持续部署(CI/CD)等现代部署实践。无论你是刚接触Node.js部署的新手,还是想优化现有部署流程的开发者,这套方案都能提供实用参考。

2. 环境准备与基础配置

2.1 Node.js环境搭建

首先需要确保开发机器上安装了合适的Node.js版本。我推荐使用nvm(Node Version Manager)来管理Node.js版本,这样可以方便地在不同项目间切换版本。

# 安装nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash

# 安装指定Node.js版本
nvm install 18.16.0
nvm use 18.16.0

选择Node.js版本时需要考虑:

  • 生产环境兼容性
  • 长期支持(LTS)版本
  • 项目依赖的特定功能需求

2.2 Docker环境配置

Docker的安装根据操作系统有所不同。在Linux上可以直接通过包管理器安装,而在Windows/macOS上需要安装Docker Desktop。

# Ubuntu安装示例
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

安装后需要将当前用户加入docker组以避免每次都需要sudo:

sudo usermod -aG docker $USER

常见安装问题排查:

  • 如果遇到"virtualization support not detected"错误,需要检查BIOS中是否启用了虚拟化支持
  • 在Windows上可能需要启用WSL2功能
  • 内存不足可能导致Docker启动失败

3. 项目容器化实践

3.1 Dockerfile编写

一个典型的Node.js项目Dockerfile应该包含以下关键部分:

# 使用官方Node.js镜像作为基础
FROM node:18-alpine

# 设置工作目录
WORKDIR /app

# 先复制package.json文件
COPY package*.json ./

# 安装依赖
RUN npm install

# 复制项目文件
COPY . .

# 构建应用
RUN npm run build

# 暴露端口
EXPOSE 3000

# 启动命令
CMD ["npm", "start"]

这个Dockerfile采用了多阶段构建的最佳实践:

  1. 使用轻量级的Alpine基础镜像
  2. 先单独复制package.json安装依赖,利用Docker缓存层
  3. 最后复制源代码,减少不必要的重建

3.2 容器网络与存储

在生产环境中,我们通常需要配置容器网络和数据卷:

# 创建自定义网络
docker network create app-network

# 运行容器并挂载卷
docker run -d \
  --name my-app \
  --network app-network \
  -v app-data:/data \
  -p 3000:3000 \
  my-node-app

4. CI/CD流水线搭建

4.1 基础CI流程

以GitHub Actions为例,一个基本的Node.js CI流程可以这样配置:

name: Node.js CI

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Use Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18.x'
    
    - name: Install dependencies
      run: npm ci
      
    - name: Run tests
      run: npm test
      
    - name: Build
      run: npm run build

这个配置实现了:

  • 代码检出
  • Node.js环境设置
  • 依赖安装(使用npm ci确保一致性)
  • 测试执行
  • 项目构建

4.2 完整CD流程

完整的CD流程需要添加Docker构建和部署步骤:

deploy:
  needs: build
  runs-on: ubuntu-latest
  
  steps:
  - uses: actions/checkout@v3
  
  - name: Login to Docker Hub
    uses: docker/login-action@v2
    with:
      username: ${{ secrets.DOCKER_HUB_USERNAME }}
      password: ${{ secrets.DOCKER_HUB_TOKEN }}
  
  - name: Build and push
    uses: docker/build-push-action@v4
    with:
      push: true
      tags: user/app:latest
      
  - name: Deploy to server
    uses: appleboy/ssh-action@master
    with:
      host: ${{ secrets.SSH_HOST }}
      username: ${{ secrets.SSH_USER }}
      key: ${{ secrets.SSH_KEY }}
      script: |
        docker pull user/app:latest
        docker stop app || true
        docker rm app || true
        docker run -d --name app -p 3000:3000 user/app:latest

这个CD流程包含:

  1. Docker镜像构建和推送
  2. 通过SSH连接到服务器
  3. 停止并移除旧容器
  4. 运行新版本容器

5. 生产环境优化

5.1 容器编排

对于生产环境,建议使用Docker Compose或Kubernetes进行容器编排。一个简单的docker-compose.yml示例:

version: '3.8'

services:
  app:
    image: user/app:latest
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
    restart: always
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

5.2 监控与日志

生产环境需要配置适当的监控和日志收集:

# 运行容器时配置日志驱动
docker run -d \
  --log-driver=json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  my-node-app

同时建议在应用中集成:

  • 健康检查端点
  • 性能监控(如Prometheus)
  • 错误跟踪(如Sentry)

6. 常见问题与解决方案

6.1 Docker构建问题

问题1 : 构建时npm install失败

  • 检查网络连接
  • 尝试使用国内镜像源: RUN npm install --registry=https://registry.npmmirror.com

问题2 : 容器启动后立即退出

  • 检查CMD命令是否正确
  • 添加 -it 参数交互式运行调试: docker run -it my-image sh

6.2 CI/CD流程问题

问题1 : GitHub Actions卡在docker login

  • 确保Docker Hub账号已开启双重验证并创建了访问令牌
  • 检查secrets配置是否正确

问题2 : 部署后应用无法访问

  • 检查服务器防火墙设置
  • 确认容器端口映射正确
  • 查看容器日志: docker logs <container-id>

7. 进阶优化建议

  1. 多阶段构建优化 :使用单独的阶段进行依赖安装和构建,最终只将必要文件复制到生产镜像

  2. 安全加固

    • 使用非root用户运行容器
    • 定期更新基础镜像
    • 扫描镜像中的漏洞
  3. 部署策略优化

    • 蓝绿部署
    • 金丝雀发布
    • 滚动更新
  4. 基础设施即代码 :使用Terraform等工具管理部署基础设施

这套流程在实际项目中已经多次验证,能够满足从中小型到大型Node.js项目的部署需求。根据项目具体情况,可以适当调整各环节配置。

更多推荐