<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>DaydreamNation</title><description>Enjoy Life</description><link>https://zhangbh.com/</link><templateTheme>Firefly</templateTheme><templateThemeVersion>6.7.12</templateThemeVersion><templateThemeUrl>https://github.com/CuteLeaf/Firefly</templateThemeUrl><lastBuildDate>2026年4月12日 23:59:06</lastBuildDate><item><title>本科回忆录 1</title><link>https://zhangbh.com/posts/bjut-life-1/</link><guid isPermaLink="true">https://zhangbh.com/posts/bjut-life-1/</guid><description>以此记录我的本科四年生活</description><pubDate>Sun, 12 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h1&gt;本科回忆录 1&lt;a href=&quot;#本科回忆录-1&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;还有两个月我就要毕业了，有闲心的时候开始整理我的本科四年生活，这四年有不少有意思的好玩的事情。担心之后忘记，所以准备记录在我的博客里，在赛博空间留下痕迹。这一栏目会按照时间排序。&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;大一入学前22年的暑假，我和陈茜去喝了北京的几家酒吧，算是第一次开始了解鸡尾酒。那段时间对喝酒还挺感兴趣的，回来之后就忍不住开始自己瞎调。一开始的理解其实非常粗糙，本质就是基酒兑饮料，能喝就行，完全谈不上什么风味结构之类的东西。&lt;/p&gt;&lt;p&gt;上了大学之后，我在朋友圈看到一个高中同学在学校里摆鸡尾酒摊卖酒，也想自己搞一个。于是我就拉上我的大学舍友刘乐，开始琢磨着在北工大也搞一个。最开始我是在校园墙发帖子摇人，结果还真有人来跟我交流。有个比我大一届的朋友告诉我，北工大其实已经有一个人在做鸡尾酒摊了，而且规模还挺大，群里都有好几百人。&lt;/p&gt;&lt;p&gt;他们当时做得挺大规模的，每天晚上在操场出摊，人一直很多，后面甚至还搞了个投影屏在那放电影，已经有点开酒吧的感觉了。不过没过一阵子就开始被保安制裁了。&lt;/p&gt;&lt;p&gt;但不管怎么说，还是决定自己试试。于是我开始做酒。当时用的配方基本都是从小红书现学的几个经典款：古典、威士忌酸、Highball 这些。基酒选得很劣质，基本就是白金宾、百加得这种最便宜的，调酒技术可以说是灾难级（蛆粪等级）。但靠着我和刘乐卖力吆喝，这个摊子最后居然回本了，甚至还赚了几十块钱。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;我手写的酒单，之后有个PS做的&quot; loading=&quot;lazy&quot; width=&quot;1075&quot; height=&quot;1226&quot; src=&quot;/_astro/menu.CLlSOZbO_Z1Oplxq.webp&quot; /&gt;&lt;figcaption&gt;我手写的酒单，之后有个PS做的&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;中间最难绷的事情是。有天晚上我和刘乐在南操场门口免费送鸡尾酒，结果碰到我们专业的同学。上来第一句话就是问我们：“这个喝了不会中毒吧？”（具体原话记不太清了，大概是这个意思。）但问完之后她还是拿了一杯走了（教父），至于最后喝没喝，我也不知道。到现在那瓶用来调的蒂萨诺杏仁利口酒还在我宿舍柜子的鞋柜里。&lt;/p&gt;&lt;p&gt;这个酒摊其实没做几天就不了了之了。原因很简单，就是懒，后面就没有再继续折腾。但对鸡尾酒的兴趣倒是一直保留到了现在，算是一个鸡尾酒启蒙吧，当时把小红书里的简单鸡尾酒制作帖子看了一遍，认识了不少经典鸡尾酒，但基本上就是记住配方，对酒的结构没有认识。现在再回头看，当时卖的那些酒确实是烂得离谱，但作为一段经历来说，还是挺好玩的。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;出摊的一晚我在宿舍的吧台&quot; loading=&quot;lazy&quot; width=&quot;2400&quot; height=&quot;1800&quot; src=&quot;/_astro/bar0.DAzmsWIH_Z1blrCR.webp&quot; /&gt;&lt;figcaption&gt;出摊的一晚我在宿舍的吧台&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;我的垃圾基酒们，甚至还有一个可乐桶&quot; loading=&quot;lazy&quot; width=&quot;2400&quot; height=&quot;1800&quot; src=&quot;/_astro/bar1.70OC0aJT_Z7t2Eh.webp&quot; /&gt;&lt;figcaption&gt;我的垃圾基酒们，甚至还有一个可乐桶&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;喝酒快乐时光&quot; loading=&quot;lazy&quot; width=&quot;1350&quot; height=&quot;1800&quot; src=&quot;/_astro/drinktime.BRv7tTfz_Z21kRfU.webp&quot; /&gt;&lt;figcaption&gt;喝酒快乐时光&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;劣质预制柠檬汁&quot; loading=&quot;lazy&quot; width=&quot;1012&quot; height=&quot;1800&quot; src=&quot;/_astro/lemon.DK0VNHd5_R0KHI.webp&quot; /&gt;&lt;figcaption&gt;劣质预制柠檬汁&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>Git 忽略规则踩坑：为什么 .gitignore 有时候完全没用？</title><link>https://zhangbh.com/posts/how-to-rm-git-track-file/</link><guid isPermaLink="true">https://zhangbh.com/posts/how-to-rm-git-track-file/</guid><description>一次误提交 cache 和 log 文件后的排雷记录，以及 Git 跟踪机制的本质理解。</description><pubDate>Wed, 08 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h1&gt;Git 忽略规则踩坑：为什么 .gitignore 有时候完全没用？&lt;a href=&quot;#git-忽略规则踩坑为什么-gitignore-有时候完全没用&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;在项目刚初始化的时候，我犯了一个非常经典的错误：&lt;/p&gt;&lt;p&gt;👉 &lt;strong&gt;没有提前写 &lt;code&gt;.gitignore&lt;/code&gt;，直接把整个仓库 commit + push 了。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;结果就是：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;log&lt;/code&gt;、&lt;code&gt;cache&lt;/code&gt;、&lt;code&gt;dist&lt;/code&gt; 全部进仓库&lt;/li&gt;
&lt;li&gt;仓库迅速变脏&lt;/li&gt;
&lt;li&gt;后面再加 &lt;code&gt;.gitignore&lt;/code&gt;，发现——&lt;strong&gt;完全没用&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这篇就是一次完整的踩坑复盘。&lt;/p&gt;&lt;hr /&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;init&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;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;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;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;first commit&quot;&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;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;然后你才意识到应该加：&lt;/p&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;*.log&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;cache/&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;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;/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;rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;out.log&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;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;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;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;remove log&quot;&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;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;然后程序一运行，又生成：&lt;/p&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;out.log&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;/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;status&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;它居然还在被跟踪（modified）&lt;/strong&gt;&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;p&gt;很多人会误以为：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;“我都加 &lt;code&gt;.gitignore&lt;/code&gt; 了，为什么 Git 还管这个文件？”&lt;/p&gt;&lt;/blockquote&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;blockquote&gt;&lt;p&gt;&lt;code&gt;.gitignore&lt;/code&gt; &lt;strong&gt;只对未被跟踪的文件生效&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;🧠 Git 的真实逻辑&lt;a href=&quot;#-git-的真实逻辑&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Git 只关心一件事：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;这个文件 &lt;strong&gt;有没有被跟踪（tracked）过&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;一旦某个文件进入过版本库：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;它就变成 &lt;strong&gt;tracked file&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.gitignore&lt;/code&gt; 对它 &lt;strong&gt;完全失效&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&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：你只是删除了文件 ❌&lt;a href=&quot;#情况-1你只是删除了文件-&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&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;rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;out.log&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;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;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;commit&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;/p&gt;&lt;ul&gt;
&lt;li&gt;Git 认为你只是“删除了一个 tracked 文件”&lt;/li&gt;
&lt;li&gt;下次再生成 &lt;code&gt;out.log&lt;/code&gt;：&lt;/li&gt;
&lt;/ul&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;status&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;/p&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;modified: out.log&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;&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;情况 2：你取消了跟踪 ✅（正确做法）&lt;a href=&quot;#情况-2你取消了跟踪-正确做法&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&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;rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--cached&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;out.log&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;stop tracking out.log&quot;&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;/p&gt;&lt;ul&gt;
&lt;li&gt;Git 不再跟踪这个文件&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.gitignore&lt;/code&gt; 开始生效&lt;/li&gt;
&lt;/ul&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;status&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;👉 什么都没有（被 ignore）&lt;/p&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;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;rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-r&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--cached&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;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;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;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;apply gitignore properly&quot;&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;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;section&gt;&lt;h3&gt;这一步做了什么？&lt;a href=&quot;#这一步做了什么&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;清空所有已跟踪文件（仅索引，不删本地）&lt;/li&gt;
&lt;li&gt;重新按 &lt;code&gt;.gitignore&lt;/code&gt; 规则添加&lt;/li&gt;
&lt;li&gt;让 ignore 真正生效&lt;/li&gt;
&lt;/ol&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;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;status&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;section&gt;&lt;h3&gt;正常情况：&lt;a href=&quot;#正常情况&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;out.log&lt;/code&gt; &lt;strong&gt;不会出现&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/section&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;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;modified: out.log&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;/p&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;p&gt;&lt;code&gt;.gitignore&lt;/code&gt; 写错路径：&lt;/p&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;log/&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;/p&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;logs/&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;/p&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;log/&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;/p&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;out.log&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;/p&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;*.log&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;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;如果这些 log 已经进入历史（导致仓库很大），需要：&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;filter-repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--path-glob&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;*.log&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--invert-paths&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;push&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;origin&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--force&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--all&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;/p&gt;&lt;ul&gt;
&lt;li&gt;会重写历史&lt;/li&gt;
&lt;li&gt;团队协作需要提前沟通&lt;/li&gt;
&lt;/ul&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;ol&gt;
&lt;li&gt;&lt;code&gt;.gitignore&lt;/code&gt; &lt;strong&gt;不会影响已被跟踪的文件&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;删除文件 ≠ 取消跟踪&lt;/li&gt;
&lt;li&gt;必须用 &lt;code&gt;git rm --cached&lt;/code&gt; 才能真正“忽略已提交文件”&lt;/li&gt;
&lt;/ol&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;blockquote&gt;&lt;p&gt;Git 关心的是“这个文件是否被记录过”，
而不是“这个文件现在存不存在”。&lt;/p&gt;&lt;/blockquote&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;p&gt;但一旦理解了 Git 的 tracking 机制，其实逻辑非常简单：&lt;/p&gt;&lt;p&gt;👉 &lt;strong&gt;ignore 是入口规则，不是清理工具。&lt;/strong&gt;&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>大连周末散心：喝喝</title><link>https://zhangbh.com/posts/dalian-drink/</link><guid isPermaLink="true">https://zhangbh.com/posts/dalian-drink/</guid><description>在冬天的尾声，张博涵请了一天假，来大连享受他的周末。</description><pubDate>Sun, 29 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h1&gt;大连周末散心：喝喝&lt;a href=&quot;#大连周末散心喝喝&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;大连作为一个在东北、但性格很不东北的城市，有不少还不错的鸡尾酒吧。这次去也尝试了两家，总的来说价格比北京便宜，出品也还不错，没有特别惊喜，但也没有很失望。&lt;/p&gt;&lt;section&gt;&lt;h2&gt;EXIT&lt;a href=&quot;#exit&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;小红书上很火的一家店，装修是包豪斯风格。七点开门，我和陈茜七点半到的时候，就只剩最后两个吧台座位了，而且还是两个不挨着的。后来遇到一个一个人来的老哥，人挺不错，挪了一个座位出来，才让我俩坐进去。&lt;/p&gt;&lt;p&gt;这家酒吧主要还是来打卡的小红书女用户比较多，点酒单里特调的人也偏多。他们家的酒单很有意思，只有 1-8 八个数字，对应八款酒，价格统一都是 75 元。前面几款基本都是果味偏重的小甜酒，我不太爱喝这类，所以没啥太多好说的，但难得来一次，还是尝试了几款特调。&lt;/p&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;这款酒是朗姆 base，加了一些雪莉，再配上青提、青柠的果味酒。酒精感很淡，果味很浓，不难喝，但我没喝出来什么特别的地方。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;#6&lt;a href=&quot;#6&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;用了烧酒的一款长饮，蜜瓜味很浓，也是一款没什么酒味的小甜酒。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;两款特调&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;1707&quot; src=&quot;/_astro/exit0.C2t2N-SZ_12t5eP.webp&quot; /&gt;&lt;figcaption&gt;两款特调&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;喝完两款特调后，终于还是忍不住回到舒适区了。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Gimlet&lt;a href=&quot;#gimlet&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;一杯挺有意思的 Gimlet，base gin 用的是 Sipsmith Sloe Gin。相比普通干金酒，杜松子味确实没有那么重，但酒本身的风味也没有特别被凸显出来，总的来说是一杯合格的出品。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;Gimlet&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;1707&quot; src=&quot;/_astro/exit1.FclYAZXn_Z2c1cIi.webp&quot; /&gt;&lt;figcaption&gt;Gimlet&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Bamboo&lt;a href=&quot;#bamboo&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;用了曼齐诺和 Tio Pepe 两款酒，喝上去比我自己做的涩感更轻。之前我自己做的时候用的是杜林干味美思，总感觉涩感很重，但也不算难喝。喝他们这杯的时候，明显觉得涩口感轻了不少，不知道是配方的原因，还是干味美思本身的原因。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;Tidal&lt;a href=&quot;#tidal&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;也是一家在小红书里号称“大连第一”的酒吧，环境也很棒，酒吧外面摆满了空瓶的季之美。&lt;/p&gt;&lt;p&gt;七点开门，我和陈茜七点零五就到了。因为还要赶晚上九点十五的晚班机回北京，这里不得不夸一下大连周水子机场，修在市区里，机场也不大，从市区酒吧打车过去也就二十分钟，完全不用太早到。九点的飞机，七点半我还在喝鸡尾酒，这在北京肯定是做不到的。&lt;/p&gt;&lt;p&gt;不过因为时间确实不长，所以这里只喝了两杯。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;两款特调&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;1707&quot; src=&quot;/_astro/tidal0.Bhi3OWug_eD9tw.webp&quot; /&gt;&lt;figcaption&gt;两款特调&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;section&gt;&lt;h3&gt;Twentieth Century&lt;a href=&quot;#twentieth-century&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;一款很有意思的短饮鸡尾酒，Gin base，带有可可——我喝起来更像白巧克力——和柑橘的香气。可可这个味道非常有意思，也是我第一次在鸡尾酒里喝到，挺好喝。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;White Gimlet&lt;a href=&quot;#white-gimlet&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;也是这里的一杯特调，但我不太喜欢。总之就是在 Gimlet 里加上了很浓的茶味，不是那种茶香，而更像是加了浓缩茶，茶味几乎盖住了所有鸡尾酒本身的味道，一般般。&lt;/p&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;p&gt;总之，喝得很开心，但感觉这边的老板没有北京酒吧的老板好玩。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>大连周末散心：吃吃</title><link>https://zhangbh.com/posts/dalian-food/</link><guid isPermaLink="true">https://zhangbh.com/posts/dalian-food/</guid><description>在冬天的尾声，张博涵请了一天假，来大连享受他的周末。</description><pubDate>Thu, 26 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h1&gt;大连周末散心：吃吃&lt;a href=&quot;#大连周末散心吃吃&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;上班实在没劲，于是请了周五一天假期给自己凑了一个周末散心。24年的夏日也来了大连旅游，但那一次是暑期的七月旺季，去哪哪都人山人海，还被出租车司机待到贵价宰客的海鲜店，实在没有太多好的经历。于是这一次来打算不去什么打卡点，就吃吃日料喝点小酒，现在看来是一个正确的选择。聊到吃在大连一定离不开日料，据说大连有一千多家日料店，水平也相当不错，很卷，而且价钱也比北京更实惠，这次来吃了三家日料店，吃的尽兴。&lt;/p&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;这家店是小红书上推荐的一家店，主营拉面，店面就开在大连的日料一条街中间。人气很火爆，我们在工作日周五的中午 11:30（开门时间）进店，已经有几桌坐下了，过了十五分钟基本就只能等位。&lt;/p&gt;&lt;p&gt;我和陈茜点了鱼介和咖喱的沾面，面条很筋道，也很香。口味上我感觉也稍微为中国人做了些调整，并没有很油腻或者很咸。赶了早班机的我们吃完之后，就美美打车回酒店晕碳睡去了，一觉睡到三点才起。&lt;/p&gt;&lt;p&gt;对这家店的评价，我觉得和北京我爱吃的日出拉面也没啥区别，挺正宗的。更讲究的口味我也吃不太出来了，总之就是吃得过瘾尽兴，而且还不贵。（30一碗）&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;两份拉面&quot; loading=&quot;lazy&quot; width=&quot;1455&quot; height=&quot;1168&quot; src=&quot;/_astro/ramen.CJYItfwX_6mvxW.webp&quot; /&gt;&lt;figcaption&gt;两份拉面&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&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;p&gt;这家的烧鸟菜单就是常规的经典烧鸟，比较稀少的内脏和特殊部位并没有提供，味道也是中规中矩。老板娘不算太热情，但基本的服务都有。价格也比较美丽，能吃得很爽。美中不足的是，菜单上提供了朝日扎啤，我本来以为可以喝个爽，但似乎啤酒冰镇得并不是很足，没有到达最好的口感。&lt;/p&gt;&lt;p&gt;这家店我和陈茜吃得都有点撑了，也就花了 200 元。在北京，同档次的一顿怎么找也得三百多了，性价比还是不错。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;提灯&quot; loading=&quot;lazy&quot; width=&quot;1458&quot; height=&quot;996&quot; src=&quot;/_astro/Shaoniao0.CG9kqGAN_15q9Q3.webp&quot; /&gt;&lt;figcaption&gt;提灯&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;鸡肉串和啤酒&quot; loading=&quot;lazy&quot; width=&quot;1452&quot; height=&quot;1681&quot; src=&quot;/_astro/shaoniao1.sVgUXl9x_BqIN6.webp&quot; /&gt;&lt;figcaption&gt;鸡肉串和啤酒&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&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;p&gt;分量不算小，也不算大，对晚上还要去酒吧喝酒的安排来说刚刚好。我一直盼着吃到真正好吃的生海胆，但这次还是让我有点失望。在日本小店或者在大连小店，都没有让我品尝到特别惊艳的海胆。或许海胆就是如此设计吧。我想象中它应该是鲜甜可口的，但那种吃进嘴里黏黏的感觉，总让我想到秋葵中间的粘液。&lt;/p&gt;&lt;p&gt;不过总之，海鲜饭加点酱油，配上米饭，还是很美味的，好评！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;海鲜饭&quot; loading=&quot;lazy&quot; width=&quot;1459&quot; height=&quot;1201&quot; src=&quot;/_astro/seafoodbowl.CcrQbnAl_Z1xX6xy.webp&quot; /&gt;&lt;figcaption&gt;海鲜饭&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>Gimlet 的新尝试：薄荷金酒与利10号的对话</title><link>https://zhangbh.com/posts/mint-gimlet/</link><guid isPermaLink="true">https://zhangbh.com/posts/mint-gimlet/</guid><description>在这个版本的 Gimlet 中，我尝试了二世谷蒸馏所的薄荷金酒与利10号的微妙融合，带来清爽与深度并存的体验。</description><pubDate>Mon, 16 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h1&gt;Gimlet 的新尝试：薄荷金酒与利10号的对话&lt;a href=&quot;#gimlet-的新尝试薄荷金酒与利10号的对话&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;调酒如同写作，每一次配比的微调，都是对风味与平衡的思考。今天，我再次尝试用二月份旅行时带回的二世谷蒸馏所薄荷味金酒制作 Gimlet。其实，这只金酒我之前已经尝试过两次。&lt;/p&gt;&lt;p&gt;第一次，我用了 30ml 常规伦敦干金搭配 15ml 薄荷金酒。薄荷的风味并不突出，反而被杜松子的香气掩盖。第二次，我吸取了上一次的经验，全量使用薄荷金酒。这次薄荷风味非常浓烈，喝下去甚至让嗓子感到一丝冰凉。如果追求饱满的薄荷感，这是一个不错的选择，但相对缺乏平衡。&lt;/p&gt;&lt;p&gt;今天，我尝试了 30ml 薄荷金酒搭配 15ml 利十号的组合，结果是这几次最满意的一杯。通过这几次实验，我也开始思考经典鸡尾酒配方的新方式——将基酒拆解为“常规基酒”与“风味基酒”，在保留酒体骨架的同时，引入更多个性化风味。&lt;/p&gt;&lt;p&gt;我在初识调酒时，看网上视频里的调酒师们，总是用这样的方式来展现他们对于鸡尾酒的理解，于是照猫画虎的也学着这样做，但是有些时候还不如完全按照经典配方好喝。在这次尝试之后，我开始更认真地思考“将基酒拆解为传统基酒与风味基酒”的操作。表面上，这看似只是把经典配方稍加修改：把原本的单一金酒分解为“骨架酒”和“风味酒”，再进行比例调节。然而，真正的价值不在于形式上的变化，而在于对风味层次的理解与掌控。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;思考的核心在于：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;传统基酒&lt;/strong&gt;承担了鸡尾酒的结构和重量，是喝进嘴里后的质感。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;风味酒&lt;/strong&gt;则提供个性化香气与味觉印记，让经典配方产生新的风景。&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;关键在于要找到能让人感到这杯酒还是Gimlet，但是特色风味也很突出的临界点。&lt;/p&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;ul&gt;
&lt;li&gt;&lt;strong&gt;添加利10号&lt;/strong&gt;：15ml&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;二世谷蒸馏所薄荷味金酒&lt;/strong&gt;：30ml&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;青柠汁&lt;/strong&gt;：15ml&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;单糖浆&lt;/strong&gt;：一吧勺&lt;/li&gt;
&lt;/ul&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;ol&gt;
&lt;li&gt;准备Shaker，加入利10号与薄荷金酒。&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;/li&gt;
&lt;/ol&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;ul&gt;
&lt;li&gt;&lt;strong&gt;添加利10号&lt;/strong&gt;：骨架，深度，微苦，柑橘香气。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;薄荷金酒&lt;/strong&gt;：清爽、香气，带来风味。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;青柠汁&lt;/strong&gt;：酸度拉升层次感。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;单糖浆&lt;/strong&gt;：平衡酸度，柔化酒体。&lt;/li&gt;
&lt;/ul&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;这款 Gimlet 是经典与创新的结合。&lt;br /&gt;
每一次调制都是实验，每一次尝试都值得记录。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>浅谈柯达电影卷5219：一款“全能”的胶卷</title><link>https://zhangbh.com/posts/film-5219/</link><guid isPermaLink="true">https://zhangbh.com/posts/film-5219/</guid><description>北京雪景下拍摄柯达5219胶卷的体验与心得，探讨它的色彩表现、宽容度和全能特性。</description><pubDate>Fri, 13 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2&gt;浅谈柯达电影卷5219：一款“全能”的胶卷&lt;a href=&quot;#浅谈柯达电影卷5219一款全能的胶卷&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;趁着北京的雪景，我终于把放在相机里小半学期的柯达5219拍完了。冲扫后的底片效果超出了我对这卷胶卷的预期，让我对它有了更深的认识。&lt;/p&gt;&lt;p&gt;作为柯达彩色负片系列中的灯光卷，5219在很多人的印象里偏蓝，尤其是在日光下。然而，这次的拍摄却让5219的偏蓝色调与雪天意外契合。雪地在冷色调的渲染下显得格外洁白，仿佛连空气都透着透明的寒意；阴天微弱的光线在画面中形成柔和的阴影，让每一片雪花都仿佛有了质感。这样的效果，比我想象中更有电影感，也让普通的雪景显得生动而不单调。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;下雪的四教天台&quot; loading=&quot;lazy&quot; width=&quot;2075&quot; height=&quot;3130&quot; src=&quot;/_astro/wangqiuxue.De4vEW1v_ZelvrU.webp&quot; /&gt;&lt;figcaption&gt;下雪的四教天台&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;5219给我最深的印象是它的“全能”。在ISO500下，它就能展现出细腻而丰富的画面质感；据说它是目前唯一可以稳定迫冲至ISO1600的彩色负片，这意味着即便在光线不足的室内或傍晚，也能拍出清晰、干净的照片。更难得的是它的宽容度：暗部细节丰富，即便是被雪反射的高光区域，也没有出现过度曝光或细节丢失的情况。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;四教天台&quot; loading=&quot;lazy&quot; width=&quot;2075&quot; height=&quot;3130&quot; src=&quot;/_astro/stadium.D9aQ4M11_Zi8Gqn.webp&quot; /&gt;&lt;figcaption&gt;四教天台&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;拍摄这卷5219的过程，也让我重新感受到胶片的魅力。在雪地中，按下快门的瞬间，白色的世界仿佛被定格，每一张照片都带着微微的冷意与静谧感。那种慢慢等待冲扫结果的期待，也让拍摄本身变成了一种仪式感。&lt;/p&gt;&lt;p&gt;总体来说，5219对我而言是一款非常适合日常随手拍的胶卷。ISO500就能应对大多数光线环境，而它的色彩与宽容度又为创作提供了更多空间。未来的日常拍摄，我相信它还会继续陪伴我，把平凡的瞬间变成有质感的影像。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;我的水杯&quot; loading=&quot;lazy&quot; width=&quot;3130&quot; height=&quot;2075&quot; src=&quot;/_astro/shuibei.Dt8nlS5C_ceJt3.webp&quot; /&gt;&lt;figcaption&gt;我的水杯&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>揭秘 ARP：IP 地址如何找到 MAC 地址</title><link>https://zhangbh.com/posts/how-arp-works/</link><guid isPermaLink="true">https://zhangbh.com/posts/how-arp-works/</guid><description>ARP协议的原理简要</description><pubDate>Fri, 13 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在计算机网络中，数据的传输遵循 OSI 七层模型，每一层都有其独特的职责与接口。当我们发送数据包时，位于第三层（网络层）的数据包携带了目标 IP 地址，但在传输到第二层（数据链路层）时，还需要添加目标节点的物理地址（MAC 地址）才能在局域网中正确传输。然而，网络层和链路层之间并没有直接关联，那么系统如何知道目标 IP 对应的 MAC 地址呢？这就是 &lt;strong&gt;ARP（Address Resolution Protocol，地址解析协议）&lt;/strong&gt; 的用武之地。&lt;/p&gt;
&lt;section&gt;&lt;h2&gt;什么是 ARP？&lt;a href=&quot;#什么是-arp&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;ARP 是 TCP/IP 协议族中的一个关键协议，用于根据 IP 地址获取物理地址。通俗来说，当上层协议需要向某个 IP 发送数据包时，ARP 可以提供该节点对应的 MAC 地址，从而完成数据的帧封装与传输。&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;ARP 的工作原理&lt;a href=&quot;#arp-的工作原理&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&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;p&gt;假设有两台主机 A 和 B 位于同一局域网内，ARP 的工作流程如下：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查找 ARP 缓存表&lt;/strong&gt;
主机 A 首先检查本地 ARP 缓存表，看是否已经存在主机 B 的 MAC 地址。如果存在，则直接使用缓存的 MAC 地址封装数据帧，并发送给 B。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;发送 ARP 请求&lt;/strong&gt;
如果缓存中没有目标 MAC 地址，主机 A 会将数据报暂存，并以广播方式发送 ARP 请求。请求报文中包含主机 A 的 IP 和 MAC 地址，以及目标 IP（主机 B）的地址，目标 MAC 设置为全 0。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ARP 响应&lt;/strong&gt;
网段内的所有主机都会接收到请求，但只有目标主机 B 会处理。当 B 检查到请求中的目标 IP 与自身 IP 匹配时，它会将主机 A 的 IP 和 MAC 存入自己的 ARP 表，并发送 ARP 响应报文（包含自身 MAC 地址）给 A。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;更新缓存与发送数据&lt;/strong&gt;
主机 A 收到响应后，将主机 B 的 MAC 地址加入 ARP 缓存，然后完成数据包的封装与发送。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;/section&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;p&gt;当主机 A 与 B 不在同一网段时，ARP 仍然是数据包到达目标的关键：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;主机 A 向本地网关发送 ARP 请求，请求目标 IP 为网关地址。&lt;/li&gt;
&lt;li&gt;获得网关 MAC 地址后，A 将数据包封装并发送给网关。&lt;/li&gt;
&lt;li&gt;如果网关未缓存主机 B 的 MAC 地址，它会广播 ARP 请求获取 B 的 MAC 地址；否则，直接将报文转发给 B。&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;通过这样的机制，无论主机是否在同一网段，ARP 都保证了 IP 到 MAC 的映射，从而实现局域网或跨网段的数据传输。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;ARP 数据包结构&lt;a href=&quot;#arp-数据包结构&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;ARP 报文包含一个关键字段 &lt;strong&gt;Opcode&lt;/strong&gt;：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;1&lt;/strong&gt; 表示请求（Request）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2&lt;/strong&gt; 表示应答（Reply）&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这使得网络中的设备可以区分报文类型，确保正确响应或请求 MAC 地址。&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;ARP 看似简单，但它是局域网通信中不可或缺的基础组件。理解 ARP 的工作机制，有助于网络调试、故障排查以及网络安全防护。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;</content:encoded></item><item><title>从 0 开始：在阿里云 ECS 上部署 Astro 博客，并用 GitHub Actions 自动发布</title><link>https://zhangbh.com/posts/build-astro-blog/</link><guid isPermaLink="true">https://zhangbh.com/posts/build-astro-blog/</guid><description>部署 Astro 一步步的详解</description><pubDate>Thu, 12 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;最近把个人博客从本地开发环境迁移到了阿里云 ECS。服务器是全新实例，系统为 &lt;strong&gt;Ubuntu 24.04.4 LTS&lt;/strong&gt;。这篇文章完整记录了从一台空白 ECS 开始，到博客可通过域名访问、启用 HTTPS，并且支持 GitHub Actions 自动部署的整个过程。&lt;/p&gt;
&lt;p&gt;这篇文章适合以下场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你有一台全新的阿里云 ECS&lt;/li&gt;
&lt;li&gt;你想部署的是 &lt;strong&gt;Astro 静态博客&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;你已经有自己的域名&lt;/li&gt;
&lt;li&gt;你希望博客支持 HTTPS&lt;/li&gt;
&lt;li&gt;你希望以后写完文章后，执行 &lt;code&gt;git push&lt;/code&gt; 就能自动上线&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本文最终实现的架构如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本地电脑负责写博客和提交代码&lt;/li&gt;
&lt;li&gt;GitHub Actions 自动安装依赖、构建 Astro 项目&lt;/li&gt;
&lt;li&gt;构建产物 &lt;code&gt;dist/&lt;/code&gt; 自动上传到 ECS&lt;/li&gt;
&lt;li&gt;ECS 上的 Nginx 直接托管静态文件&lt;/li&gt;
&lt;li&gt;域名解析到 ECS 公网 IP&lt;/li&gt;
&lt;li&gt;网站通过 HTTPS 对外提供服务&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;section&gt;&lt;h1&gt;一、为什么选择这种部署方式&lt;a href=&quot;#一为什么选择这种部署方式&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Astro 博客本质上非常适合静态部署。对于个人博客来说，没有必要在服务器上长期运行 Node 服务，更没必要把 ECS 当构建机。&lt;/p&gt;&lt;p&gt;更稳妥的做法是：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;本地或 GitHub Actions 负责构建&lt;/li&gt;
&lt;li&gt;服务器只负责托管静态文件&lt;/li&gt;
&lt;li&gt;Nginx 负责访问入口和 HTTPS&lt;/li&gt;
&lt;li&gt;GitHub Actions 负责自动发布&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这种方式有几个明显优点：&lt;/p&gt;&lt;p&gt;第一，服务器压力小。
第二，架构简单，出问题时容易排查。
第三，CI/CD 清晰，后续维护成本很低。
第四，适合 Astro、Vite 一类静态站点项目。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;二、准备工作&lt;a href=&quot;#二准备工作&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;开始之前，需要准备好以下几样东西：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;一台阿里云 ECS，系统为 Ubuntu 24.04&lt;/li&gt;
&lt;li&gt;ECS 拥有公网 IP&lt;/li&gt;
&lt;li&gt;一个已经注册好的域名&lt;/li&gt;
&lt;li&gt;GitHub 仓库&lt;/li&gt;
&lt;li&gt;本地已经有 Astro 项目，或者准备新建一个&lt;/li&gt;
&lt;li&gt;一个可用的 SSL 证书（本文采用手动部署证书，而不是 Certbot）&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果你的 ECS 在中国大陆节点，网站正式上线前还需要关注备案要求。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;三、服务器基础初始化&lt;a href=&quot;#三服务器基础初始化&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;先通过 SSH 登录 ECS。&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&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;root@你的ECS公网IP&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;/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;apt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;upgrade&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-y&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;apt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-y&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nginx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;unzip&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ufw&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;如果你希望启用 Ubuntu 防火墙，可以继续执行：&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;ufw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;allow&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OpenSSH&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;ufw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;allow&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;80/tcp&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;ufw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;allow&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;443/tcp&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;ufw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;enable&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;ufw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;status&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;此外，在阿里云 ECS 控制台里，还需要确认安全组已开放以下端口：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;22（SSH）&lt;/li&gt;
&lt;li&gt;80（HTTP）&lt;/li&gt;
&lt;li&gt;443（HTTPS）&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果安全组没有开放 80/443，即便 Nginx 配好了，外部也无法访问网站。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;四、配置域名解析&lt;a href=&quot;#四配置域名解析&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;进入域名的 DNS 管理后台，添加两条 A 记录：&lt;/p&gt;&lt;p&gt;主域名解析：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;记录类型：A&lt;/li&gt;
&lt;li&gt;主机记录：&lt;code&gt;@&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;记录值：ECS 公网 IP&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;www 子域名解析：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;记录类型：A&lt;/li&gt;
&lt;li&gt;主机记录：&lt;code&gt;www&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;记录值：ECS 公网 IP&lt;/li&gt;
&lt;/ul&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;ping&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yourdomain.com&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;ping&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;www.yourdomain.com&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;如果解析结果已经指向 ECS 公网 IP，就说明域名已经生效。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;五、准备博客部署目录&lt;a href=&quot;#五准备博客部署目录&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&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;mkdir&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/var/www/astro-blog&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;chown&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-R&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;www-data:www-data&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/var/www/astro-blog&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;chmod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-R&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;755&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/var/www/astro-blog&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;为了便于确认 Nginx 配置是否成功，可以先放一个临时测试页面：&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;cat&lt;/span&gt;&lt;span&gt; &amp;gt; &lt;/span&gt;&lt;span&gt;/var/www/astro-blog/index.html&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;EOF&apos;&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;lt;!&lt;/span&gt;&lt;span&gt;doctype&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;html&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;&amp;lt;html&amp;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;&amp;lt;head&amp;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;&amp;lt;meta&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;charset=&quot;utf-8&quot;&amp;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;&amp;lt;title&amp;gt;Astro&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Blog&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Ready&amp;lt;/title&amp;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;span&gt;  &lt;/span&gt;&lt;span&gt;&amp;lt;/head&amp;gt;&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;&amp;lt;body&amp;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;&amp;lt;h1&amp;gt;Astro&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Blog&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;部署目录已就绪&amp;lt;/h1&amp;gt;&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;&amp;lt;/body&amp;gt;&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;span&gt;&amp;lt;/html&amp;gt;&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;EOF&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;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;六、配置 Nginx 托管站点&lt;a href=&quot;#六配置-nginx-托管站点&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;在 &lt;code&gt;/etc/nginx/sites-available/&lt;/code&gt; 下创建站点配置文件：&lt;/p&gt;&lt;div&gt;&lt;div&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;span&gt;显示更多&lt;/span&gt;&lt;span&gt;显示更少&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;cat&lt;/span&gt;&lt;span&gt; &amp;gt; &lt;/span&gt;&lt;span&gt;/etc/nginx/sites-available/astro-blog&lt;/span&gt;&lt;span&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;EOF&apos;&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;server {&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;listen 80;&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;&lt;/span&gt;&lt;span&gt;listen [::]:80;&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;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;server_name yourdomain.com www.yourdomain.com;&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 /var/www/astro-blog;&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 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;&lt;/span&gt;&lt;span&gt;location / {&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;&lt;/span&gt;&lt;span&gt;try_files $uri $uri/ /index.html;&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;}&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;/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;EOF&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;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;ln&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-s&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/etc/nginx/sites-available/astro-blog&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/etc/nginx/sites-enabled/astro-blog&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;rm&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;/etc/nginx/sites-enabled/default&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;nginx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-t&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;systemctl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;reload&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nginx&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;code&gt;nginx -t&lt;/code&gt; 输出 &lt;code&gt;syntax is ok&lt;/code&gt; 和 &lt;code&gt;test is successful&lt;/code&gt;，说明配置语法没有问题。&lt;/p&gt;&lt;p&gt;此时访问：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;http://yourdomain.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;http://www.yourdomain.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果能看到测试页，说明：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;域名解析正常&lt;/li&gt;
&lt;li&gt;80 端口正常&lt;/li&gt;
&lt;li&gt;Nginx 配置正常&lt;/li&gt;
&lt;li&gt;站点目录可访问&lt;/li&gt;
&lt;/ul&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;七、创建或准备 Astro 项目&lt;a href=&quot;#七创建或准备-astro-项目&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;如果你还没有 Astro 项目，可以在本地创建：&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;npm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;create&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;astro@latest&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;如果你使用的是现成主题，比如 AstroPaper，也可以直接基于主题模板初始化。&lt;/p&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;npm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&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;npm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dev&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;/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;npm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;build&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;code&gt;dist/&lt;/code&gt; 目录。&lt;/p&gt;&lt;p&gt;如果你的项目使用的是 pnpm，而不是 npm，那么命令应该改成：&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;pnpm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&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;pnpm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;build&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;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;八、Astro 项目的关键配置&lt;a href=&quot;#八astro-项目的关键配置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;部署到正式域名后，建议确认 &lt;code&gt;astro.config.mjs&lt;/code&gt; 或主题配置文件里已经写入正确的生产环境地址。&lt;/p&gt;&lt;p&gt;例如：&lt;/p&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;import&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;defineConfig&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;astro/config&apos;&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;/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;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;defineConfig&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;site&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;https://yourdomain.com&apos;&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;/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;如果你使用 AstroPaper 之类的主题，还要修改主题自己的站点配置，例如：&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;li&gt;时区&lt;/li&gt;
&lt;li&gt;文章编辑地址&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;以 AstroPaper 为例，重点文件通常是：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;src/config.ts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;src/constants.ts&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;尤其要注意把正式域名填进去，否则 canonical URL、社交分享链接、SEO 信息可能都会不正确。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;九、第一次手动部署 Astro 构建产物&lt;a href=&quot;#九第一次手动部署-astro-构建产物&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;在启用自动化部署前，建议先手动部署一次，确保服务器侧配置没问题。&lt;/p&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;npm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;build&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;/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;pnpm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;build&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;code&gt;rsync&lt;/code&gt; 或 &lt;code&gt;scp&lt;/code&gt; 把 &lt;code&gt;dist/&lt;/code&gt; 上传到 ECS。&lt;/p&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;rsync&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-avz&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dist/&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;root@你的ECS公网IP:/var/www/astro-blog/&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;上传完成后，再次访问域名。
如果已经能看到 Astro 首页，而不是之前的测试页，说明静态文件部署路径是正确的。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;十、手动部署 SSL 证书&lt;a href=&quot;#十手动部署-ssl-证书&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;本文使用的是&lt;strong&gt;手动申请的 SSL 证书&lt;/strong&gt;，所以不使用 Certbot，而是手动把证书部署到 Nginx。&lt;/p&gt;&lt;p&gt;通常证书包里会有：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;证书文件，例如 &lt;code&gt;fullchain.pem&lt;/code&gt; 或 &lt;code&gt;yourdomain.pem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;私钥文件，例如 &lt;code&gt;yourdomain.key&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;先在 ECS 上创建证书目录：&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;mkdir&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/etc/nginx/ssl&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;chmod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;700&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/etc/nginx/ssl&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;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc/nginx/ssl/fullchain.pem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/etc/nginx/ssl/yourdomain.key&lt;/code&gt;&lt;/li&gt;
&lt;/ul&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;chmod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;600&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/etc/nginx/ssl/yourdomain.key&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;chmod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;644&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/etc/nginx/ssl/fullchain.pem&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;接着修改 Nginx 配置，让 80 跳转到 443，并配置 HTTPS。&lt;/p&gt;&lt;div&gt;&lt;div&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;span&gt;显示更多&lt;/span&gt;&lt;span&gt;显示更少&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;cat&lt;/span&gt;&lt;span&gt; &amp;gt; &lt;/span&gt;&lt;span&gt;/etc/nginx/sites-available/astro-blog&lt;/span&gt;&lt;span&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt;&apos;EOF&apos;&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;server {&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;listen 80;&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;&lt;/span&gt;&lt;span&gt;listen [::]:80;&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;server_name yourdomain.com www.yourdomain.com;&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;/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;return 301 https://$host$request_uri;&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;/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;/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;server {&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;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;listen 443 ssl;&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;&lt;/span&gt;&lt;span&gt;listen [::]:443 ssl;&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;server_name yourdomain.com www.yourdomain.com;&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;/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;&lt;/span&gt;&lt;span&gt;root /var/www/astro-blog;&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;index index.html;&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;&lt;/span&gt;&lt;span&gt;ssl_certificate /etc/nginx/ssl/fullchain.pem;&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;ssl_certificate_key /etc/nginx/ssl/yourdomain.key;&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;/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;location / {&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;&lt;/span&gt;&lt;span&gt;try_files $uri $uri/ /index.html;&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;&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;/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;EOF&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;p&gt;然后测试并重载 Nginx：&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;nginx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-t&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;systemctl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;reload&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nginx&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;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;https://yourdomain.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;https://www.yourdomain.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果能正常打开，说明 HTTPS 部署完成。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;十一、为 GitHub Actions 准备部署账号&lt;a href=&quot;#十一为-github-actions-准备部署账号&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;为了安全起见，不建议让 GitHub Actions 直接使用 root 用户登录 ECS。更合理的做法是创建一个专门的部署用户，比如 &lt;code&gt;deploy&lt;/code&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;adduser&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;deploy&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;usermod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-aG&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;www-data&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;deploy&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;mkdir&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/home/deploy/.ssh&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;chmod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;700&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/home/deploy/.ssh&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;chown&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-R&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;deploy:deploy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/home/deploy/.ssh&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;然后需要给这个用户配置 SSH 公钥登录。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;十二、生成 GitHub Actions 专用 SSH 密钥&lt;a href=&quot;#十二生成-github-actions-专用-ssh-密钥&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;在本地 Windows 电脑上，可以使用如下命令生成一对密钥。&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;mkdir&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%USERPROFILE%&lt;/span&gt;&lt;span&gt;\.ssh&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;ssh-keygen&lt;/span&gt;&lt;span&gt; -t ed25519 -C &lt;/span&gt;&lt;span&gt;&quot;github-actions-deploy&quot;&lt;/span&gt;&lt;span&gt; -f &lt;/span&gt;&lt;span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;/span&gt;&lt;span&gt;USERPROFILE&lt;/span&gt;&lt;span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;\.ssh\github_actions_astro&quot;&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;p&gt;会生成两个文件：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;私钥：&lt;code&gt;C:\Users\你的用户名\.ssh\github_actions_astro&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;公钥：&lt;code&gt;C:\Users\你的用户名\.ssh\github_actions_astro.pub&lt;/code&gt;&lt;/li&gt;
&lt;/ul&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;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%USERPROFILE%&lt;/span&gt;&lt;span&gt;\.ssh\github_actions_astro.pub&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;/p&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;ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... github-actions-deploy&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;/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;/home/deploy/.ssh/authorized_keys&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;code&gt;nano&lt;/code&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;nano&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/home/deploy/.ssh/authorized_keys&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;/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;chmod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;600&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/home/deploy/.ssh/authorized_keys&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;chown&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;deploy:deploy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/home/deploy/.ssh/authorized_keys&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;code&gt;authorized_keys&lt;/code&gt; 中写入的是：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;github_actions_astro.pub&lt;/code&gt; 的内容&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;不是私钥文件内容。&lt;/p&gt;&lt;p&gt;另外，公钥开头必须是：&lt;/p&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;ssh-ed25519&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;code&gt;sh-ed25519&lt;/code&gt; 之类的错误格式，SSH 会直接认证失败。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;十三、先在本地测试 SSH 是否打通&lt;a href=&quot;#十三先在本地测试-ssh-是否打通&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;在正式跑 GitHub Actions 之前，建议本地先测试一次 SSH 登录。&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&lt;/span&gt;&lt;span&gt; -i &lt;/span&gt;&lt;span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;/span&gt;&lt;span&gt;USERPROFILE&lt;/span&gt;&lt;span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;\.ssh\github_actions_astro&quot;&lt;/span&gt;&lt;/span&gt;&lt;span&gt; deploy@你的ECS公网IP&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;/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;/ul&gt;&lt;p&gt;只有这一步先打通，GitHub Actions 的远程上传才有成功的基础。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;十四、配置 GitHub 仓库 Secrets&lt;a href=&quot;#十四配置-github-仓库-secrets&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;进入 GitHub 仓库：&lt;/p&gt;&lt;p&gt;&lt;code&gt;Settings -&amp;gt; Secrets and variables -&amp;gt; Actions&lt;/code&gt;&lt;/p&gt;&lt;p&gt;添加以下几个 Secrets：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ECS_HOST&lt;/code&gt;：你的 ECS 公网 IP&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ECS_PORT&lt;/code&gt;：&lt;code&gt;22&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ECS_USER&lt;/code&gt;：&lt;code&gt;deploy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ECS_SSH_KEY&lt;/code&gt;：私钥文件 &lt;code&gt;github_actions_astro&lt;/code&gt; 的完整内容&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;注意，&lt;code&gt;ECS_SSH_KEY&lt;/code&gt; 填的是&lt;strong&gt;私钥全文&lt;/strong&gt;，内容会包含：&lt;/p&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;-----BEGIN OPENSSH PRIVATE KEY-----&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;/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;-----END OPENSSH PRIVATE KEY-----&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;code&gt;.pub&lt;/code&gt; 文件内容填进这个 Secret。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;十五、编写 GitHub Actions 自动部署 workflow&lt;a href=&quot;#十五编写-github-actions-自动部署-workflow&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;如果你的 Astro 项目使用的是 &lt;strong&gt;pnpm&lt;/strong&gt;，推荐使用下面这份 workflow。&lt;/p&gt;&lt;p&gt;创建文件：&lt;/p&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;.github/workflows/deploy.yml&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;/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 Astro to ECS&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;/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;/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;- &lt;/span&gt;&lt;span&gt;main&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;env&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;FORCE_JAVASCRIPT_ACTIONS_TO_NODE24&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&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;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;12&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;13&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;/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;/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;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;17&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@v5&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;/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;- &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;20&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;21&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;22&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;23&lt;/div&gt;&lt;/div&gt;&lt;div&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;- &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;Setup Node&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;uses&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;actions/setup-node@v5&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;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;27&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;22&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;cache&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;29&lt;/div&gt;&lt;/div&gt;&lt;div&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;- &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;31&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 --frozen-lockfile&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;span&gt;- &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;Build Astro&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;run&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;35&lt;/div&gt;&lt;/div&gt;&lt;div&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;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;Upload dist to ECS&lt;/span&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;uses&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;appleboy/scp-action@v1&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;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;39&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;host&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${{ secrets.ECS_HOST }}&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;span&gt;          &lt;/span&gt;&lt;span&gt;username&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${{ secrets.ECS_USER }}&lt;/span&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;key&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${{ secrets.ECS_SSH_KEY }}&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;port&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${{ secrets.ECS_PORT }}&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;source&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;dist/*&quot;&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;target&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;/var/www/astro-blog&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;strip_components&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&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;overwrite&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&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;/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;&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;Fix permissions&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;uses&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;appleboy/ssh-action@v1&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;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;51&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;host&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${{ secrets.ECS_HOST }}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;52&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;username&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${{ secrets.ECS_USER }}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;53&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${{ secrets.ECS_SSH_KEY }}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;54&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;port&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;${{ secrets.ECS_PORT }}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;55&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;script&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;56&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;chown -R deploy:www-data /var/www/astro-blog&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;57&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;find /var/www/astro-blog -type d -exec chmod 775 {} \;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;58&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;find /var/www/astro-blog -type f -exec chmod 664 {} \;&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;p&gt;如果你项目使用的是 npm，就把 pnpm 相关命令替换成 npm 即可。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;十六、pnpm 项目常见问题&lt;a href=&quot;#十六pnpm-项目常见问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;如果你使用的是 pnpm 项目，仓库根目录里必须提交：&lt;/p&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;pnpm-lock.yaml&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 Actions 安装依赖时会失败。&lt;/p&gt;&lt;p&gt;另外，如果 &lt;code&gt;package.json&lt;/code&gt; 中写了：&lt;/p&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;&quot;packageManager&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;pnpm@9.14.4&quot;&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;code&gt;pnpm/action-setup&lt;/code&gt; 里也要保持同样版本，不能写成 10，否则会报版本冲突错误。&lt;/p&gt;&lt;p&gt;换句话说，workflow 里的 pnpm 版本必须和项目自己声明的版本一致。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;十七、触发自动部署&lt;a href=&quot;#十七触发自动部署&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;把 workflow 提交到仓库后，执行：&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;add deploy workflow&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 仓库的 Actions 页面，就能看到自动部署任务开始执行。&lt;/p&gt;&lt;p&gt;成功后，流程会是：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;拉取仓库代码&lt;/li&gt;
&lt;li&gt;安装 Node 和 pnpm&lt;/li&gt;
&lt;li&gt;安装依赖&lt;/li&gt;
&lt;li&gt;构建 Astro&lt;/li&gt;
&lt;li&gt;把 &lt;code&gt;dist/&lt;/code&gt; 上传到 ECS&lt;/li&gt;
&lt;li&gt;修复目录权限&lt;/li&gt;
&lt;li&gt;网站自动更新&lt;/li&gt;
&lt;/ul&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;publish new post&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;新的内容就会自动部署上线。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;十八、常见问题排查&lt;a href=&quot;#十八常见问题排查&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;整个部署过程中，最容易踩到的坑主要有以下几类。&lt;/p&gt;&lt;section&gt;&lt;h2&gt;1. GitHub Actions 无法通过 SSH 认证&lt;a href=&quot;#1-github-actions-无法通过-ssh-认证&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;/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: unable to authenticate, attempted methods [none publickey]&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;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ECS_SSH_KEY&lt;/code&gt; 不是正确私钥&lt;/li&gt;
&lt;li&gt;服务器上的 &lt;code&gt;authorized_keys&lt;/code&gt; 没写对&lt;/li&gt;
&lt;li&gt;公钥格式写错&lt;/li&gt;
&lt;li&gt;用户名不匹配&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.ssh&lt;/code&gt; 或 &lt;code&gt;authorized_keys&lt;/code&gt; 权限不正确&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;正确的排查顺序应该是：&lt;/p&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;ssh&lt;/span&gt;&lt;span&gt; -i &lt;/span&gt;&lt;span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;/span&gt;&lt;span&gt;USERPROFILE&lt;/span&gt;&lt;span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;\.ssh\github_actions_astro&quot;&lt;/span&gt;&lt;/span&gt;&lt;span&gt; deploy@你的ECS公网IP&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 Actions 才有机会成功。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;2. &lt;code&gt;authorized_keys&lt;/code&gt; 公钥格式错误&lt;a href=&quot;#2-authorized_keys-公钥格式错误&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;/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-ed25519 AAAA...&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;/p&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;sh-ed25519 AAAA...&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;那么 SSH 会直接把这行视为无效公钥，导致始终认证失败。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;3. pnpm 版本冲突&lt;a href=&quot;#3-pnpm-版本冲突&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;如果 workflow 里写的是：&lt;/p&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;version&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;10&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;code&gt;package.json&lt;/code&gt; 里写的是：&lt;/p&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;&quot;packageManager&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;pnpm@9.14.4&quot;&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;/p&gt;&lt;p&gt;解决方法很简单：保持两边完全一致。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;4. 找不到 lock file&lt;a href=&quot;#4-找不到-lock-file&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;如果项目是 pnpm 项目，却使用了 npm 的 workflow，可能会报找不到 &lt;code&gt;package-lock.json&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;解决思路是：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;cache: pnpm&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;pnpm install --frozen-lockfile&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;确保仓库里有 &lt;code&gt;pnpm-lock.yaml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;5. HTTPS 配好了但站点打不开&lt;a href=&quot;#5-https-配好了但站点打不开&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;这种情况优先检查：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;阿里云安全组是否放行 443&lt;/li&gt;
&lt;li&gt;UFW 是否放行 443&lt;/li&gt;
&lt;li&gt;证书路径是否写对&lt;/li&gt;
&lt;li&gt;证书和私钥是否配对&lt;/li&gt;
&lt;li&gt;Nginx 是否重载成功&lt;/li&gt;
&lt;/ul&gt;&lt;hr /&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;十九、最终效果&lt;a href=&quot;#十九最终效果&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;完成上述所有步骤后，你会得到一个完整可用的个人博客部署方案：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;域名已经绑定到阿里云 ECS&lt;/li&gt;
&lt;li&gt;Nginx 正常提供静态站点&lt;/li&gt;
&lt;li&gt;网站通过 HTTPS 对外访问&lt;/li&gt;
&lt;li&gt;每次提交代码后，GitHub Actions 自动构建并部署&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这个方案对个人博客来说已经足够稳定，而且维护起来非常轻松。&lt;/p&gt;&lt;hr /&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;二十、结语&lt;a href=&quot;#二十结语&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;这次部署最大的感受是：
对于 Astro 这类静态站点，最省心的方式并不是在服务器上运行开发环境，而是把服务器当作一个稳定的静态资源托管端。&lt;/p&gt;&lt;p&gt;本地负责开发。
GitHub Actions 负责构建。
ECS 负责托管。
Nginx 负责访问和 HTTPS。&lt;/p&gt;&lt;p&gt;职责清晰，问题也更容易定位。&lt;/p&gt;&lt;p&gt;如果你也正好在用阿里云 ECS、Ubuntu 24.04、Astro 或 AstroPaper，希望这篇记录能帮你少踩一些坑。&lt;/p&gt;&lt;/section&gt;</content:encoded></item></channel></rss>