You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化GitHub Action工作流:解决NestJS部署超时及内存不足问题

问题

我正尝试将NestJS项目部署至Digital Ocean Droplet(配置25GB SSD、2GB RAM),但遇到两个问题:

  • 通过SSH执行npm i时超时
  • 执行npm run build时Node.js因内存不足崩溃

我的项目仅包含5个端点,结构并不复杂,不确定是Droplet配置问题还是其他原因导致耗时过长。想请教:

  1. 如何优化当前的GitHub Action工作流?
  2. 如何避免服务停机并缩短部署时间?

当前使用的GitHub Action工作流配置如下:

name: Node.js CI

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-20.04

    strategy:
      matrix:
        node-version: [16.x]

    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - run: npm i

      - run: npm run build

      - name: executing remote ssh commands using password
        uses: appleboy/ssh-action@v0.1.7
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USER }}
          port: ${{ secrets.SSH_PORT }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            if [ -d "\/opt\/nodejs_project" ]; then rm -Rf \/opt\/nodejs_project; fi
            mkdir \/opt\/nodejs_project 
            cp ~\/secret\/.env.prod \/opt\/nodejs_project\/
            cp ~\/secret\/db.cert \/opt\/nodejs_project\/

      - name: Copy dist to VPS
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USER }}
          port: ${{ secrets.SSH_PORT }}
          key: ${{ secrets.SSH_KEY }}
          # Selecting all folders except "node_modules"
          source: '.,!node_modules'
          # The path is based on the directory where the user logged into the server starts
          target: '\/opt\/nodejs_project'

      - name: executing remote ssh commands using password
        uses: appleboy/ssh-action@v0.1.7
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USER }}
          port: ${{ secrets.SSH_PORT }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            chown -R root \/opt\/nodejs_project
            cd \/opt\/nodejs_project
            npm i --production
            pm2 restart all
优化方案

一、GitHub Action工作流核心优化

1. 转移构建/依赖安装到GitHub Runner,减少服务器压力

你现在已经在Runner上做了npm i和build,但又在服务器重复执行npm i --production,完全没必要。直接在Runner上完成生产依赖安装,只传必要文件到服务器:

  • 在Runner执行npm ci --only=production替代服务器端的依赖安装
  • SCP仅传输dist、package.json、package-lock.json(或yarn.lock),不用传整个项目目录

调整后的关键步骤示例:

# ... 保留checkout、setup-node步骤
- run: npm ci
- run: npm run build
- run: npm ci --only=production # 在Runner上安装生产依赖
- name: Copy necessary files to VPS
  uses: appleboy/scp-action@master
  with:
    # ... 主机信息不变
    source: 'dist, package.json, package-lock.json'
    target: '/opt/nodejs_project'
# 删掉服务器端的npm i --production步骤

2. 合并SSH操作,减少连接次数

当前多次调用ssh-action和scp-action,每次都要重新建立SSH连接,增加耗时。把多个SSH命令合并成一个步骤:

- name: Deploy to VPS
  uses: appleboy/ssh-action@v0.1.7
  with:
    # ... 主机信息不变
    script: |
      # 备份旧目录(可选,用于回滚)
      if [ -d "/opt/nodejs_project" ]; then mv /opt/nodejs_project /opt/nodejs_project.bak; fi
      mkdir -p /opt/nodejs_project
      cp ~/secret/.env.prod /opt/nodejs_project/
      cp ~/secret/db.cert /opt/nodejs_project/
      chown -R root /opt/nodejs_project
      cd /opt/nodejs_project
      pm2 reload nest-app # 替换原来的restart all

3. 升级Action版本

当前用的actions/checkout@v2、actions/setup-node@v2版本较旧,升级到最新稳定版(比如v4)能获得性能提升和bug修复。

二、避免服务停机的策略

1. 蓝绿部署

在服务器维护两个部署目录(比如/opt/nodejs_v1和/opt/nodejs_v2),每次部署到空闲目录,启动新服务后再切换流量:

  • 检查当前活跃版本(通过PM2应用名称判断)
  • 部署到非活跃目录并启动新PM2进程
  • 调用健康检查端点验证新服务正常
  • 修改Nginx反向代理配置指向新服务端口
  • 重启Nginx后停止旧服务

2. 用PM2 reload替代restart

pm2 restart all会一次性重启所有进程,导致短暂停机。换成pm2 reload [你的应用名称],PM2会逐个重启进程,保证服务始终有实例运行。

3. 健康检查前置

在切换流量前,先调用NestJS的健康检查端点(可以用@nestjs/terminus实现),确认新服务正常响应后再完成部署。

三、服务器端临时缓解措施(不用升级Droplet)

1. 增加Node.js内存限制

执行build时通过NODE_OPTIONS分配更多内存:

NODE_OPTIONS="--max-old-space-size=1536" npm run build

(2GB内存的Droplet,给Node分配1.5GB比较合理)

2. 启用Swap分区

给Droplet添加Swap分区,内存不足时用磁盘临时替代:

# 创建1GB swap文件
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 设置开机自动挂载
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

3. 用pnpm替代npm

pnpm内存占用比npm低很多,安装依赖更快。在Runner和服务器都换成pnpm:

# 在GitHub Action中配置pnpm
- uses: actions/setup-node@v4
  with:
    node-version: 16.x
    cache: 'pnpm'
- run: npm install -g pnpm
- run: pnpm install
- run: pnpm run build

内容的提问来源于stack exchange,提问作者sahil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 21:15:11