<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Ynnn</title><description>blog</description><link>https://www.ynnn-7.com/</link><templateTheme>Firefly</templateTheme><templateThemeVersion>6.15.8</templateThemeVersion><templateThemeUrl>https://github.com/CuteLeaf/Firefly</templateThemeUrl><lastBuildDate>2026年8月12日 22:05:55</lastBuildDate><item><title>博客热部署指南：Push 代码自动更新到服务器</title><link>https://www.ynnn-7.com/posts/%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%83%AD%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/</link><guid isPermaLink="true">https://www.ynnn-7.com/posts/%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%83%AD%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/</guid><description>使用 GitHub Actions 实现博客热部署：推送代码到 GitHub 后自动构建并部署到自有服务器，服务器无需安装 Node.js、Git 等环境。</description><pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;背景&lt;a href=&quot;#背景&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;本博客基于 Astro 静态站点框架，部署在自有服务器上(Ubuntu22.04)。之前每次更新内容都需要手动 SSH 连上服务器，拉代码、构建、拷贝文件，非常繁琐。&lt;/p&gt;&lt;p&gt;引入 &lt;strong&gt;GitHub Actions&lt;/strong&gt; 自动化部署后，只需本地 &lt;code&gt;git push&lt;/code&gt;，云端自动构建并将 &lt;code&gt;dist/&lt;/code&gt; 推送到服务器，Nginx 直接返回新内容，真正实现”写完就发”。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;整体架构&lt;a href=&quot;#整体架构&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;┌──────────────┐   git push   ┌───────────────┐   SSH+rsync   ┌──────────────┐&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│  本地电脑      │ ──────────&amp;gt; │  GitHub 仓库    │ ────────────&amp;gt; │  自有服务器    │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;│  (写代码)      │             │  Actions 构建   │               │  Nginx 返回   │&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;└──────────────┘             └───────┬───────┘               └──────────────┘&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                                     &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                              &lt;/span&gt;&lt;/span&gt;&lt;span&gt;云端 Ubuntu 环境&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                              &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- checkout 代码&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                              &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- 安装 pnpm + 依赖&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                              &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- pnpm build 构建&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                              &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- rsync dist/ → 服务器&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;核心优势&lt;/strong&gt;：服务器上不需要安装 Git、Node.js、pnpm 等任何开发环境，只需要 Nginx 和 rsync。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;第一步：服务器生成 SSH 密钥&lt;a href=&quot;#第一步服务器生成-ssh-密钥&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;SSH 连上服务器，生成一组供 GitHub Actions 使用的密钥对：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ssh-keygen&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-t&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ed25519&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/root/.ssh/github-actions&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-N&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 公钥（锁）装到服务器&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;cat&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/root/.ssh/github-actions.pub&lt;/span&gt;&lt;span&gt; &amp;gt;&amp;gt; &lt;/span&gt;&lt;span&gt;/root/.ssh/authorized_keys&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;# 私钥（钥匙）复制下来，稍后填入 GitHub&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;cat&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/root/.ssh/github-actions&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;公钥和私钥的区别&lt;/strong&gt;：公钥是”锁”，装在服务器上，谁都可以看；私钥是”钥匙”，必须保密。GitHub Actions 拿着钥匙去开服务器的锁，匹配成功就能免密登录。&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;第二步：GitHub 仓库添加 Secrets&lt;a href=&quot;#第二步github-仓库添加-secrets&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;打开 GitHub 仓库 → &lt;strong&gt;Settings → Secrets and variables → Actions → New repository secret&lt;/strong&gt;，添加三个：&lt;/p&gt;
























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Secret 名称&lt;/th&gt;&lt;th&gt;示例值&lt;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;SERVER_HOST&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;162.211.183.61&lt;/code&gt;&lt;/td&gt;&lt;td&gt;服务器 IP 地址&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;SERVER_USER&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;root&lt;/code&gt;&lt;/td&gt;&lt;td&gt;SSH 登录用户名&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;SERVER_SSH_KEY&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;-----BEGIN OPENSSH PRIVATE KEY-----&lt;/code&gt;…&lt;/td&gt;&lt;td&gt;第一步复制的完整私钥（含头尾）&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;添加时注意私钥必须包含 &lt;code&gt;-----BEGIN OPENSSH PRIVATE KEY-----&lt;/code&gt; 和 &lt;code&gt;-----END OPENSSH PRIVATE KEY-----&lt;/code&gt;，缺一不可。
确保&lt;a href=&quot;https://github.com/%E7%94%A8%E6%88%B7%E5%90%8D%E7%A7%B0/%E4%BB%93%E5%BA%93%E5%90%8D%E7%A7%B0/settings/actions%E7%9A%84Actions&quot; target=&quot;_blank&quot;&gt;https://github.com/用户名称/仓库名称/settings/actions的Actions&lt;/a&gt; permissions是Allow all actions and reusable workflows。&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;第三步：创建 deploy.yml&lt;a href=&quot;#第三步创建-deployyml&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;在项目根目录创建 &lt;code&gt;.github/workflows/deploy.yml&lt;/code&gt;：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;Deploy to Server&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;on&lt;/span&gt;&lt;span&gt;:                          &lt;/span&gt;&lt;span&gt;# 触发条件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;push&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;branches&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;span&gt;master&lt;/span&gt;&lt;span&gt;]        &lt;/span&gt;&lt;span&gt;# 推送到 master 分支时触发&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;workflow_dispatch&lt;/span&gt;&lt;span&gt;:          &lt;/span&gt;&lt;span&gt;# 允许在网页上手动触发&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;concurrency&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;deploy&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;cancel-in-progress&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;jobs&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;build-and-deploy&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;runs-on&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;ubuntu-latest&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# GitHub 提供的一台临时云服务器&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;steps&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;# ① 拉代码&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;Checkout&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;uses&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;actions/checkout@v4&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;# ② 装 Node.js 22&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;Setup Node.js&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;uses&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;actions/setup-node@v4&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;node-version&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;22&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;# ③ 装 pnpm 9.14.4&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;Setup pnpm&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;uses&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;pnpm/action-setup@v4&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;version&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;9.14.4&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;run_install&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;# ④ 装项目依赖&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;Install dependencies&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;pnpm install --no-frozen-lockfile&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;# ⑤ 构建 → 生成 dist/ 目录&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;Build site&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;pnpm run build&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;# ⑥ 把 dist/ 推送到你的服务器 /var/www/html/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;42&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;Deploy to server&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;43&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;uses&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;easingthemes/ssh-deploy@v5.1.2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;44&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;45&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;SSH_PRIVATE_KEY&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${{ secrets.SERVER_SSH_KEY }}&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;# 你的私钥&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;46&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;ARGS&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;-avz --delete&quot;&lt;/span&gt;&lt;span&gt;                             &lt;/span&gt;&lt;span&gt;# rsync 参数：归档+压缩+删除旧文件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;47&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;SOURCE&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;dist/&quot;&lt;/span&gt;&lt;span&gt;                                   &lt;/span&gt;&lt;span&gt;# 要上传的本地目录&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;48&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;REMOTE_HOST&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${{ secrets.SERVER_HOST }}&lt;/span&gt;&lt;span&gt;           &lt;/span&gt;&lt;span&gt;# 你的服务器 IP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;49&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;REMOTE_USER&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${{ secrets.SERVER_USER }}&lt;/span&gt;&lt;span&gt;           &lt;/span&gt;&lt;span&gt;# 登录用户&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;50&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;TARGET&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;/var/www/html&quot;&lt;/span&gt;&lt;span&gt;                           &lt;/span&gt;&lt;span&gt;# 服务器上的目标目录&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;section&gt;&lt;h3&gt;配置说明&lt;a href=&quot;#配置说明&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;




































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;配置项&lt;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;on.push.branches: [master]&lt;/code&gt;&lt;/td&gt;&lt;td&gt;推送到 master 分支时自动触发&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;workflow_dispatch&lt;/code&gt;&lt;/td&gt;&lt;td&gt;允许手动在 Actions 页面点击触发&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;runs-on: ubuntu-latest&lt;/code&gt;&lt;/td&gt;&lt;td&gt;GitHub 提供的临时 Linux 服务器&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;SOURCE: &quot;dist/&quot;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;本地构建产物目录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;TARGET: &quot;/var/www/html&quot;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;服务器上 Nginx 的根目录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;ARGS: &quot;-avz --delete&quot;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;rsync 参数：归档模式 + 压缩 + 删除旧文件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;--no-frozen-lockfile&lt;/code&gt;&lt;/td&gt;&lt;td&gt;允许 pnpm 更新 lockfile，避免版本锁定导致构建失败&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;第四步：Nginx 配置&lt;a href=&quot;#第四步nginx-配置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;确保服务器上的 Nginx 指向正确的目录：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;server&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;   &lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;listen &lt;/span&gt;&lt;span&gt;443&lt;/span&gt;&lt;span&gt; ssl http2;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;   &lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;server_name &lt;/span&gt;&lt;span&gt;www.ynnn-7.com;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;   &lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ssl_certificate &lt;/span&gt;&lt;span&gt;    /etc/nginx/ssl/fullchain.pem;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;   &lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ssl_certificate_key &lt;/span&gt;&lt;span&gt;/etc/nginx/ssl/privkey.pem;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;   &lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;root &lt;/span&gt;&lt;span&gt;/var/www/html;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;   &lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;index &lt;/span&gt;&lt;span&gt;index.html;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# 不带 www 跳转到带 www&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;server&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;       &lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;listen &lt;/span&gt;&lt;span&gt;443&lt;/span&gt;&lt;span&gt; ssl;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;       &lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;server_name &lt;/span&gt;&lt;span&gt;ynnn-7.com;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;301&lt;/span&gt;&lt;span&gt; https://www.ynnn-7.com$&lt;/span&gt;&lt;span&gt;request_uri&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;location&lt;/span&gt;&lt;span&gt; / {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;       &lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;try_files &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;uri&lt;/span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;uri&lt;/span&gt;&lt;span&gt;.html $&lt;/span&gt;&lt;span&gt;uri&lt;/span&gt;&lt;span&gt;/ /404.html;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# Astro 静态资源长期缓存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;location&lt;/span&gt;&lt;span&gt; /_astro/ {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;       &lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;expires &lt;/span&gt;&lt;span&gt;1y;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;       &lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;add_header &lt;/span&gt;&lt;span&gt;Cache-Control &lt;/span&gt;&lt;span&gt;&quot;public, immutable&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;   &lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;gzip &lt;/span&gt;&lt;span&gt;on&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;   &lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;gzip_types &lt;/span&gt;&lt;span&gt;text/plain text/css application/json application/javascript&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;               &lt;/span&gt;&lt;/span&gt;&lt;span&gt;text/xml application/xml text/javascript image/svg+xml;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;工作原理&lt;a href=&quot;#工作原理&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;每次 &lt;code&gt;git push origin master&lt;/code&gt; 后，GitHub Actions 自动执行以下流程：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;git push&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;GitHub Actions 触发&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;拉取最新代码&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;安装 Node.js 22&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;安装 pnpm&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;pnpm install 装依赖&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;pnpm build 构建&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;rsync dist/ → 服务器 /var/www/html/&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;Nginx 返回新页面&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;git push&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;GitHub Actions 触发&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;拉取最新代码&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;安装 Node.js 22&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;安装 pnpm&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;pnpm install 装依赖&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;pnpm build 构建&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;rsync dist/ → 服务器 /var/www/html/&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;Nginx 返回新页面&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;如何使用&lt;a href=&quot;#如何使用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;以后写完文章只需要：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;commit&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-m&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;更新内容&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;push&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;然后打开 GitHub 仓库的 &lt;strong&gt;Actions&lt;/strong&gt; 标签页，查看 &lt;strong&gt;Deploy to Server&lt;/strong&gt; 运行状态。变成绿色 ✅ 后等待 1-2 分钟，刷新博客即可看到更新。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;踩坑记录&lt;a href=&quot;#踩坑记录&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1. SSH 连接被拒&lt;a href=&quot;#1-ssh-连接被拒&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;现象&lt;/strong&gt;：&lt;code&gt;Host key verification failed&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;解决&lt;/strong&gt;：确认 &lt;code&gt;authorized_keys&lt;/code&gt; 中已添加公钥，且 GitHub Secrets 中的 &lt;code&gt;SERVER_SSH_KEY&lt;/code&gt; 私钥内容完整（包含头尾标记）。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2. Action 版本找不到&lt;a href=&quot;#2-action-版本找不到&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;现象&lt;/strong&gt;：&lt;code&gt;Unable to resolve action easingthemes/ssh-deploy@v5&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;解决&lt;/strong&gt;：&lt;code&gt;v5&lt;/code&gt; 不是有效的版本 tag，必须使用具体版本号如 &lt;code&gt;v5.1.2&lt;/code&gt;。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3. 构建失败但部署日志看不到&lt;a href=&quot;#3-构建失败但部署日志看不到&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;现象&lt;/strong&gt;：Actions 页面显示红色失败&lt;/p&gt;&lt;p&gt;&lt;strong&gt;解决&lt;/strong&gt;：项目中的其他 workflow（如 Biome 代码检查）可能同时运行并失败，但它们是独立的，不影响部署 workflow。在 Actions 页面左侧点击 &lt;strong&gt;Deploy to Server&lt;/strong&gt; 查看部署专属日志。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4. 部署成功但网站没变化&lt;a href=&quot;#4-部署成功但网站没变化&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;解决&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;检查 Nginx 的 &lt;code&gt;root&lt;/code&gt; 是否指向 &lt;code&gt;/var/www/html&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;检查服务器是否安装了 &lt;code&gt;rsync&lt;/code&gt;：&lt;code&gt;apt install -y rsync&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;清除浏览器缓存或使用无痕模式访问&lt;/li&gt;
&lt;/ul&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;总结&lt;a href=&quot;#总结&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;




























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;做了什么&lt;/th&gt;&lt;th&gt;在哪里&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;SSH 密钥对&lt;/td&gt;&lt;td&gt;服务器 &lt;code&gt;/root/.ssh/&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;三个 Secrets&lt;/td&gt;&lt;td&gt;GitHub 仓库 Settings&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;deploy.yml&lt;/code&gt;&lt;/td&gt;&lt;td&gt;项目 &lt;code&gt;.github/workflows/&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Nginx 配置&lt;/td&gt;&lt;td&gt;服务器 &lt;code&gt;/etc/nginx/&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;本地代码&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;正常上传即可&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;</content:encoded></item></channel></rss>