Skip to content

永远不再手动发版:用 GitHub Actions 为 Astro 博客接入全自动 CI/CD 持续部署

毛佳国

📌 核心速览 (TL;DR)

GitHub Actions 为 Astro 博客提供完全免费的 CI/CD 流水线。核心流程:git push → GitHub Actions 拉起 Ubuntu 虚拟机 → 安装 pnpm → pnpm run build 生成 dist/ → SSH rsync 或 Cloudflare Wrangler 部署上线。整个过程无需你手动干预,约 40–90 秒完成全量发布。

关键文件:.github/workflows/deploy.yml;关键 Secret:MY_SERVER_SSH_KEY(ED25519 私钥)、MY_SERVER_IP。


很多朋友在按照我们的结构搭建好类似 singbox.ygjc.cc 这样精美的 Astro 博客后,每次在本地用 Markdown 写完了一篇洋洋洒洒的高级教程,会按照极其原始的行为做以下重复劳动:

  1. 终端里敲 pnpm run build;
  2. 干坐在椅子上等控制台跳一行行的生成日志;
  3. 把生成好的几十兆 dist 静态文件夹打开;
  4. 用 SSH 或者 FTP 传到自己的云服务器上……

万一你在哪一个步骤断电了,或者刚才文章里的一个错别字你想改一下?完蛋了,上面 4 个极其折磨人的机械动作你得全都重来一遍!


工业级的解法:CI/CD 持续集成

大公司是怎么发版的?他们甚至都不会碰线上的代码。他们只管写内容,写完了往代码托管平台上一推(Git Push)。平台会借用云端的机器人计算力,自动拉起一台”一次性且干净”的云电脑机器,在这台电脑上帮你跑打包指令,并且在打包完成后顺带着执行一个 SSH 文件上传的命令帮你塞进最终的小鸡里。

这就是赫赫有名的 CI/CD(持续集成与持续部署)。并且目前,这一切针对我们极客和个人博客来说,依靠 GitHub Actions,是完全终身免费的无限云计算资源。


场景一:Cloudflare Pages 自动化零成本部署

将全静态的 Astro 博客部署在全球分发免费不限流的 Cloudflare Pages 平台可谓是目前最强的梦幻组合(比放在还要掏钱买的小水管 VPS 上快多了!)。

1. 将项目托管到 GitHub

首先确保你的整个 Astro 源代码项目已经在一个你专属的 GitHub Repository 里(可以设置为 Private 私有防抄袭)。

2. 在 Cloudflare 面板新建 Pages

登录你的 Cloudflare:

  1. 前往 Pages (页面) 菜单;
  2. 选择 连接到 Git (Connect to Git);
  3. 授权绑定你的那个装有 Astro 源码的 GitHub 仓库;
  4. 框架预设 (Framework preset) 选择 Astro;
  5. 构建命令 (Build command) 填 pnpm run build;
  6. 输出目录 (Build output directory) 填 dist。

点击 Save and Deploy(保存并部署)!

就在你点击保存的瞬间,Cloudflare 内部的构建机器人已经在千兆专线上拉取了你全部的 .mdx 文章,花费几秒钟将你的 HTML 压缩打包,并立刻分发到全球 200+ 高速缓存节点上。它会扔给你一个 https://xxx.pages.dev 的永久免费域名,如果你有自己的域名,直接去 Custom Domain 绑定即可。


场景二:通过 GitHub Actions 自动部署到自己的 VPS

如果你想保持对部署目标的完全控制(比如部署到你自己的 Nginx 服务器、NAS 群晖,或者打成 Docker 镜像),就必须请出 GitHub Actions 的 workflow.yml。

第一步:生成 SSH 部署密钥

在本地生成一对专用的 ED25519 SSH 密钥(推荐 ED25519 而不是 RSA,更安全且签名更快):

# 生成专用部署密钥,不要设置 passphrase(CI 环境无法交互输入)
ssh-keygen -t ed25519 -C "github-actions-deploy" -f ~/.ssh/deploy_key -N ""

# 查看公钥,添加到目标服务器的 authorized_keys
cat ~/.ssh/deploy_key.pub

将公钥内容追加到你 VPS 的 ~/.ssh/authorized_keys:

# 在 VPS 上执行
echo "ssh-ed25519 AAAA..." >> ~/.ssh/authorized_keys

第二步:将私钥添加到 GitHub Secrets

在你的 GitHub 仓库 → Settings → Secrets and variables → Actions → New repository secret:

Secret 名称内容
MY_SERVER_SSH_KEY刚才生成的私钥内容(全文)
MY_SERVER_IP你的 VPS 公网 IP 或域名
MY_SERVER_USERSSH 登录用户名(如 ubuntu)

