从零搭建 boyuan.net.cn:Astro + Firefly + 宝塔 Nginx 全流程

这篇文章按真实操作的顺序记录本站从空目录到上线的全过程。如果你也想搭一个静态博客,照着走一遍基本能复现。
技术栈很简单:
- Astro —— 静态站点生成器,负责把 Markdown 编译成 HTML
- Firefly —— 基于 Astro 的博客主题,提供壁纸、搜索、评论、暗色模式等一整套界面
- Nginx —— 服务器上只做一件事:把 dist 目录当静态文件发出去
一、项目准备
环境要求
本地需要 Node.js(Firefly 要求 >= 22)。本站开发环境:
node -v # v26.7.0npm -v # 11.19.0Firefly 官方推荐 pnpm,并且 package.json 里有一行 preinstall: npx only-allow pnpm 强制校验。如果你和我一样用 npm,需要先把这行删掉,否则 npm install 会直接被拒绝。同时删掉 packageManager 字段、pnpm-lock.yaml 和 pnpm-workspace.yaml。
目录结构
Firefly 是标准的 Astro 项目结构,日常真正会碰的只有几个目录:
src/content/posts/ 文章目录(最常用)src/content/spec/ 关于、友链、留言等特殊页面src/config/ 站点配置public/ 静态资源,原样拷贝到 distdist/ 构建产物,部署的就是这个目录package.json 项目脚本二、配置站点信息
站点的大部分基础信息都在 src/config/siteConfig.ts 里:
export const siteConfig: SiteConfig = { title: "石以砥焉化钝为利", subtitle: "以石自砥 · 化钝为利", site_url: "https://boyuan.net.cn", themeColor: { hue: 210, defaultMode: "system" }, siteStartDate: "2026-09-20",};这里几个容易踩的点:
site_url必须写最终域名,RSS、sitemap、OpenGraph 全都依赖它。写错了分享出去的链接就是错的。themeColor.hue是主题色相,0 到 360。本站用 210,偏冷的钢青色。siteStartDate用于页脚统计”已运行多少天”。
导航菜单在 src/config/navBarConfig.ts,个人信息和社交链接在 src/config/profileConfig.ts,首页横幅的文字和壁纸在 src/config/backgroundWallpaper.ts。
页面开关集中在 siteConfig.ts 顶部的 pages 里,关掉的页面会返回 404 并自动从导航栏隐藏:
const pages = resolvePageToggles({ friends: true, // 友链 guestbook: true, // 留言板 dynamic: true, // 动态 projects: true, // 项目 gallery: false, // 相册(放好照片再开) booknav: true, // 书签导航 bilibili: true, // 追番 sponsor: false, // 打赏(没放收款码就别开)});关掉打赏页时,记得把 src/config/sponsorConfig.ts 里的 showButtonInPost 也改成 false。否则文章底部还会渲染一个打赏按钮,点进去是 404。
三、写文章
文章用 Markdown,放在 src/content/posts/。最简单的形式是一个 .md 文件:
---title: 文章标题published: 2026-09-20description: 文章简介,会显示在列表和分享卡片里image: ./cover.aviftags: [博客搭建, Astro]category: 博客指南draft: false---
这里开始写正文。需要配图时,改成一个文章一个目录:
src/content/posts/build-my-blog/├── index.md 正文├── cover.avif 封面└── step-1.png 正文插图正文里直接引用同目录图片:
draft 的作用
draft: true 的文章只在本地开发时显示,生产构建会自动过滤。判断逻辑在 src/utils/content-utils.ts:
return import.meta.env.PROD ? data.draft !== true : true;所以本地看到的文章数可能比线上多,这是正常的。草稿写完,把 draft 改成 false 再构建即可。
四、本地运行
npm install # 安装依赖,首次约 3 分钟npm run dev # 开发服务器,默认 http://localhost:4321/开发服务器有热更新,改配置和文章都会自动刷新。
五、生产构建
npm run build这个命令不是只跑 Astro,它会按顺序做一串事情:
| 步骤 | 作用 |
|---|---|
generate-github-card-data.ts | 抓取 GitHub 卡片数据 |
generate-lqips.ts | 为图片生成低质量占位图 |
generate-vndb-covers.ts | 下载 VNDB 封面(未启用则跳过) |
astro build | 生成静态站点 |
prune-pio-assets.ts | 删掉没用到的看板娘资源 |
subset-fonts.ts | 字体子集化,显著减小字体体积 |
minify-inline-scripts.ts | 压缩内联脚本 |
run-pagefind.ts | 生成 Pagefind 搜索索引 |
构建完成后,产物在 dist/。部署到服务器的就是这个目录里的内容。
先预览再上线
开发环境正常不代表生产构建正常,部署前最好跑一次:
npm run preview预览服务读取的是 dist,更接近线上效果。如果这里正常而线上不正常,问题通常出在部署目录、静态资源缓存或服务器配置上。
siteConfig.ts 里的 generateOgImages 开启后会在构建时为每篇文章渲染分享图,构建时间会明显变长。本地调试建议关掉,需要社交平台分享卡片时再打开。
六、服务器环境
线上是宝塔面板 + Nginx,boyuan.net.cn 和 www.boyuan.net.cn 指向同一个网站根目录。
Nginx 配置里核心就三行:
root /www/wwwroot/boyuan.net.cn;index index.html;
location / { try_files $uri $uri/ $uri.html =404;}try_files 最后那个 $uri.html 很关键。Astro 默认输出 about.html 这样的文件而不是 about/index.html,不加上这条,直接访问 /about/ 就会 404。
HTTPS 证书由宝塔申请和管理,部署静态文件时不要动证书配置。
七、部署流程
思路很简单:
- 本地执行
npm run build - 把
dist打包上传到服务器 - 备份旧的网站目录
- 清空网站根目录里的旧静态文件
- 解压新的
dist到网站根目录 - 检查 Nginx 配置并 reload
为什么必须清空旧文件
Astro 生成的 _astro 资源带内容哈希,比如 index.abc123.css。如果只是覆盖上传而不删除,旧版本的 CSS、JS 会一直残留。
更麻烦的是,浏览器和 Nginx 都会长期缓存这些带哈希的资源。结果是本地一切正常,线上某些交互却还是旧行为——很难查。
所以每次部署前先备份旧版本,再清空目录。这样新版本出问题也能快速回滚。
具体命令和脚本见工作区里的 deploy/DEPLOY.md。
八、线上验证
部署完成后按顺序检查这几项:
https://boyuan.net.cn/ 首页能打开 → Nginx root 和静态文件没问题https://boyuan.net.cn/rss.xml RSS 正常 → 文章元数据构建成功https://boyuan.net.cn/_astro/ 资源能访问 → 资源路径没问题如果样式或下拉菜单还是旧状态,先强制刷新:
Ctrl + F5仍然不对,就去比对线上 HTML 里引用的资源文件名,是不是最新一次构建生成的。
九、日常更新
以后发新文章的固定流程:
- 在
src/content/posts/新建 Markdown 或文章目录 - 设置好
published、tags、category、draft - 本地
npm run dev预览 - 确认无误后
npm run build - 上传新的
dist - 访问线上确认
小结
整条链路可以概括成一句话:
用 Markdown 写内容,用 Astro 生成静态站点,用宝塔 Nginx 托管 dist,用 HTTPS 把它稳定地挂到 boyuan.net.cn。
它不是最复杂的部署方式,但对个人博客来说很舒服:本地写作足够快,线上访问足够轻,出问题也容易定位。 后面无论是加文章、加工具体验、改导航、换壁纸,基本都能围着这套流程继续迭代。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
















