<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Certbot on 我的博客</title><link>https://www.phyweicheng.com/tags/certbot/</link><description>Recent content in Certbot on 我的博客</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><lastBuildDate>Tue, 28 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.phyweicheng.com/tags/certbot/index.xml" rel="self" type="application/rss+xml"/><item><title>Hugo 博客自动部署到 VPS 的完整流程记录</title><link>https://www.phyweicheng.com/p/hugo-vps-auto-deploy/</link><pubDate>Tue, 28 Apr 2026 00:00:00 +0000</pubDate><guid>https://www.phyweicheng.com/p/hugo-vps-auto-deploy/</guid><description>&lt;img src="https://www.phyweicheng.com/p/hugo-vps-auto-deploy/cover.png" alt="Featured image of post Hugo 博客自动部署到 VPS 的完整流程记录" /&gt;&lt;p&gt;这篇笔记完整记录了我把一个本地 Hugo 博客部署到 VPS 的全过程，包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本地 Hugo 模板初始化与基础配置&lt;/li&gt;
&lt;li&gt;GitHub 仓库与 Actions 自动部署&lt;/li&gt;
&lt;li&gt;VPS 上的目录规划与 Nginx 配置&lt;/li&gt;
&lt;li&gt;域名解析与 HTTPS 证书申请&lt;/li&gt;
&lt;li&gt;常见问题排查&lt;/li&gt;
&lt;li&gt;这个过程中经常使用的命令与含义&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最终实现的效果是：本地写文章并提交到 GitHub 后，GitHub Actions 自动构建静态站点并发布到 VPS，网页内容自动更新。&lt;/p&gt;
&lt;h2 id="一目标与整体思路"&gt;一、目标与整体思路
&lt;/h2&gt;&lt;p&gt;我想实现的目标非常明确：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在本地维护 Hugo 博客内容&lt;/li&gt;
&lt;li&gt;通过 &lt;code&gt;git push&lt;/code&gt; 将更新提交到 GitHub&lt;/li&gt;
&lt;li&gt;GitHub Actions 自动构建 Hugo 站点&lt;/li&gt;
&lt;li&gt;将生成后的静态文件自动同步到 VPS&lt;/li&gt;
&lt;li&gt;由 Nginx 直接对外提供网页服务&lt;/li&gt;
&lt;li&gt;配置 HTTPS，让 &lt;code&gt;phyweicheng.com&lt;/code&gt; 和 &lt;code&gt;www.phyweicheng.com&lt;/code&gt; 都可以安全访问&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;整个流程可以概括为：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;本地修改文章
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; git commit / git push
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; GitHub Actions 自动构建 Hugo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; 通过 SSH/SCP 上传静态文件到 VPS
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; VPS 切换 current 软链接到最新版本
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; Nginx 读取 current 目录
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; 网站自动更新
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="二本地-hugo-模板部署"&gt;二、本地 Hugo 模板部署
&lt;/h2&gt;&lt;h3 id="1-准备-hugo-博客项目"&gt;1. 准备 Hugo 博客项目
&lt;/h3&gt;&lt;p&gt;首先需要在本地准备一个 Hugo 项目。我这里使用的是 Hugo Theme Stack 模板，并保留了标准的 Hugo 目录结构，例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;config/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;content/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;layouts/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;assets/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;themes/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;.github/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其中最关键的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;content/&lt;/code&gt;：文章内容&lt;/li&gt;
&lt;li&gt;&lt;code&gt;config/&lt;/code&gt;：站点配置&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.github/workflows/&lt;/code&gt;：GitHub Actions 自动部署配置&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-设置生产站点地址"&gt;2. 设置生产站点地址
&lt;/h3&gt;&lt;p&gt;在 Hugo 中，生产站点的域名需要通过 &lt;code&gt;baseurl&lt;/code&gt; 指定。我在配置文件中设置为：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;baseurl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://www.phyweicheng.com/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;对应文件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.phyweicheng.com/G:/Github_wei/Blog/config/_default/config.toml" &gt;config/_default/config.toml&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个值非常重要，因为 Hugo 在构建时会根据它生成页面中的链接、资源路径和 canonical URL。&lt;/p&gt;
&lt;h3 id="3-保持-public-不提交到仓库"&gt;3. 保持 &lt;code&gt;public/&lt;/code&gt; 不提交到仓库
&lt;/h3&gt;&lt;p&gt;Hugo 构建后的静态文件默认输出到 &lt;code&gt;public/&lt;/code&gt;。这部分不需要提交到 GitHub，而是交给 GitHub Actions 自动构建。&lt;/p&gt;
&lt;p&gt;因此 &lt;code&gt;.gitignore&lt;/code&gt; 中应当忽略：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;public
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这样可以避免把编译产物混入源码仓库。&lt;/p&gt;
&lt;h2 id="三将博客与-github-仓库连接"&gt;三、将博客与 GitHub 仓库连接
&lt;/h2&gt;&lt;h3 id="1-初始化-git-仓库并提交"&gt;1. 初始化 Git 仓库并提交
&lt;/h3&gt;&lt;p&gt;如果项目还没有连接 GitHub，基本流程如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add .
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit -m &lt;span class="s2"&gt;&amp;#34;init hugo blog&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch -M main
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git remote add origin &amp;lt;your-github-repo-url&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push -u origin main
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;完成后，本地博客项目就与 GitHub 仓库建立了连接。&lt;/p&gt;
&lt;h3 id="2-为什么要用-github-actions"&gt;2. 为什么要用 GitHub Actions
&lt;/h3&gt;&lt;p&gt;这里没有选择“在 VPS 上直接 &lt;code&gt;git pull&lt;/code&gt; 并构建 Hugo”，而是选择让 GitHub Actions 来完成构建，原因是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VPS 不需要安装 Hugo&lt;/li&gt;
&lt;li&gt;VPS 不需要保留完整源码仓库&lt;/li&gt;
&lt;li&gt;构建过程统一由 GitHub 执行，结果更稳定&lt;/li&gt;
&lt;li&gt;VPS 只保存最终静态文件，更适合静态站点部署&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="四配置-github-actions-自动部署"&gt;四、配置 GitHub Actions 自动部署
&lt;/h2&gt;&lt;h3 id="1-自动部署工作流的目标"&gt;1. 自动部署工作流的目标
&lt;/h3&gt;&lt;p&gt;自动部署的核心思路是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;当 &lt;code&gt;main&lt;/code&gt; 分支收到新的提交&lt;/li&gt;
&lt;li&gt;GitHub Actions 自动运行 Hugo 构建&lt;/li&gt;
&lt;li&gt;将构建好的静态文件打包&lt;/li&gt;
&lt;li&gt;通过 SSH 上传到 VPS&lt;/li&gt;
&lt;li&gt;在 VPS 上解压并切换到最新版本&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="2-工作流文件位置"&gt;2. 工作流文件位置
&lt;/h3&gt;&lt;p&gt;自动部署工作流文件放在：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.phyweicheng.com/G:/Github_wei/Blog/.github/workflows/deploy-vps.yml" &gt;deploy-vps.yml&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个工作流主要做了下面几件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;checkout 当前仓库&lt;/li&gt;
&lt;li&gt;安装 Go&lt;/li&gt;
&lt;li&gt;安装 Hugo Extended&lt;/li&gt;
&lt;li&gt;执行 &lt;code&gt;hugo --gc --minify&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;将 &lt;code&gt;public/&lt;/code&gt; 打成压缩包&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;appleboy/scp-action&lt;/code&gt; 上传到 VPS&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;appleboy/ssh-action&lt;/code&gt; 在 VPS 上切换部署版本&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-为什么要用-releases-和-current"&gt;3. 为什么要用 &lt;code&gt;releases&lt;/code&gt; 和 &lt;code&gt;current&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;在 VPS 上，我采用了这样的目录结构：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/var/www/phyweicheng-blog/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; releases/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; current -&amp;gt; /var/www/phyweicheng-blog/releases/&amp;lt;commit-sha&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;每次发布都会：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;生成一个新的版本目录&lt;/li&gt;
&lt;li&gt;把静态文件解压进去&lt;/li&gt;
&lt;li&gt;将 &lt;code&gt;current&lt;/code&gt; 软链接切换到新版本&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这种方案的好处是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;发布过程清晰&lt;/li&gt;
&lt;li&gt;方便回滚&lt;/li&gt;
&lt;li&gt;Nginx 永远读取固定路径 &lt;code&gt;current&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="五配置-github-actions-所需-secrets"&gt;五、配置 GitHub Actions 所需 Secrets
&lt;/h2&gt;&lt;p&gt;在 GitHub 仓库中进入：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Settings -&amp;gt; Secrets and variables -&amp;gt; Actions
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然后新增或确认以下 &lt;code&gt;Repository secrets&lt;/code&gt;：&lt;/p&gt;
&lt;h3 id="1-vps_ip"&gt;1. &lt;code&gt;VPS_IP&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;VPS 的公网 IP 地址。&lt;/p&gt;
&lt;h3 id="2-vps_user"&gt;2. &lt;code&gt;VPS_USER&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;GitHub Actions 登录 VPS 时使用的 Linux 用户名。&lt;/p&gt;
&lt;p&gt;如果直接使用 root 登录，可以写：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;root
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="3-vps_port"&gt;3. &lt;code&gt;VPS_PORT&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;SSH 登录端口。如果服务器 SSH 不是默认的 &lt;code&gt;22&lt;/code&gt;，这里需要填实际端口，例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;6626
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="4-vps_deploy_path"&gt;4. &lt;code&gt;VPS_DEPLOY_PATH&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;站点部署目录，例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/var/www/phyweicheng-blog
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="5-ssh_private_key"&gt;5. &lt;code&gt;SSH_PRIVATE_KEY&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;GitHub Actions 用于连接 VPS 的私钥内容。通常需要把本地或服务器生成的一对 SSH 密钥中的私钥完整粘贴到这里。&lt;/p&gt;
&lt;h2 id="六vps-上的目录准备"&gt;六、VPS 上的目录准备
&lt;/h2&gt;&lt;h3 id="1-创建部署目录"&gt;1. 创建部署目录
&lt;/h3&gt;&lt;p&gt;如果使用 root 部署，可以直接执行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mkdir -p /var/www/phyweicheng-blog/releases
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chown -R root:root /var/www/phyweicheng-blog
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果使用普通用户，例如 &lt;code&gt;deploy&lt;/code&gt;，则应改为：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chown -R deploy:deploy /var/www/phyweicheng-blog
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="2-检查-ssh-连通性"&gt;2. 检查 SSH 连通性
&lt;/h3&gt;&lt;p&gt;在正式自动部署前，最好先确认 GitHub 与 VPS 的 SSH 连通已经打通。&lt;/p&gt;
&lt;p&gt;如果 GitHub Actions 能顺利执行远程命令，说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;VPS_IP&lt;/code&gt; 正确&lt;/li&gt;
&lt;li&gt;&lt;code&gt;VPS_USER&lt;/code&gt; 正确&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SSH_PRIVATE_KEY&lt;/code&gt; 正确&lt;/li&gt;
&lt;li&gt;&lt;code&gt;VPS_PORT&lt;/code&gt; 正确&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="七配置-nginx-站点"&gt;七、配置 Nginx 站点
&lt;/h2&gt;&lt;h3 id="1-站点配置文件"&gt;1. 站点配置文件
&lt;/h3&gt;&lt;p&gt;我的 VPS 没有使用 &lt;code&gt;sites-available&lt;/code&gt; / &lt;code&gt;sites-enabled&lt;/code&gt; 结构，因此采用了 &lt;code&gt;conf.d&lt;/code&gt; 的方式。&lt;/p&gt;
&lt;p&gt;配置文件路径：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/etc/nginx/conf.d/phyweicheng-blog.conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="2-初始-http-配置"&gt;2. 初始 HTTP 配置
&lt;/h3&gt;&lt;p&gt;在申请证书之前，先配置 HTTP 站点：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-nginx" data-lang="nginx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;phyweicheng.com&lt;/span&gt; &lt;span class="s"&gt;www.phyweicheng.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="s"&gt;/var/www/phyweicheng-blog/current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri/&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;保存后执行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nginx -t
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl reload nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;只要域名已经解析到 VPS，这时就应该能通过 HTTP 访问网页。&lt;/p&gt;
&lt;h2 id="八域名解析配置"&gt;八、域名解析配置
&lt;/h2&gt;&lt;p&gt;为了让两个域名都能访问，需要在域名服务商后台配置 DNS 解析。&lt;/p&gt;
&lt;p&gt;推荐至少配置两条 A 记录：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;A @ -&amp;gt; VPS公网IP
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;A www -&amp;gt; VPS公网IP
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;含义如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@&lt;/code&gt; 表示裸域 &lt;code&gt;phyweicheng.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;www&lt;/code&gt; 表示 &lt;code&gt;www.phyweicheng.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只配置了 &lt;code&gt;www&lt;/code&gt;，那么通常只有 &lt;code&gt;www.phyweicheng.com&lt;/code&gt; 可以访问，而 &lt;code&gt;phyweicheng.com&lt;/code&gt; 无法访问。&lt;/p&gt;
&lt;h2 id="九申请-https-证书"&gt;九、申请 HTTPS 证书
&lt;/h2&gt;&lt;h3 id="1-安装-certbot"&gt;1. 安装 Certbot
&lt;/h3&gt;&lt;p&gt;我的系统是 Debian，因此安装方式如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install certbot python3-certbot-nginx -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="2-申请两个域名的证书"&gt;2. 申请两个域名的证书
&lt;/h3&gt;&lt;p&gt;执行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo certbot --nginx -d phyweicheng.com -d www.phyweicheng.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个命令会完成以下工作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;申请 Let’s Encrypt 证书&lt;/li&gt;
&lt;li&gt;自动修改 Nginx 配置&lt;/li&gt;
&lt;li&gt;为 &lt;code&gt;phyweicheng.com&lt;/code&gt; 和 &lt;code&gt;www.phyweicheng.com&lt;/code&gt; 绑定证书&lt;/li&gt;
&lt;li&gt;可选开启 HTTP 到 HTTPS 的自动跳转&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-证书申请后检查"&gt;3. 证书申请后检查
&lt;/h3&gt;&lt;p&gt;申请完成后，可以执行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nginx -t
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl reload nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ls -la /etc/letsencrypt/live/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ls -la /etc/letsencrypt/live/phyweicheng.com/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果能看到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;fullchain.pem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;privkey.pem&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;说明证书已经生成成功。&lt;/p&gt;
&lt;h2 id="十https-访问失败时的一个真实问题"&gt;十、HTTPS 访问失败时的一个真实问题
&lt;/h2&gt;&lt;p&gt;在本次部署过程中，曾经出现过一个很典型的问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;证书申请成功&lt;/li&gt;
&lt;li&gt;Nginx 配置正常&lt;/li&gt;
&lt;li&gt;但浏览器访问 &lt;code&gt;https://www.phyweicheng.com&lt;/code&gt; 仍然失败&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后排查发现，并不是证书有问题，而是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;443 端口被 xray 占用了
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;通过以下命令可以检查是谁占用了 443：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ss -tlnp &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="m"&gt;443&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果看到是 &lt;code&gt;xray&lt;/code&gt; 而不是 &lt;code&gt;nginx&lt;/code&gt;，就说明 HTTPS 请求没有交给 Nginx 处理。&lt;/p&gt;
&lt;p&gt;解决方法是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;修改 xray 配置，将其监听端口从 &lt;code&gt;443&lt;/code&gt; 改到其他端口，例如 &lt;code&gt;8443&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在客户端同步修改 xray 端口&lt;/li&gt;
&lt;li&gt;放行新的端口，例如 &lt;code&gt;8443&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;重新启动 xray 和 nginx&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;相关命令例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart xray
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow 8443/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="十一自动续期是否会生效"&gt;十一、自动续期是否会生效
&lt;/h2&gt;&lt;p&gt;只要使用的是 Debian 上标准安装的 &lt;code&gt;certbot&lt;/code&gt;，通常会自动配置续期机制。&lt;/p&gt;
&lt;p&gt;可以通过以下命令检查：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl list-timers &lt;span class="p"&gt;|&lt;/span&gt; grep certbot
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl status certbot.timer
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo certbot renew --dry-run
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;它们的作用分别是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查看是否存在 Certbot 定时任务&lt;/li&gt;
&lt;li&gt;查看续期定时器是否已启用&lt;/li&gt;
&lt;li&gt;模拟一次证书续期，确认自动续期链路没问题&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="十二首次上线后的完整发布流程"&gt;十二、首次上线后的完整发布流程
&lt;/h2&gt;&lt;p&gt;当以上步骤全部完成后，后续每次更新博客的流程就非常简单：&lt;/p&gt;
&lt;h3 id="1-在本地修改文章或页面"&gt;1. 在本地修改文章或页面
&lt;/h3&gt;&lt;p&gt;例如新建文章、修改配置、调整样式等。&lt;/p&gt;
&lt;h3 id="2-本地测试-hugo"&gt;2. 本地测试 Hugo
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo server
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;或者正式构建检查：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo --gc --minify
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="3-提交到-github"&gt;3. 提交到 GitHub
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add .
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit -m &lt;span class="s2"&gt;&amp;#34;update blog post&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push origin main
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="4-github-actions-自动执行部署"&gt;4. GitHub Actions 自动执行部署
&lt;/h3&gt;&lt;p&gt;推送成功后，GitHub 会自动：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;构建 Hugo 站点&lt;/li&gt;
&lt;li&gt;上传 &lt;code&gt;public/&lt;/code&gt; 产物到 VPS&lt;/li&gt;
&lt;li&gt;切换 &lt;code&gt;current&lt;/code&gt; 到最新版本&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="5-nginx-自动提供新内容"&gt;5. Nginx 自动提供新内容
&lt;/h3&gt;&lt;p&gt;因为 Nginx 的 &lt;code&gt;root&lt;/code&gt; 始终指向：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/var/www/phyweicheng-blog/current
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;所以网站内容会自动更新，不需要登录 VPS 手动 &lt;code&gt;git pull&lt;/code&gt; 或手动复制文件。&lt;/p&gt;
&lt;h2 id="十三常见问题总结"&gt;十三、常见问题总结
&lt;/h2&gt;&lt;h3 id="1-github-actions-checkout-失败"&gt;1. GitHub Actions checkout 失败
&lt;/h3&gt;&lt;p&gt;可能原因：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主题目录存在残留 submodule 信息&lt;/li&gt;
&lt;li&gt;仓库里有 gitlink，但没有 &lt;code&gt;.gitmodules&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;解决思路：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不依赖错误的 submodule checkout&lt;/li&gt;
&lt;li&gt;改用 Hugo module 的方式引入主题&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-phyweichengcom-能否访问取决于-dns"&gt;2. &lt;code&gt;phyweicheng.com&lt;/code&gt; 能否访问取决于 DNS
&lt;/h3&gt;&lt;p&gt;如果只有 &lt;code&gt;www.phyweicheng.com&lt;/code&gt; 能访问，通常是因为只解析了 &lt;code&gt;www&lt;/code&gt;，没有解析裸域 &lt;code&gt;@&lt;/code&gt;。&lt;/p&gt;
&lt;h3 id="3-https-无法访问但-http-正常"&gt;3. &lt;code&gt;https://&lt;/code&gt; 无法访问但 &lt;code&gt;http://&lt;/code&gt; 正常
&lt;/h3&gt;&lt;p&gt;重点检查：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nginx 是否监听 &lt;code&gt;443&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;443 是否被其他程序占用&lt;/li&gt;
&lt;li&gt;防火墙是否放行 &lt;code&gt;443&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;云厂商安全组是否放行 &lt;code&gt;443&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="4-xray-改端口后仍然无法连接"&gt;4. xray 改端口后仍然无法连接
&lt;/h3&gt;&lt;p&gt;重点检查：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;xray 是否真的监听了新端口&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ufw&lt;/code&gt; 和云安全组是否放行新端口&lt;/li&gt;
&lt;li&gt;客户端端口是否同步修改&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="十四这个过程中常用的命令汇总"&gt;十四、这个过程中常用的命令汇总
&lt;/h2&gt;&lt;p&gt;下面把整个部署过程中最常用的命令整理一下。&lt;/p&gt;
&lt;h3 id="1-git-相关"&gt;1. Git 相关
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;将当前修改加入暂存区。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit -m &lt;span class="s2"&gt;&amp;#34;message&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;生成一次本地提交记录。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push origin main
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;将本地提交推送到 GitHub 的 &lt;code&gt;main&lt;/code&gt; 分支，并触发自动部署。&lt;/p&gt;
&lt;h3 id="2-hugo-相关"&gt;2. Hugo 相关
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo server
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在本地启动开发服务器，方便预览博客效果。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo --gc --minify
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;执行正式构建：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--gc&lt;/code&gt;：清理无用缓存和资源&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--minify&lt;/code&gt;：压缩输出内容&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-nginx-相关"&gt;3. Nginx 相关
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nginx -t
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;检查 Nginx 配置语法是否正确。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl reload nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;平滑重载 Nginx 配置，不中断服务。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;重启 Nginx 服务，适合在重大配置变化后使用。&lt;/p&gt;
&lt;h3 id="4-certbot-相关"&gt;4. Certbot 相关
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo certbot --nginx -d phyweicheng.com -d www.phyweicheng.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;为两个域名申请证书，并自动写入 Nginx HTTPS 配置。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo certbot renew --dry-run
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;模拟续期，验证自动续期逻辑是否正常。&lt;/p&gt;
&lt;h3 id="5-端口与服务排查"&gt;5. 端口与服务排查
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ss -tlnp &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="m"&gt;443&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;检查谁正在监听 443 端口。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl status nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;查看 Nginx 当前状态。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl status xray
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;查看 xray 当前状态。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo journalctl -u xray -n &lt;span class="m"&gt;50&lt;/span&gt; --no-pager
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;查看 xray 最近的日志，便于定位启动失败和配置错误。&lt;/p&gt;
&lt;h3 id="6-防火墙相关"&gt;6. 防火墙相关
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw status
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;查看当前防火墙规则。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow 80/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow 443/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow 8443/tcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;分别放行 HTTP、HTTPS 和 xray 的自定义端口。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;重新加载防火墙规则。&lt;/p&gt;
&lt;h3 id="7-证书文件检查"&gt;7. 证书文件检查
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ls -la /etc/letsencrypt/live/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ls -la /etc/letsencrypt/live/phyweicheng.com/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;确认证书目录和文件是否存在。&lt;/p&gt;
&lt;h2 id="十五总结"&gt;十五、总结
&lt;/h2&gt;&lt;p&gt;这次部署的关键点并不只是“把网页放上去”，而是把整套链路打通：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本地负责内容维护&lt;/li&gt;
&lt;li&gt;GitHub 负责自动构建与自动发布&lt;/li&gt;
&lt;li&gt;VPS 负责稳定托管静态文件&lt;/li&gt;
&lt;li&gt;Nginx 负责网站访问&lt;/li&gt;
&lt;li&gt;Certbot 负责 HTTPS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当这套流程跑通以后，博客维护就会轻松很多。以后更新文章时，只需要：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add .
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit -m &lt;span class="s2"&gt;&amp;#34;update note&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push origin main
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;剩下的构建、上传、切换版本、网页更新，都会自动完成。&lt;/p&gt;
&lt;p&gt;如果以后继续扩展，还可以在这套基础上增加：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;评论系统&lt;/li&gt;
&lt;li&gt;访问统计&lt;/li&gt;
&lt;li&gt;备份与回滚脚本&lt;/li&gt;
&lt;li&gt;多环境部署&lt;/li&gt;
&lt;li&gt;自动化健康检查&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但对于一个 Hugo 静态博客来说，这样的部署方案已经足够稳定、清晰，也非常适合长期维护。&lt;/p&gt;</description></item></channel></rss>