第三步:创建 Workflow 文件

在你的项目根目录下创建文件:.github/workflows/deploy.yml:

name: Deploy Astro Blog to My VPS 🚀

# 触发条件:main 分支有 push 时自动触发
on:
  push:
    branches: ["main"]

# 防止并发部署互相覆盖
concurrency:
  group: "deploy"
  cancel-in-progress: true

jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    steps:
      # 1. 拉取最新代码(包含子模块)
      - name: Checkout Code
        uses: actions/checkout@v4

      # 2. 安装 pnpm(先于 Node,确保 corepack 生效)
      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9

      # 3. 安装 Node.js 并启用 pnpm store 缓存
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "pnpm"

      # 4. 安装依赖(利用 lockfile 缓存,跳过重复下载)
      - name: Install Dependencies
        run: pnpm install --frozen-lockfile

      # 5. 构建 Astro 静态文件
      - name: Build Astro
        run: pnpm run build

      # 6. 用 rsync + SSH 密钥推送到 VPS(--delete 清理旧文件)
      - name: Deploy to VPS via rsync
        uses: easingthemes/ssh-deploy@v5
        with:
          SSH_PRIVATE_KEY: ${{ secrets.MY_SERVER_SSH_KEY }}
          ARGS: "-rltgoDzvO --delete"
          SOURCE: "dist/"
          REMOTE_HOST: ${{ secrets.MY_SERVER_IP }}
          REMOTE_USER: ${{ secrets.MY_SERVER_USER }}
          TARGET: "/var/www/myblog/html"

💡 pnpm store 缓存说明:actions/setup-node@v4 配合 cache: "pnpm" 会自动缓存 ~/.local/share/pnpm/store,二次部署时依赖安装时间从约 60 s 降至约 5 s。

完成!一行命令触发全量部署

从此以后,你只需要:

git add .
git commit -m "发布新文章:Sing-box VLESS Reality 配置指南"
git push

你可以直接合上电脑屏幕睡觉去。几千公里外的 GitHub 云数据中心会拉起虚拟机、完成所有高强度算力解包打包和加密传输。几十秒后,全世界的网民就能阅读到你博客上的最新博文了。


🔍 常见故障排查

故障现象排查方向
Permission denied (publickey)检查 MY_SERVER_SSH_KEY Secret 是否包含完整私钥(含 -----BEGIN 和 -----END 行)
Host key verification failed在 VPS 端提前执行 ssh-keyscan <IP> >> ~/.ssh/known_hosts 并提交到仓库
pnpm: command not found确保 pnpm/action-setup step 在 setup-node 之前
dist/ 为空检查 astro.config.mjs 的 outDir 配置,默认值就是 dist
Cloudflare Pages 构建失败在 Cloudflare 面板将 Node.js 版本手动设置为 20.x

❓ 常见问题与 AI 快问快答 (FAQ)

Q:GitHub Actions 免费吗?有使用限制吗?

A:公开仓库(Public repo)完全无限免费。私有仓库每月有 2,000 分钟免费额度,Astro 博客每次构建约耗时 60–90 秒,即使按每天发 10 篇文章计算也绰绰有余。

Q:我能同时部署到 Cloudflare Pages 和 VPS 吗?

A:可以。在一个 workflow 文件中定义两个 jobs,互相不依赖,GitHub Actions 会并行执行它们,实现同时双线部署。

Q:为什么推荐 ED25519 而不是 RSA?

A:ED25519 基于椭圆曲线密码学,密钥更短(256 bit vs RSA 的 4096 bit)、签名速度更快(约快 20 倍),且抗量子攻击能力更强。RSA-2048 在 2025 年后已不推荐用于新的部署场景。

Q:--frozen-lockfile 有什么用?

A:强制 pnpm 严格按照 pnpm-lock.yaml 安装,若 lockfile 与 package.json 不一致则立即报错退出。这确保了 CI 环境的依赖版本与本地开发完全一致,避免”在我机器上能跑”的问题。

Q:能配合 Cloudflare Workers 或 Pages Functions 使用吗?

A:完全可以。在 pnpm run build 之后添加一个 pnpm exec wrangler pages deploy dist --project-name=your-project step,直接使用 Wrangler CLI 部署到 Cloudflare Pages,比 Cloudflare 内置 CI 更灵活(支持自定义环境变量、多分支预览等)。

上一篇
告别屏幕牛皮癣广告:用 Docker 部署 AdGuard Home 打造家庭净网 DNS 中心 (2026版)
下一篇
你的密码不安全:用 Docker 一键私有化部署 Vaultwarden (Bitwarden 完美平替) (2026版)