GitHub Actions 自动部署到阿里云 OSS
GitHub Actions 自动部署到阿里云 OSS
为什么需要自动化部署
手动部署博客的痛点:
- ⏱️ 每次更新都要手动构建、上传文件
- 🐌 单线程上传速度慢,100 个文件要等 2-3 分钟
- 😰 容易漏传或错传文件
- 📝 需要记住一堆命令和配置
使用 GitHub Actions 后:
- ✅ 代码一推送自动构建部署
- ✅ 并发上传速度提升 4-6 倍
- ✅ 零人工干预,完全自动化
- ✅ 支持手动触发部署
前提准备
1. 阿里云 OSS Bucket
确保你已经:
- 创建了 OSS Bucket(例如:
my-blog-bucket) - 知道 Bucket 所在区域(例如:
oss-cn-hangzhou) - 获取了 AccessKey ID 和 AccessKey Secret
如何获取 AccessKey:
- 登录阿里云控制台
- 鼠标悬停在右上角头像,点击 AccessKey 管理
- 点击 创建 AccessKey
- 保存好 AccessKey ID 和 AccessKey Secret(只显示一次)
⚠️ 安全提示:AccessKey 拥有账号的完全权限,务必妥善保管,建议使用 RAM 子账号并只授予 OSS 写入权限。
2. GitHub 仓库
确保你的博客代码已经托管在 GitHub 上。
第一步:配置 GitHub Secrets
为什么要用 Secrets?
Secrets 是 GitHub 提供的安全存储机制,可以加密存储敏感信息(如 AccessKey),在工作流中使用时不会暴露明文。
配置步骤
- 进入你的 GitHub 仓库页面
- 点击 Settings → Secrets and variables → Actions
- 点击 New repository secret 添加以下 4 个密钥:
| Secret 名称 | 说明 | 示例值 |
|---|---|---|
ALIYUN_ACCESS_KEY_ID | 阿里云 AccessKey ID | LTAI5t... |
ALIYUN_ACCESS_KEY_SECRET | 阿里云 AccessKey Secret | wKx9... |
ALIYUN_BUCKET_NAME | OSS Bucket 名称 | my-blog-bucket |
ALIYUN_ENDPOINT | OSS 区域节点 | oss-cn-hangzhou |
OSS Endpoint 区域对照表
| 区域 | Endpoint |
|---|---|
| 华东1(杭州) | oss-cn-hangzhou |
| 华东2(上海) | oss-cn-shanghai |
| 华北1(青岛) | oss-cn-qingdao |
| 华北2(北京) | oss-cn-beijing |
| 华南1(深圳) | oss-cn-shenzhen |
| 香港 | oss-cn-hongkong |
| 美国西部1(硅谷) | oss-us-west-1 |
| 新加坡 | oss-ap-southeast-1 |
完整区域列表:https://help.aliyun.com/document_detail/31837.html
第二步:创建 GitHub Actions 工作流
在项目根目录创建文件:.github/workflows/deploy-oss.yml
name: Deploy to Aliyun OSS on: push: branches: - main # 当推送到 main 分支时触发 workflow_dispatch: # 允许手动触发 env: ALIYUN_ACCESS_KEY_ID: ${{ secrets.ALIYUN_ACCESS_KEY_ID }} ALIYUN_ACCESS_KEY_SECRET: ${{ secrets.ALIYUN_ACCESS_KEY_SECRET }} ALIYUN_BUCKET_NAME: ${{ secrets.ALIYUN_BUCKET_NAME }} ALIYUN_ENDPOINT: ${{ secrets.ALIYUN_ENDPOINT }} jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '18' cache: 'npm' - name: Install dependencies run: npm ci - name: Build project run: npm run build - name: Install ossutil run: | wget https://gosspublic.alicdn.com/ossutil/1.7.18/ossutil-v1.7.18-linux-amd64.zip unzip ossutil-v1.7.18-linux-amd64.zip sudo mv ossutil-v1.7.18-linux-amd64/ossutil /usr/local/bin/ sudo chmod +x /usr/local/bin/ossutil ossutil --version - name: Configure ossutil run: | ossutil config -e oss-${ALIYUN_ENDPOINT}.aliyuncs.com -i ${ALIYUN_ACCESS_KEY_ID} -k ${ALIYUN_ACCESS_KEY_SECRET} - name: Upload files to Aliyun OSS with high concurrency run: | echo "🚀 开始批量并发上传文件到 OSS..." # 高性能并发上传配置 ossutil cp -r -f -u ./out/ oss://${ALIYUN_BUCKET_NAME}/ \ --parallel 15 \ --part-size 10485760 \ --jobs 10 \ --retry-times 3 echo "✅ 上传完成!" - name: Deployment summary if: always() run: | echo "📊 部署摘要" echo "================================" echo "✅ 构建分支: ${{ github.ref_name }}" echo "✅ 提交信息: ${{ github.event.head_commit.message }}" echo "✅ 部署时间: $(date)" echo "✅ OSS Bucket: ${ALIYUN_BUCKET_NAME}" echo "✅ OSS Endpoint: ${ALIYUN_ENDPOINT}" echo "================================"
工作流配置详解
触发方式
on: push: branches: - main # 推送到 main 分支自动触发 workflow_dispatch: # 允许在 GitHub Actions 页面手动触发
环境变量
env: ALIYUN_ACCESS_KEY_ID: ${{ secrets.ALIYUN_ACCESS_KEY_ID }}
使用 ${{ secrets.NAME }} 语法读取之前配置的 Secrets。
关键步骤说明
1. 检出代码
- uses: actions/checkout@v4
拉取最新代码到 GitHub Actions 运行环境。
2. 安装 Node.js
- uses: actions/setup-node@v4 with: node-version: '18' cache: 'npm'
cache: 'npm':自动缓存 node_modules,加速后续构建
3. 安装依赖
- run: npm ci
npm ci比npm install更快更可靠(适合 CI 环境)
4. 构建项目
- run: npm run build
执行 package.json 中的 build 脚本(Next.js 会生成 ./out 目录)
5. 安装 ossutil
- run: | wget https://gosspublic.alicdn.com/ossutil/1.7.18/ossutil-v1.7.18-linux-amd64.zip unzip ossutil-v1.7.18-linux-amd64.zip sudo mv ossutil-v1.7.18-linux-amd64/ossutil /usr/local/bin/ sudo chmod +x /usr/local/bin/ossutil
下载并安装阿里云官方的 OSS 命令行工具。
6. 配置 ossutil
- run: | ossutil config -e oss-${ALIYUN_ENDPOINT}.aliyuncs.com \ -i ${ALIYUN_ACCESS_KEY_ID} \ -k ${ALIYUN_ACCESS_KEY_SECRET}
配置 OSS 访问凭证。
第三步:高性能并发上传配置
核心上传命令
ossutil cp -r -f -u ./out/ oss://${ALIYUN_BUCKET_NAME}/ \ --parallel 15 \ --part-size 10485760 \ --jobs 10 \ --retry-times 3
参数详解
| 参数 | 说明 | 推荐值 |
|---|---|---|
-r | 递归上传目录 | - |
-f | 强制覆盖已存在的文件 | - |
-u | 增量上传,只上传新增或修改的文件 | - |
--parallel | 分片并发数,同时上传多少个文件分片 | 15 |
--part-size | 分片大小(字节),10485760 = 10MB | 10MB |
--jobs | 文件并发数,同时上传多少个文件 | 10 |
--retry-times | 失败重试次数 | 3 |
性能调优建议
根据你的文件大小和网络情况调整参数:
--parallel(分片并发数)
- 小文件为主:5-10
- 大文件为主:15-20
- 超大文件:20-30
--part-size(分片大小)
- 小于 10MB 的文件:不分片
- 10MB-100MB:10485760(10MB)
- 大于 100MB:52428800(50MB)
--jobs(文件并发数)
- 文件数量少:5-10
- 文件数量多:10-20
- 网络带宽充足:可增加到 20-30
性能对比
| 配置 | 单线程上传 | 并发上传 | 提升比例 |
|---|---|---|---|
| 100 个文件(10MB) | ~2 分钟 | ~30 秒 | 4 倍 |
| 500 个文件(1MB) | ~5 分钟 | ~45 秒 | 6.7 倍 |
| 10 个大文件(100MB) | ~8 分钟 | ~1.5 分钟 | 5.3 倍 |
第四步:触发部署
方式 1:自动触发(推荐)
每次推送到 main 分支时自动部署:
git add . git commit -m "update: 更新博客内容" git push origin main
推送后:
- 进入 GitHub 仓库页面
- 点击 Actions 标签
- 查看最新的工作流运行状态
方式 2:手动触发
- 进入 GitHub 仓库页面
- 点击 Actions 标签
- 选择 Deploy to Aliyun OSS 工作流
- 点击 Run workflow 按钮
- 选择分支(通常是 main)
- 点击绿色的 Run workflow 按钮
增量上传的优势
使用 -u 参数实现增量上传:
工作原理:
- ossutil 会对比本地文件和 OSS 上文件的 MD5 值
- 只上传新增或修改过的文件
- 跳过未修改的文件
优势:
- ⚡ 显著减少上传时间(只上传变更的文件)
- 💰 节省流量费用
- 🔄 支持频繁更新的场景
示例:
- 首次部署:500 个文件,耗时 1 分钟
- 第二次部署(只修改了 2 个文件):耗时 5 秒
CDN 缓存刷新(可选)
如果你的 OSS 绑定了 CDN,上传完成后需要刷新 CDN 缓存,否则用户访问的还是旧内容。
添加 CDN 刷新步骤
在 deploy-oss.yml 的最后添加:
- name: Refresh CDN cache run: | # 安装阿里云 CLI wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz tar -xzf aliyun-cli-linux-latest-amd64.tgz sudo mv aliyun /usr/local/bin/ # 配置阿里云 CLI aliyun configure set \ --profile default \ --mode AK \ --region cn-hangzhou \ --access-key-id ${ALIYUN_ACCESS_KEY_ID} \ --access-key-secret ${ALIYUN_ACCESS_KEY_SECRET} # 刷新 CDN 缓存(需要替换成你的域名) aliyun cdn RefreshObjectCaches \ --ObjectPath https://your-domain.com \ --ObjectType Directory
注意:
- 需要在 GitHub Secrets 中额外配置 CDN 相关权限
- 阿里云 CDN 每天有刷新次数限制(URL 刷新:2000 次/天,目录刷新:100 次/天)
常见问题解决
1. AccessDenied 错误
错误信息:
Error: AccessDenied
原因:AccessKey 没有 OSS 写入权限
解决方案:
- 登录阿里云控制台
- 进入 RAM 访问控制 → 用户
- 给用户添加
AliyunOSSFullAccess权限策略
2. NoSuchBucket 错误
错误信息:
Error: NoSuchBucket
原因:Bucket 名称错误或 Endpoint 不匹配
解决方案:
- 检查
ALIYUN_BUCKET_NAME是否正确 - 检查
ALIYUN_ENDPOINT是否与 Bucket 所在区域一致
3. 上传速度慢
原因:并发参数设置过低
解决方案:
- 增加
--parallel参数(建议 15-20) - 增加
--jobs参数(建议 10-15) - 检查网络带宽
4. 工作流失败
排查步骤:
- 进入 GitHub Actions 页面查看详细日志
- 检查是否所有 Secrets 都配置正确
- 检查
npm run build是否成功 - 检查 ossutil 是否安装成功
安全最佳实践
1. 使用 RAM 子账号
不要使用主账号的 AccessKey,而是创建 RAM 子账号:
- 登录阿里云控制台
- 进入 RAM 访问控制 → 用户 → 创建用户
- 勾选 编程访问
- 保存 AccessKey
- 给用户添加权限:
AliyunOSSFullAccess
2. 最小权限原则
只授予 OSS 写入权限,不要给不必要的权限。
自定义权限策略示例:
{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "oss:PutObject", "oss:DeleteObject" ], "Resource": [ "acs:oss:*:*:my-blog-bucket/*" ] } ] }
3. 定期轮换 AccessKey
建议每 3-6 个月更换一次 AccessKey:
- 创建新的 AccessKey
- 更新 GitHub Secrets
- 验证部署正常
- 删除旧的 AccessKey
4. 启用 OSS 访问日志
在 OSS 控制台启用访问日志审计,方便排查异常访问。
费用说明
OSS 费用构成
| 项目 | 计费方式 | 说明 |
|---|---|---|
| 存储费用 | 按实际存储量计费 | 标准存储:0.12 元/GB/月 |
| 上传流量 | 免费 | 从本地上传到 OSS 不收费 |
| 下载流量 | 按量计费 | 外网下载:0.50 元/GB |
| API 请求 | 按请求次数计费 | PUT 请求:0.01 元/万次 |
成本优化建议
- 启用 CDN:减少 OSS 外网下载流量,CDN 流量更便宜
- 配置生命周期规则:自动删除过期文件或转为低频存储
- 使用增量上传:减少不必要的 API 请求
预估费用(以 1GB 博客为例):
- 存储费用:0.12 元/月
- CDN 流量(1000 次访问,平均 1MB/次):约 0.15 元
- 总计:约 0.27 元/月
总结
通过 GitHub Actions 自动部署到阿里云 OSS,你获得了:
✅ 自动化:代码一推送就自动部署 ✅ 高性能:并发上传速度提升 4-6 倍 ✅ 增量更新:只上传修改的文件,节省时间和流量 ✅ 零成本:GitHub Actions 对公开仓库免费
完整工作流:
本地修改博客 → git push → GitHub Actions 自动构建 → 并发上传到 OSS → 部署完成
一次配置,终身受益!