|
| 1 | +# GitHub Actions 自动部署 — 一次性配置指南 |
| 2 | + |
| 3 | +> **配完之后**: 任何人 push 到 `main` 分支 → GitHub Actions 自动 SSH 到 VPS → git pull + build + 重启 → 1-2 分钟内上线 |
| 4 | +> **谁配**: lichang333 配 VPS 一次 + boss 配 GitHub Secrets 一次, **总共 5 分钟** |
| 5 | +
|
| 6 | +--- |
| 7 | + |
| 8 | +## 第一步: 在 VPS 上加 deploy 用的 SSH 公钥 |
| 9 | + |
| 10 | +ssh 上 VPS (lichang333 自己的方式, 我们 [meta-cc] 上不去): |
| 11 | + |
| 12 | +```bash |
| 13 | +ssh root@64.176.62.85 |
| 14 | +``` |
| 15 | + |
| 16 | +把下面整段公钥追加到 `/root/.ssh/authorized_keys`: |
| 17 | + |
| 18 | +``` |
| 19 | +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINm+ZFZc99HRra9uR84nwwkZdr4h2Ax8oO5L/E8QaTNh nieao@hermes-agent-hackathon-2026-05-02 |
| 20 | +``` |
| 21 | + |
| 22 | +一行命令搞定: |
| 23 | + |
| 24 | +```bash |
| 25 | +echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINm+ZFZc99HRra9uR84nwwkZdr4h2Ax8oO5L/E8QaTNh nieao@hermes-agent-hackathon-2026-05-02" | sudo tee -a /root/.ssh/authorized_keys |
| 26 | +sudo chmod 600 /root/.ssh/authorized_keys |
| 27 | +sudo chmod 700 /root/.ssh |
| 28 | +``` |
| 29 | + |
| 30 | +(可选) 验证 GitHub Actions 出口 IP 不被 fail2ban ban: |
| 31 | + |
| 32 | +```bash |
| 33 | +sudo fail2ban-client status sshd |
| 34 | +``` |
| 35 | + |
| 36 | +如果有大量 banned IP, 暂时禁用 fail2ban 让首次部署通过: |
| 37 | + |
| 38 | +```bash |
| 39 | +sudo systemctl stop fail2ban |
| 40 | +# 部署成功后再开 |
| 41 | +sudo systemctl start fail2ban |
| 42 | +``` |
| 43 | + |
| 44 | +--- |
| 45 | + |
| 46 | +## 第二步: 把 SSH 私钥配成 GitHub Secret |
| 47 | + |
| 48 | +### 2.1 拿到私钥内容 |
| 49 | + |
| 50 | +从 [meta-cc] 的本地机 (boss 你想猫的电脑) 拿: |
| 51 | + |
| 52 | +```bash |
| 53 | +cat ~/.ssh/hermes_agent_vps |
| 54 | +``` |
| 55 | + |
| 56 | +会输出类似: |
| 57 | + |
| 58 | +``` |
| 59 | +-----BEGIN OPENSSH PRIVATE KEY----- |
| 60 | +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQ... |
| 61 | +... 多行 base64 ... |
| 62 | +-----END OPENSSH PRIVATE KEY----- |
| 63 | +``` |
| 64 | + |
| 65 | +**整段复制** (包括 BEGIN / END 行). |
| 66 | + |
| 67 | +### 2.2 配 GitHub Secret |
| 68 | + |
| 69 | +打开浏览器: |
| 70 | + |
| 71 | +`https://github.com/nieao/know-canvas/settings/secrets/actions` |
| 72 | + |
| 73 | +(如果没看到 settings, 说明账号不是仓库 owner — 需要 nieao 自己操作) |
| 74 | + |
| 75 | +点 **"New repository secret"**, 加 3 个: |
| 76 | + |
| 77 | +| Secret 名 | 值 | 说明 | |
| 78 | +|----------|---|------| |
| 79 | +| `DEPLOY_SSH_KEY` | 上面 cat 的私钥**整段** (含 BEGIN/END 行) | SSH 私钥 | |
| 80 | +| `DEPLOY_HOST` | `64.176.62.85` | VPS IP (或域名 `ha2.digitalvio.shop` 也行) | |
| 81 | +| `DEPLOY_USER` | `root` | SSH 用户名 (新建 deploy 用户的话改这个) | |
| 82 | + |
| 83 | +(可选) 第 4 个: |
| 84 | + |
| 85 | +| `DEPLOY_PORT` | `22` | SSH 端口 — 默认 22, 不用配 | |
| 86 | + |
| 87 | +--- |
| 88 | + |
| 89 | +## 第三步: 触发首次部署 |
| 90 | + |
| 91 | +### 方式 A: 手动触发 (推荐第一次) |
| 92 | + |
| 93 | +`https://github.com/nieao/know-canvas/actions/workflows/deploy.yml` |
| 94 | + |
| 95 | +点 **"Run workflow"** → Branch `main` → **"Run workflow"** 按钮. |
| 96 | + |
| 97 | +约 1-3 分钟跑完, 看绿色勾就是成功. 如果红色叉, 点进去看哪一步失败. |
| 98 | + |
| 99 | +### 方式 B: 推一个 commit 测试 |
| 100 | + |
| 101 | +```bash |
| 102 | +cd "/e/claude code/know-canvas" |
| 103 | +git commit --allow-empty -m "trigger first deploy" |
| 104 | +git push origin main |
| 105 | +``` |
| 106 | + |
| 107 | +GitHub Actions 自动跑. |
| 108 | + |
| 109 | +--- |
| 110 | + |
| 111 | +## 第四步: 一次性 Caddy 配置 (无法自动化) |
| 112 | + |
| 113 | +**重要**: 部署脚本不会自动改 `/etc/caddy/Caddyfile` (避免破坏 Hermes 现有配置). 第一次部署后必须手动追加. |
| 114 | + |
| 115 | +ssh 上 VPS: |
| 116 | + |
| 117 | +```bash |
| 118 | +sudo nano /etc/caddy/Caddyfile |
| 119 | +``` |
| 120 | + |
| 121 | +找到 `ha2.digitalvio.shop {` 这一段, 在它的 `}` 之前插入: |
| 122 | + |
| 123 | +```caddy |
| 124 | + # Know Canvas 前端 (静态文件) |
| 125 | + handle_path /canvas/* { |
| 126 | + root * /var/www/know-canvas |
| 127 | + try_files {path} /index.html |
| 128 | + file_server |
| 129 | + } |
| 130 | +
|
| 131 | + # Yjs WebSocket 反代 |
| 132 | + handle_path /yws/* { |
| 133 | + reverse_proxy localhost:1234 { |
| 134 | + header_up Host {host} |
| 135 | + header_up X-Real-IP {remote} |
| 136 | + } |
| 137 | + } |
| 138 | +``` |
| 139 | + |
| 140 | +应用: |
| 141 | + |
| 142 | +```bash |
| 143 | +sudo caddy validate /etc/caddy/Caddyfile |
| 144 | +sudo systemctl reload caddy |
| 145 | +``` |
| 146 | + |
| 147 | +验证: |
| 148 | + |
| 149 | +```bash |
| 150 | +curl -s -o /dev/null -w '%{http_code}\n' https://ha2.digitalvio.shop/canvas/ |
| 151 | +# 期望: 200 |
| 152 | +``` |
| 153 | + |
| 154 | +--- |
| 155 | + |
| 156 | +## 配置完成后的工作流 |
| 157 | + |
| 158 | +**[meta-cc] / [ui-cc] / boss 任何人**: |
| 159 | + |
| 160 | +```bash |
| 161 | +git push origin main # → GitHub Actions 自动部署 |
| 162 | +``` |
| 163 | + |
| 164 | +**1-2 分钟内**: VPS 上的 `/var/www/know-canvas/` 自动更新, 浏览器刷新 https://ha2.digitalvio.shop/canvas/ 看到最新版本. |
| 165 | + |
| 166 | +**手动触发** (不 push 也能部署, 比如想 redeploy 一次): |
| 167 | + |
| 168 | +`https://github.com/nieao/know-canvas/actions/workflows/deploy.yml` → Run workflow. |
| 169 | + |
| 170 | +--- |
| 171 | + |
| 172 | +## 故障排查 |
| 173 | + |
| 174 | +### Actions 显示 "Permission denied (publickey)" |
| 175 | + |
| 176 | +公钥没加到 VPS authorized_keys, 或路径错了. 在 VPS 上: |
| 177 | + |
| 178 | +```bash |
| 179 | +sudo cat /root/.ssh/authorized_keys | grep nieao |
| 180 | +# 应该看到完整的一行 ssh-ed25519 AAAA... nieao@hermes-agent-hackathon-2026-05-02 |
| 181 | +``` |
| 182 | + |
| 183 | +### Actions 显示 "Connection closed by remote host" |
| 184 | + |
| 185 | +VPS 的 fail2ban 把 GitHub runner IP ban 了. 解决: |
| 186 | + |
| 187 | +```bash |
| 188 | +sudo fail2ban-client status sshd # 看 banned IP |
| 189 | +sudo fail2ban-client set sshd unbanip <IP> |
| 190 | +``` |
| 191 | + |
| 192 | +或者临时禁用: |
| 193 | + |
| 194 | +```bash |
| 195 | +sudo systemctl stop fail2ban |
| 196 | +# 跑完部署再 |
| 197 | +sudo systemctl start fail2ban |
| 198 | +``` |
| 199 | + |
| 200 | +### Actions 显示 "git pull 失败" (合并冲突) |
| 201 | + |
| 202 | +VPS 上 /opt/know-canvas 有未提交改动: |
| 203 | + |
| 204 | +```bash |
| 205 | +cd /opt/know-canvas |
| 206 | +git status # 看哪些文件改了 |
| 207 | +git stash # 暂存掉 |
| 208 | +# 或 git reset --hard origin/main (慎用, 丢失本地改动) |
| 209 | +``` |
| 210 | + |
| 211 | +### Actions 部署成功但 https://ha2.digitalvio.shop/canvas/ 返回 404 |
| 212 | + |
| 213 | +Caddy 还没追加 `/canvas/*` 段. 见上面"第四步". |
| 214 | + |
| 215 | +--- |
| 216 | + |
| 217 | +## 高级: 用专门的 deploy 用户 (更安全) |
| 218 | + |
| 219 | +避免给 GitHub Actions root 权限, 在 VPS 上: |
| 220 | + |
| 221 | +```bash |
| 222 | +sudo useradd -m -s /bin/bash deploy |
| 223 | +sudo mkdir -p /home/deploy/.ssh |
| 224 | +echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINm+ZFZc99HRra9uR84nwwkZdr4h2Ax8oO5L/E8QaTNh nieao@hermes-agent-hackathon-2026-05-02" | sudo tee /home/deploy/.ssh/authorized_keys |
| 225 | +sudo chmod 600 /home/deploy/.ssh/authorized_keys |
| 226 | +sudo chmod 700 /home/deploy/.ssh |
| 227 | +sudo chown -R deploy:deploy /home/deploy/.ssh |
| 228 | + |
| 229 | +# deploy 用户能 sudo 跑哪些命令 (最小权限原则) |
| 230 | +sudo tee /etc/sudoers.d/deploy-know-canvas <<'EOF' |
| 231 | +deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart know-canvas-yws |
| 232 | +deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload caddy |
| 233 | +deploy ALL=(ALL) NOPASSWD: /bin/bash /opt/know-canvas/deploy/deploy-on-vps.sh |
| 234 | +deploy ALL=(ALL) NOPASSWD: /usr/bin/cp -r /opt/know-canvas/dist /var/www/ |
| 235 | +EOF |
| 236 | +sudo chmod 440 /etc/sudoers.d/deploy-know-canvas |
| 237 | + |
| 238 | +# /opt/know-canvas 给 deploy 写权限 |
| 239 | +sudo chown -R deploy:deploy /opt/know-canvas |
| 240 | +sudo chown -R deploy:deploy /var/www/know-canvas 2>/dev/null || true |
| 241 | +``` |
| 242 | + |
| 243 | +然后把 GitHub Secret `DEPLOY_USER` 改成 `deploy`. |
| 244 | + |
| 245 | +--- |
| 246 | + |
| 247 | +## 关于私钥安全 |
| 248 | + |
| 249 | +私钥 `~/.ssh/hermes_agent_vps` **永远不入 git**: |
| 250 | + |
| 251 | +- ✅ 它**只**作为 GitHub Secret 存在 (加密存储, GitHub 内部都看不到) |
| 252 | +- ✅ 用完会自动 rm (workflow 末尾 `cleanup` step) |
| 253 | +- ❌ 不写到任何文件 / 注释 / 日志里 |
| 254 | +- ❌ 不发到 Slack / 邮件 / 群聊 |
| 255 | + |
| 256 | +如果担心泄露, 任何时候都可以重新生成一对 key: |
| 257 | + |
| 258 | +```bash |
| 259 | +# 本机 |
| 260 | +ssh-keygen -t ed25519 -f ~/.ssh/hermes_agent_vps_v2 -N "" |
| 261 | +# 把 .pub 加到 VPS authorized_keys, .pub 旧的删掉 |
| 262 | +# GitHub Secret DEPLOY_SSH_KEY 换成新私钥内容 |
| 263 | +``` |
| 264 | + |
| 265 | +--- |
| 266 | + |
| 267 | +## 配置好后效果预览 |
| 268 | + |
| 269 | +``` |
| 270 | +boss / cc 任何人: |
| 271 | + git push origin main |
| 272 | + ↓ (1 秒内) |
| 273 | + GitHub Actions 触发 |
| 274 | + ↓ (10 秒装 SSH key) |
| 275 | + ssh root@64.176.62.85 |
| 276 | + ↓ (~30 秒 git pull + npm install + build) |
| 277 | + systemctl restart know-canvas-yws |
| 278 | + ↓ (5 秒 health check) |
| 279 | + 完成 ✓ 通知 boss |
| 280 | +``` |
| 281 | + |
| 282 | +总耗时约 **1-2 分钟**. 期间 yws 重启会让所有协作用户**短暂断开** (Yjs 自动重连, 不丢数据). |
0 commit comments