GitHub Actions 项目部署国内服务器,文件传输优化方案
前言
问题:当我使用 GitHub Actions 部署项目至国内服务器时,发现上传文件时间非常长,每次上传文件到服务器都要十几分钟。
原因:无论是前端项目的静态文件,还是后端项目的源码和依赖,当项目文件数量庞大时,都会面临相同的部署性能瓶颈。
本文提供一套通用的文件传输优化方案,适用于所有需要传输大量文件的部署场景。
适用场景分析
前端项目(静态文件部署)
# 构建产物通常包含大量小文件
dist/
├── assets/
│ ├── js/ # 数十个JS文件
│ ├── css/ # 数十个CSS文件
│ └── images/ # 数百张图片
├── index.html
└── ... # 总计可能数百到数千个文件后端项目(源码+依赖部署)
Node.js 项目
# 包含源码和依赖
project/
├── src/ # 源代码文件
├── node_modules/ # 数万个依赖文件
├── package.json
└── ... # 总计可能数万个文件其它项目类型,如 Java、Python 等,都可以参考这个模板进行优化。
核心优化原理(通用)
1. 网络往返次数优化
# 原始方案:N次网络往返(N=文件数量)
scp file1 server:/path/
scp file2 server:/path/
# ... 重复N次
# 优化方案:2次网络往返
tar -czf files.tar.gz . # 本地压缩
scp files.tar.gz server:/ # 1次传输
ssh server "tar -xzf ..." # 1次解压命令
# 海外CI环境到中国服务器
单次网络往返延迟: 200-500ms
文件数量越多,延迟累积越严重
计算公式: 总延迟 = 文件数量 × 平均延迟
示例: 500文件 × 300ms = 150秒 = 2.5分钟 (仅延迟时间)2. 数据传输量优化
# 压缩效果示例
原始文件大小: 100MB
压缩后大小: 20-40MB # 减少60-80%3. 连接建立优化
# SSH连接复用,避免重复握手
export SSH_OPTIONS="-o ControlMaster=auto -o ControlPersist=300"不同项目类型的具体实现
1. 前端静态项目
# 前端项目特定配置
- name: 构建前端项目
run: npm run build
- name: 部署前端项目
run: |
# 只压缩构建产物
cd dist # 或 build
tar -czf ../frontend.tar.gz .
cd ..
# 上传到Nginx目录
scp $SSH_OPTIONS frontend.tar.gz \
${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:${{ secrets.WEB_ROOT_PATH }}/
# 解压替换(无需重启服务)
ssh $SSH_OPTIONS ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} "
cd ${{ secrets.WEB_ROOT_PATH }} &&
tar -xzf frontend.tar.gz &&
rm frontend.tar.gz &&
echo '前端部署完成!'
"2. Node.js 后端项目
# Node.js项目特定配置
- name: 部署Node.js项目
run: |
# 压缩源码(排除开发依赖)
tar -czf nodejs-app.tar.gz . \
--exclude='.git' \
--exclude='node_modules' \
--exclude='*.log'
scp $SSH_OPTIONS nodejs-app.tar.gz \
${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:${{ secrets.PROJECT_PATH }}/
ssh $SSH_OPTIONS ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} "
cd ${{ secrets.PROJECT_PATH }} &&
echo '停止Node.js服务...' &&
# 宝塔PM2管理
pm2 stop your-app-name || true &&
# 或systemctl管理
# systemctl stop your-app-name || true &&
echo '备份现有版本...' &&
mv current backup_\$(date +%Y%m%d_%H%M%S) 2>/dev/null || true &&
echo '部署新版本...' &&
mkdir -p current &&
tar -xzf nodejs-app.tar.gz -C current &&
cd current &&
npm ci --production &&
rm ../nodejs-app.tar.gz &&
echo '启动Node.js服务...' &&
# 宝塔PM2管理
pm2 start ecosystem.config.js &&
# 或systemctl管理
# systemctl start your-app-name &&
echo 'Node.js项目部署完成!'
"参数配置指南:
secrets.XXXXXX: 在 GitHub 仓库 Settings → Secrets 中配置
性能提升对比数据
执行 vue3 项目,dist 文件夹上传到服务器,部署时间对比:
| 指标项目 | 原始方案 | 优化方案 | 提升效果 |
|---|---|---|---|
| 总部署时间 | 10 分 23 秒 | 1 分 28 秒 | 85.8%提升 |
| 网络往返次数 | 490 次 | 2 次 | 99.6%减少 |
| 传输数据量 | 45.2MB | 8.7MB | 80.7%减少 |
| SSH 连接时间 | 147 秒 | 0.3 秒 | 99.8%减少 |
总结
这套优化方案的核心价值在于:
通用性 - 适用于前端、后端、全栈项目
可扩展性 - 根据项目类型调整具体实现
高效性 - 无论文件数量多少,都能获得显著提升
实用性 - 提供了完整的宝塔服务管理命令
关键优化原则:
当文件数量 > 100 时,压缩传输效果显著
当传输距离较远时(如海外 CI 到国内服务器),优化效果更明显
根据项目类型选择合适的服务重启方式
这不仅仅是前端项目的优化方案,而是所有涉及大量文件传输的项目部署的通用解决方案。