<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>darknight</title><description>你好，世界</description><link>https://darknight.website/</link><templateTheme>Aemeath</templateTheme><templateThemeVersion>4.3.0</templateThemeVersion><templateThemeUrl>https://github.com/Jarvis0227/Aemeath</templateThemeUrl><lastBuildDate>Sun, 01 Nov 2026 16:20:15 GMT</lastBuildDate><item><title>你好，世界</title><link>https://darknight.website/posts/hello-world/</link><guid isPermaLink="true">https://darknight.website/posts/hello-world/</guid><description>这个博客开通的第一篇文章，说明我为什么要写点什么。</description><pubDate>Sun, 01 Nov 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;站点的签名我填的是「你好，世界」。&lt;/p&gt;
&lt;p&gt;没什么特别的理由。程序员的第一个程序是 &lt;code&gt;Hello, World&lt;/code&gt;，那第一篇博客也应该叫这个。&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;大二之后开始有一件事变得很清楚：看过的东西不等于学会的东西。&lt;/p&gt;&lt;p&gt;课堂上听懂了，作业做完了，过两周还是一问三不知。但当我试着把某件事讲给别人——哪怕只是写下来写给两周后的自己——才会发现中间有多少环节其实是空的。写文章就是把空的地方照出来的过程。&lt;/p&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;strong&gt;技术笔记&lt;/strong&gt;：代码、工具、踩过的坑。我现在的方向是 AI / 机器学习，会写一些正在学的东西。这类文章的标准是「两周后的我能看懂」，所以会尽量把前提说清楚，而不是堆术语。&lt;/p&gt;&lt;p&gt;一类是&lt;strong&gt;数学&lt;/strong&gt;。专业课里的东西，或者自己看到的有意思的结论。数学这块我更在意解释，不追求严谨到可以发论文——那是课本该做的事，我要做的是让某个概念在脑子里有个具体的形状。&lt;/p&gt;&lt;p&gt;一类是&lt;strong&gt;没什么用但很想说的想法&lt;/strong&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;a href=&quot;https://rainzt.cn/&quot; target=&quot;_blank&quot;&gt;rainzt.cn&lt;/a&gt; 所用的开源主题 &lt;a href=&quot;https://github.com/Jarvis0227/Aemeath&quot; target=&quot;_blank&quot;&gt;Aemeath&lt;/a&gt;，代码是 MIT 协议，文字和图片是我自己的。&lt;/p&gt;&lt;p&gt;它跑在一台阿里云的服务器上，首页的壁纸和头像是生成的原创图。以后可能会换。&lt;/p&gt;&lt;p&gt;慢慢来。&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>这个博客是怎么跑起来的</title><link>https://darknight.website/posts/how-this-blog-works/</link><guid isPermaLink="true">https://darknight.website/posts/how-this-blog-works/</guid><description>记录站点的部署链路——一份构建产物同时喂给 Cloudflare Pages 和自建 nginx，以及两边各自的坑。</description><pubDate>Sun, 01 Nov 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;搭完顺手记一下链路。以后忘了可以自己回来看。&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;静态博客。用户访问的永远是构建产物（一堆 HTML / CSS / JS），不需要跑 Node 服务。&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;本地改内容&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├─ npm run deploy:cf ──▶ 本地构建 dist ──▶ wrangler 上传 ──▶ Cloudflare Pages ──▶ darknight.website&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;└─ git push server main ──▶ 服务器 post-receive 自己构建 ──▶ nginx ──▶ 101.37.208.65&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 在朋友的账号里，个人账号之间没法授权备案服务码），而境外节点压根不产生备案义务。于是域名交给 Cloudflare，服务器留一个 IP 直连当备用出口，顺便练手 nginx。&lt;/p&gt;&lt;p&gt;下面先写 Cloudflare 这条，再写服务器那条。&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Cloudflare Pages 这条链路&lt;a href=&quot;#cloudflare-pages-这条链路&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;npm run deploy:cf&lt;/code&gt; 一条命令做完所有事：生成图标和 LQIP、算友链头像底色、&lt;code&gt;astro build&lt;/code&gt;、字体子集化、Pagefind 建索引，最后 &lt;code&gt;wrangler pages deploy dist&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;没有走「连 GitHub 自动构建」那条路，两个原因：这个仓库只有本地和服务器两个 remote，没往 GitHub 推；而且 Pages 的构建容器只有 4 GB 内存和 512 并发限制，不如在自己机器上构建快——笔记本跑完整构建一分多钟，上传 359 个文件半分钟。&lt;/p&gt;&lt;p&gt;第一次部署有个坑：wrangler 把文件全传完了（&lt;code&gt;Success! Uploaded 359 files&lt;/code&gt;），最后注册 deployment 那一步网络抖了一下报 &lt;code&gt;fetch failed&lt;/code&gt;。这时候项目是空的，访问返回 &lt;strong&gt;522&lt;/strong&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;ol&gt;
&lt;li&gt;Cloudflare 面板 &lt;strong&gt;Add a site&lt;/strong&gt;，填 &lt;code&gt;darknight.website&lt;/code&gt;，Free 计划，拿到两个 &lt;code&gt;*.ns.cloudflare.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Pages 项目 → &lt;strong&gt;Custom domains&lt;/strong&gt; 里把域名关联上（CF 自动建记录、自动签证书）&lt;/li&gt;
&lt;li&gt;阿里云域名控制台 → &lt;strong&gt;修改 DNS 服务器&lt;/strong&gt;，换成第 1 步那两个 NS&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;第 2 步必须在第 3 步前面。NS 一切到 Cloudflare，流量就进边缘了，这时 Pages 还没跟域名建立关联，回源找不到目标直接 522。&lt;/p&gt;&lt;p&gt;另外改 NS 要求域名实名认证已经通过，实名没过阿里云会拒绝修改。&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;code&gt;/srv/blog&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;/srv/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;├── git/blog.git/       # bare 仓库，push 到这里&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;│   └── hooks/post-receive   # 部署脚本&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;├── app/                # 源码工作区（构建时占用）&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;│   └── node_modules/&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;├── releases/           # 每次构建的产物，按时间戳存&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;│   └── 20261101-121100/&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;├── current ─────▶ releases/20261101-121100&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;└── deploy.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;code&gt;current&lt;/code&gt; 是个软链接，nginx 只认它。切换版本就是把软链接指向新的 release，所以发布是瞬时的，不会出现「构建到一半用户看到半截页面」。&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;code&gt;post-receive&lt;/code&gt; 里几个值得说的细节。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;只认 main 分支&lt;/strong&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;while&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;read&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;_old&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ref&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;do&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;[ &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;$ref&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;refs/heads/main&quot;&lt;/span&gt;&lt;span&gt; ] || &lt;/span&gt;&lt;span&gt;continue&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;/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;done&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;code&gt;nice -n 19&lt;/code&gt; 跑构建&lt;/strong&gt;。这台机器内存只有 1.7 GB，Astro 构建会吃满 CPU。不加 nice 的话构建期间服务器基本没法用。同时给 Node 设了上限：&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;nice&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;19&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;NODE_OPTIONS=--max-old-space-size=&lt;/span&gt;&lt;span&gt;1200&lt;/span&gt;&lt;span&gt; &lt;/span&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;strong&gt;先检查再重载 nginx&lt;/strong&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;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nginx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-t&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt;/dev/null&lt;/span&gt;&lt;span&gt; 2&amp;gt;&amp;amp;1; &lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;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;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;else&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;log&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;WARN nginx -t failed, NOT reloading&quot;&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;fi&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;只保留最近 3 个 release&lt;/strong&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;ls&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-1dt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;$REL_ROOT&lt;/span&gt;&lt;span&gt;&quot;/&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span&gt;tail&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+4&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span&gt;xargs&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;rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-rf&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;releases/&lt;/code&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;code&gt;/_astro/&lt;/code&gt; 下的文件名带 content hash，内容变了名字就变，所以可以放心设很长的缓存：&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;location&lt;/span&gt;&lt;span&gt; /_astro/ {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt; &lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;add_header &lt;/span&gt;&lt;span&gt;Cache-Control &lt;/span&gt;&lt;span&gt;&quot;public, max-age=31536000, immutable&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&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;图片没 hash，设一周。&lt;code&gt;/pagefind/&lt;/code&gt; 是全文搜索的索引，每次构建整体替换，设 300 秒——太长会导致刚发的文章搜不到。&lt;/p&gt;&lt;p&gt;Cloudflare 那边用 &lt;code&gt;public/_headers&lt;/code&gt; 声明同样的规则，构建时会被拷进 &lt;code&gt;dist&lt;/code&gt;。这里有个和 nginx 完全不同的行为：&lt;strong&gt;所有匹配上的规则都会生效并且叠加，不是后面的覆盖前面的&lt;/strong&gt;。所以 &lt;code&gt;/*&lt;/code&gt; 和 &lt;code&gt;/_astro/*&lt;/code&gt; 同时写了 &lt;code&gt;Cache-Control&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;Cache-Control: public, max-age=31536000, immutable, public, max-age=0, must-revalidate&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;Cache-Control&lt;/code&gt; 只在具体路径上写。HTML 不写也没关系，Pages 默认就给 &lt;code&gt;max-age=0, must-revalidate&lt;/code&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;用的 Pagefind。它扫构建好的 HTML 建静态索引，不需要后端、不需要 API key，查询全在浏览器里完成。代价是索引体积会随文章数增长，现在这个量级完全无所谓。&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;strong&gt;备案这件事最后没走通。&lt;/strong&gt; 卡在第 5 步选云产品实例——那台 ECS 在朋友的阿里云账号里，而跨账号授权备案服务码要求&lt;strong&gt;对方是企业实名认证&lt;/strong&gt;，个人账号只能给自己账号下的服务器生成。买付费服务码也不行，它必须绑定在同一个账号里符合条件的实例上。所以只剩两条路：在朋友账号里以我的身份提交（会永久占掉那个账号唯一的主体名额），或者自己买台便宜的内地机。目前选了第三条：域名不碰内地节点，直接挂 Cloudflare，境外节点不产生备案义务。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Cockpit 占了 443。&lt;/strong&gt; 服务器的 Web 管理面板反代在 &lt;code&gt;https://&amp;lt;IP&amp;gt;/start&lt;/code&gt;，博客不跟它抢，用 80。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;本地构建其实能跑。&lt;/strong&gt; 原先以为主题的字体在构建时要从 jsdelivr 拉、笔记本连不上，所以一直只在服务器上构建。实际试下来 &lt;code&gt;astro build&lt;/code&gt; 在本地一次过，字体子集化和 Pagefind 也都正常，那条判断是错的。&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;评论（Waline）和访问统计（Umami）都没上，先把纯静态链路跑通。HTTPS 在 Cloudflare 侧是自动签发的，不用管；内地那台如果以后要上证书再走 certbot。&lt;/p&gt;&lt;p&gt;国内访问速度目前没测。真觉得慢再考虑套一层 Cloudflare 优选 IP，或者上腾讯云 EdgeOne Pages 回源——但那是等有人抱怨慢以后再说的事。&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>怎么写文章并发布</title><link>https://darknight.website/posts/how-to-write-and-publish/</link><guid isPermaLink="true">https://darknight.website/posts/how-to-write-and-publish/</guid><description>给自己用的操作手册——新增一篇文章、改配置、上线的完整步骤。</description><pubDate>Sun, 01 Nov 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;以后忘了就查这篇。核心只有一句：&lt;strong&gt;在本地改文件，然后 &lt;code&gt;npm run deploy:cf&lt;/code&gt; 上线。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;域名走 Cloudflare Pages，服务器那份是 IP 直连的备用出口。平时只管 Cloudflare 这条，两边都要更新就再补一次 &lt;code&gt;git push&lt;/code&gt;。&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;博客源码在本地 &lt;code&gt;D:\服务器测试\blog&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;cd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/d/服务器测试/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;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;remote&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-v&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;# server  ssh://darknight@101.37.208.65/srv/blog/git/blog.git (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;/section&gt;
&lt;section&gt;&lt;h2&gt;写一篇新文章&lt;a href=&quot;#写一篇新文章&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;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;cd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/d/服务器测试/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;corepack&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pnpm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new-post&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;my-first-note&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;src/content/posts/&lt;/code&gt; 下生成一个带 frontmatter 模板的 &lt;code&gt;my-first-note.md&lt;/code&gt;。文件名就是文章网址：&lt;code&gt;posts/my-first-note&lt;/code&gt;。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;用英文小写加连字符做文件名，别用中文和空格——URL 里中文会被转义成一长串 &lt;code&gt;%XX&lt;/code&gt;，不好分享。&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;frontmatter 怎么写&lt;a href=&quot;#frontmatter-怎么写&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;---&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;title&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;published&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;2026-11-02&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;description&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;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;aiPolished&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;# 不是 AI 润色过的就填 false，否则文章顶部会有提示&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;image&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;/assets/images/wallpaper/darknight-rain.webp&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;# 封面图，留空则不显示&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;tags&lt;/span&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;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;category&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;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;draft&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&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;span&gt;pinned&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&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;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;lang&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;zh-CN&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;/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;title&lt;/code&gt; 和 &lt;code&gt;published&lt;/code&gt; 必填，其它都有默认值。&lt;/p&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;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;cd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/d/服务器测试/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;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;src/content/posts/&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;posts: 新增《文章标题》&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;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;deploy:cf&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;最后这条会先把整条构建链跑一遍（图标 → LQIP → 友链底色 → astro build → 字体子集 → Pagefind），再把 &lt;code&gt;dist&lt;/code&gt; 传给 Cloudflare。本地跑完整构建一分多钟，上传半分钟，比服务器快得多。看到&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;✨ Deployment complete! Take a peek over at https://xxxxxxxx.darknight-alp.pages.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;code&gt;https://darknight-alp.pages.dev&lt;/code&gt;，前面那串哈希是这次部署的快照，用来验证改动不影响别人。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;如果上传显示成功但站点打不开、返回 522，说明最后注册 deployment 的请求丢了。重跑一次 &lt;code&gt;npm run deploy:cf&lt;/code&gt;，文件按哈希去重，秒完。&lt;/p&gt;&lt;/blockquote&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;想让 IP 直连那份也同步，再推一次：&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;push&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;server&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&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;push 完输出里会出现 &lt;code&gt;remote:&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;remote: [2026-11-01 12:34:56] ===== deploy 20261101-123456 start =====&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;remote: [2026-11-01 12:35:02] pnpm install&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;remote: [2026-11-01 12:36:40] pnpm build&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;remote: [2026-11-01 12:39:11] live -&amp;gt; /srv/blog/releases/20261101-123456&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;remote: [2026-11-01 12:39:12] nginx reloaded&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;remote: [2026-11-01 12:39:12] ===== deploy 20261101-123456 OK =====&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;，服务器只有 1.7G 内存，构建慢。看到 &lt;code&gt;OK&lt;/code&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;Cloudflare 这条如果失败，报错会直接打在终端里，构建阶段的错和上传阶段的错一眼能分开。构建没过就按报错改，改完重跑；上传阶段网络断了也直接重跑，&lt;code&gt;dist&lt;/code&gt; 没变的话是秒传。&lt;/p&gt;&lt;p&gt;服务器那条先看 push 输出里有没有 &lt;code&gt;FAIL&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;ssh&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;darknight@101.37.208.65&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;tail -50 /srv/blog/deploy.log&apos;&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;strong&gt;构建报错，站点没更新。&lt;/strong&gt; 放心，这时线上还是上一个正常版本——软链接只在构建成功后才切换。按日志里的报错改 Markdown 或配置，重新 push。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;frontmatter 校验没过。&lt;/strong&gt; 一般是日期格式写错了（必须是 &lt;code&gt;YYYY-MM-DD&lt;/code&gt;）或者 &lt;code&gt;tags&lt;/code&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;code&gt;src/config/&lt;/code&gt; 下，一个文件管一块：&lt;/p&gt;




































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;文件&lt;/th&gt;&lt;th&gt;管什么&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;siteConfig.ts&lt;/code&gt;&lt;/td&gt;&lt;td&gt;站名、签名、URL、功能开关&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;profileConfig.ts&lt;/code&gt;&lt;/td&gt;&lt;td&gt;头像、昵称、简介、社交链接&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;backgroundWallpaper.ts&lt;/code&gt;&lt;/td&gt;&lt;td&gt;首页壁纸、标题文字、打字机&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;navBarConfig.ts&lt;/code&gt;&lt;/td&gt;&lt;td&gt;顶部菜单&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;sidebarConfig.ts&lt;/code&gt;&lt;/td&gt;&lt;td&gt;侧边栏小组件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;themeColor.ts&lt;/code&gt;&lt;/td&gt;&lt;td&gt;主题色&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;licenseConfig.ts&lt;/code&gt;&lt;/td&gt;&lt;td&gt;文章版权声明&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;改完同样 &lt;code&gt;npm run deploy:cf&lt;/code&gt; 上线。&lt;/p&gt;&lt;p&gt;&lt;code&gt;siteConfig.ts&lt;/code&gt; 里的 &lt;code&gt;pages&lt;/code&gt; 是功能开关，比如想开相册就把 &lt;code&gt;gallery&lt;/code&gt; 改成 &lt;code&gt;true&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;&lt;span&gt;pages&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;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;friends&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&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;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;guestbook&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&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;&lt;/span&gt;&lt;span&gt;gallery&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&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;&lt;/span&gt;&lt;span&gt;bangumi&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&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;/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;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;public/assets/images/&lt;/code&gt; 或者它的子目录，然后用绝对路径引用，比如 &lt;code&gt;/assets/images/wallpaper/xxx.webp&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;用 webp，别用 png。&lt;/strong&gt; 同样的观感，体积能小一大半，首页加载全靠它。&lt;/p&gt;&lt;p&gt;转格式可以用 &lt;code&gt;sharp-cli&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;corepack&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pnpm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dlx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sharp-cli&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-i&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;in.png&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;out.webp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-q&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;82&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;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;cd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/d/服务器测试/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;corepack&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pnpm&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;code&gt;pnpm&lt;/code&gt; 没单独装，用 &lt;code&gt;corepack&lt;/code&gt; 前缀调，它会按 &lt;code&gt;package.json&lt;/code&gt; 里的 &lt;code&gt;packageManager&lt;/code&gt; 字段拉 9.14.4。&lt;/p&gt;&lt;p&gt;之前一直以为本地构建跑不起来——主题字体要在构建时从 jsdelivr 拉，怀疑笔记本连不上它，所以只在服务器上构建。实测是错的，本地 &lt;code&gt;astro build&lt;/code&gt;、字体子集化、Pagefind 全都能一次过，所以现在的部署才改成本地构建再上传。&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;code&gt;/srv/blog/app&lt;/code&gt; 是部署时 checkout 出来的，下次 push 会被 &lt;code&gt;checkout -f&lt;/code&gt; 覆盖掉。要改就改本地、提交、推上去。&lt;/p&gt;&lt;/section&gt;</content:encoded></item></channel></rss>