从0到1搭建博客技术原理完全指南

6084 字
30 分钟
从0到1搭建博客技术原理完全指南

从 0 到 1 手动搭建一个安全博客 — 技术原理完全指南#

本文详细解释从零开始手动搭建、配置、安全加固到部署上线一个现代化博客所涉及的所有技术原理。无论你是完全的新手还是有经验的开发者,都能从中理解每一步「为什么这样做」以及底层的工作机制。


目录#

  1. 概述:一个博客系统由哪些部分组成
  2. 技术选型:为什么选择 Astro + 静态站点
  3. 环境准备:Node.js 与包管理器的原理
  4. 项目初始化:从模板开始 vs 从零搭建
  5. 目录结构与架构设计
  6. 配置文件体系:类型安全的前端配置
  7. 内容创作:Markdown 及其扩展语法
  8. 静态站点生成(SSG)的工作原理
  9. 前端技术栈深入
  10. 安全防护体系
  11. 部署与 CDN
  12. DDoS 防护详解
  13. 持续集成与持续部署(CI/CD)
  14. 监控、分析与维护
  15. 总结:完整的技术链路

1. 概述:一个博客系统由哪些部分组成#

一个现代化的博客系统从技术架构上可以分为以下几个层次:

┌─────────────────────────────────────────────┐
│ 用户浏览器 (Client) │
├─────────────────────────────────────────────┤
│ CDN / WAF 层 (Cloudflare) │ ← 安全防护、缓存加速
├─────────────────────────────────────────────┤
│ 静态文件托管 (Pages/CDN) │ ← HTML/CSS/JS 分发
├─────────────────────────────────────────────┤
│ 构建层 (Astro SSG) │ ← 编译时生成静态页面
├─────────────────────────────────────────────┤
│ 内容层 (Markdown/MDX) │ ← 文章撰写与管理
├─────────────────────────────────────────────┤
│ 配置层 (TypeScript Config) │ ← 主题、布局、功能配置
└─────────────────────────────────────────────┘

核心概念:现代静态博客不再需要传统的服务器(如 WordPress + PHP + MySQL),而是采用 Jamstack 架构——在构建时(Build Time)将内容预渲染为静态 HTML 文件,直接部署到 CDN 边缘节点。


2. 技术选型:为什么选择 Astro + 静态站点#

2.1 静态站点 vs 动态站点#

维度动态博客 (WordPress)静态博客 (Astro/Hugo)
服务器需要 PHP + MySQL仅需文件托管
速度每次请求查询数据库预渲染 HTML,秒开
安全性攻击面大(SQL注入、插件漏洞)攻击面极小(无服务端代码)
成本需要 VPS/云服务器免费 CDN 托管
维护需要更新系统、插件只需更新内容
SEO需要额外优化天然 SEO 友好

2.2 Astro 的「Islands 架构」#

Astro 的核心创新是 Islands Architecture(群岛架构)

页面 = 静态内容海(默认)+ 交互岛屿(按需加载 JS)
┌──────────────────────────────────┐
│ ███████ 静态 HTML ████████████ │ ← 服务端渲染,0 JS
│ ██████████████████████████████ │
│ ████ [搜索框] ████████████████ │ ← Svelte Island,按需加载 JS
│ ██████████████████████████████ │
│ ██████ [评论区] ██████████████ │ ← 另一个 Island
│ ██████████████████████████████ │
└──────────────────────────────────┘

原理

  • 默认情况下,Astro 在构建时将所有内容渲染为纯 HTML,不发送任何 JavaScript 到浏览器
  • 只有当组件需要交互时(如搜索框、评论区、主题切换),才会将其标记为”岛屿”
  • 每个岛屿独立加载,互不影响

为什么这很重要:更少的 JavaScript = 更快的加载速度 = 更好的 SEO = 更低的带宽消耗。

2.3 Tailwind CSS — 实用优先的 CSS 框架#

Tailwind 采用「原子化 CSS」理念:

<!-- 传统 CSS:定义类名,写样式 -->
<div class="card">
<h2 class="card-title">标题</h2>
</div>
<!-- Tailwind:直接用工具类组合 -->
<div class="bg-white rounded-lg shadow-md p-6">
<h2 class="text-xl font-bold text-gray-900">标题</h2>
</div>

原理:Tailwind 在构建时扫描你的模板文件,只生成你用到的 CSS 类,最终产出的 CSS 文件通常只有几 KB。


3. 环境准备:Node.js 与包管理器的原理#

3.1 Node.js 是什么#

Node.js 是一个 JavaScript 运行时,基于 Chrome 的 V8 引擎。它让你可以在服务器/本地运行 JavaScript 代码。

你的 .js/.ts 代码
Node.js 运行时 (V8 引擎 + API)
操作系统 (Windows/macOS/Linux)

3.2 包管理器:npm vs pnpm#

  • npm:Node.js 默认包管理器。将依赖下载到 node_modules/,每个项目独立一份。
  • pnpm:更高效的包管理器。使用硬链接(hard link)内容寻址存储来共享相同版本的包,节省磁盘空间和安装时间。
npm 模式: pnpm 模式:
projectA/node_modules projectA/node_modules/.pnpm/react@18 → 全局存储/react@18
└── react (500MB) projectB/node_modules/.pnpm/react@18 → 同一个全局存储 ↑
projectB/node_modules
└── react (500MB) ← 又存了一份!

pnpm 的内容寻址存储原理

  1. 所有包存储在全局仓库(~/.pnpm-store
  2. 每个包的存储位置由其内容的哈希值决定
  3. 项目中的 node_modules 通过硬链接指向全局存储
  4. 相同内容只存储一次,不同项目共享

3.3 版本要求#

  • Node.js ≥ 22:Firefly 使用了最新的 ES 特性和 Astro 6.x,需要较新版本的 Node.js
  • pnpm ≥ 9:项目配置了 packageManager: "pnpm@9.14.4",使用 only-allow pnpm 强制使用 pnpm

4. 项目初始化:从模板开始 vs 从零搭建#

4.1 为什么使用模板#

Firefly 模板基于 Fuwari 二次开发,已经集成了:

  • 完整的 Astro 配置(Markdown 插件、Expressive Code 代码高亮、Katex 数学公式等)
  • 响应式布局(双侧边栏、网格/瀑布流)
  • 多语言支持(i18n)
  • 全文搜索(Pagefind)
  • 评论系统集成(Twikoo/Waline/Giscus/Disqus/Artalk)
  • 主题系统(亮色/暗色/跟随系统)
  • 动画效果(Swup 页面过渡)

使用模板可以让你站在巨人的肩膀上,专注于内容创作而非基础设施搭建。

4.2 Git 克隆与版本控制#

Terminal window
# 从 GitHub 克隆
git clone https://github.com/CuteLeaf/Firefly.git
cd Firefly
# 或从 Gitee 镜像克隆(国内访问更快)
git clone https://gitee.com/CuteLeaf/Firefly.git
cd Firefly

Git 原理简述

  • Git 是一个分布式版本控制系统
  • .git/ 目录包含完整的版本历史
  • 每次 commit 创建一个快照(snapshot),记录文件的变化
  • 远程仓库(GitHub/Gitee)是代码的中央存储和协作平台

5. 目录结构与架构设计#

Firefly/
├── src/ # 源代码目录
│ ├── assets/ # 静态资源(图片、壁纸)
│ │ └── images/
│ │ ├── DesktopWallpaper/ # 桌面壁纸
│ │ └── MobileWallpaper/ # 移动壁纸
│ ├── components/ # UI 组件
│ │ ├── analytics/ # 统计分析组件
│ │ ├── comment/ # 评论系统组件
│ │ ├── common/ # 通用组件(按钮、分页等)
│ │ ├── controls/ # 控制组件(搜索、主题切换等)
│ │ ├── features/ # 功能组件(音乐、特效等)
│ │ ├── layout/ # 布局组件(导航栏、侧边栏等)
│ │ ├── misc/ # 杂项组件(分享海报等)
│ │ ├── pages/ # 页面级组件
│ │ └── widget/ # 侧边栏小组件
│ ├── config/ # 配置文件(TypeScript)
│ ├── constants/ # 常量定义
│ ├── content/ # 内容目录
│ │ ├── posts/ # 博客文章(.md)
│ │ └── spec/ # 特殊页面内容
│ ├── i18n/ # 国际化翻译文件
│ ├── pages/ # Astro 页面路由
│ ├── plugins/ # 自定义插件
│ ├── styles/ # 全局样式
│ └── types/ # TypeScript 类型定义
├── public/ # 静态文件(直接复制到 dist/)
│ ├── _headers # 安全头配置(Cloudflare Pages)
│ └── _redirects # 重定向规则
├── dist/ # 构建输出目录
├── astro.config.mjs # Astro 核心配置
├── package.json # 项目元数据和依赖
├── pnpm-lock.yaml # 依赖锁定文件
├── tsconfig.json # TypeScript 配置
└── wrangler.toml # Cloudflare Pages 配置

5.1 Astro 的基于文件的路由#

Astro 使用 文件系统路由

src/pages/
├── index.astro → https://yoursite.com/
├── about.astro → https://yoursite.com/about/
├── posts/
│ └── [slug].astro → https://yoursite.com/posts/hello-world/
├── archive.astro → https://yoursite.com/archive/
└── rss.xml.js → https://yoursite.com/rss.xml

原理:Astro 在构建时扫描 src/pages/ 目录,为每个 .astro.md.mdx 文件生成对应的 HTML 页面。[slug] 是动态路由参数,可以匹配任意路径段。

5.2 内容集合(Content Collections)#

Astro 的内容集合系统让你以类型安全的方式管理 Markdown 内容:

src/content/config.ts
const postsCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
published: z.date(),
tags: z.array(z.string()),
draft: z.boolean().default(false),
}),
});
export const collections = { posts: postsCollection };

原理:Astro 在构建时读取 src/content/posts/ 下的所有 Markdown 文件,根据 schema 验证 frontmatter,并提供类型安全的查询 API。


6. 配置文件体系:类型安全的前端配置#

6.1 TypeScript 配置的优势#

Firefly 使用 TypeScript 编写配置文件,提供:

  • 编译时类型检查:配置错误在构建时就暴露,不会等到运行时才发现
  • IDE 智能提示:编辑器自动补全配置项
  • 结构化组织:相关配置集中管理

6.2 关键配置说明#

siteConfig.ts — 站点基础配置#

export const siteConfig: SiteConfig = {
title: "CC's Blog", // 站点标题
site_url: "https://...", // 站点 URL(用于 RSS、sitemap)
themeColor: {
hue: 165, // 主题色相(0-360,HSL 色彩空间)
defaultMode: "system", // 亮色/暗色/跟随系统
},
// ...
};

HSL 色彩空间原理

  • Hue(色相):0°=红色,120°=绿色,240°=蓝色,范围 0-360
  • Saturation(饱和度):颜色的纯度,0%=灰色,100%=最鲜艳
  • Lightness(亮度):0%=黑色,50%=正常,100%=白色

Firefly 允许你调节色相值来一键改变整个博客的主题色。

profileConfig.ts — 个人资料#

配置头像、昵称、个人简介和社交链接。社交链接使用 Iconify 图标系统,支持 200,000+ 图标。

sidebarConfig.ts — 侧边栏布局#

// 组件类型
type WidgetComponentType =
| "profile" // 个人资料
| "announcement" // 公告
| "music" // 音乐播放器
| "categories" // 分类
| "tags" // 标签
| "stats" // 站点统计
| "calendar" // 日历
| "sidebarToc" // 文章目录
| "advertisement" // 广告

每个组件可以配置:

  • position: "top" — 固定在侧边栏顶部
  • position: "sticky" — 跟随页面滚动
  • showOnPostPage — 是否在文章详情页显示
  • showOnNonPostPage — 是否在列表页显示

7. 内容创作:Markdown 及其扩展语法#

7.1 Markdown 基础#

Markdown 是一种轻量级标记语言,旨在用纯文本格式编写可读性强的文档。

# 一级标题
## 二级标题
**粗体** *斜体* ~~删除线~~
[链接](https://example.com)
![图片](image.jpg)
- 无序列表
1. 有序列表
> 引用
`行内代码`
​```javascript
// 代码块
console.log("Hello");
​```

7.2 Frontmatter — 文章元数据#

Markdown 文件顶部的 YAML 格式元数据:

---
title: 文章标题
published: 2026-01-01 # 发布日期
pinned: true # 置顶
description: 文章摘要
tags: [标签1, 标签2] # 标签
category: 分类名称
draft: false # true=草稿,不发布
image: ./cover.jpg # 封面图
---

原理gray-matter 库在构建时解析 frontmatter,将 YAML 转换为 JavaScript 对象,供模板使用。

7.3 Firefly 的 Markdown 扩展#

Firefly 通过 Astro 的 remark/rehype 插件系统扩展了标准 Markdown:

  • GitHub 风格提醒框(Admonitions):::note:::warning:::danger
  • GitHub 仓库卡片::github{repo="owner/repo"}
  • 数学公式:通过 Katex 渲染 LaTeX 公式
  • Mermaid 图表:通过 Mermaid 渲染流程图、时序图等
  • 代码高亮:通过 Expressive Code 实现增强的代码块

7.4 remark 与 rehype 处理管道#

Markdown 的处理分为两个阶段:

Markdown 文本
[remark 插件] ← 处理 Markdown AST (mdast)
[转换层] ← mdast → hast
[rehype 插件] ← 处理 HTML AST (hast)
HTML 输出
  • remark:操作 Markdown 抽象语法树(例如:提取阅读时间、解析自定义指令)
  • rehype:操作 HTML 抽象语法树(例如:添加 heading id、外部链接处理)

8. 静态站点生成(SSG)的工作原理#

8.1 构建流程#

🚀 pnpm run build
├─ 1. 图标生成 (generate-icons.js)
│ 扫描源码 → 提取图标引用 → 生成 icons.ts
├─ 2. Astro 构建 (astro build)
│ ├─ 解析内容集合 (Content Collections)
│ ├─ 编译 Astro/Svelte 组件
│ ├─ 静态路由生成 (SSG)
│ │ ├─ /index.html (首页)
│ │ ├─ /posts/*/index.html (文章页)
│ │ ├─ /archive/index.html (归档页)
│ │ ├─ /about/index.html (关于页)
│ │ └─ ... (15+ 页面)
│ ├─ 图像优化 (Sharp)
│ │ 原始图片 → WebP/AVIF 多种尺寸
│ └─ 资源打包 (Vite)
│ JS/CSS 打包、压缩、哈希命名
└─ 3. Pagefind 索引 (pagefind --site dist)
扫描 HTML → 提取文本 → 构建搜索索引

8.2 图像优化的原理#

Astro 内置的图像优化基于 Sharp(高性能 Node.js 图像处理库):

原始图片 (avif, 300KB)
Sharp 处理
├─ 调整尺寸 (响应式:320w, 640w, 1280w, 1920w)
├─ 格式转换 (avif → webp 或保留 avif)
└─ 压缩 (quality: 85)
输出多种尺寸 + srcset 属性

响应式图像原理

<img
src="/_astro/photo_1x.webp"
srcset="
/_astro/photo_320w.webp 320w,
/_astro/photo_640w.webp 640w,
/_astro/photo_1280w.webp 1280w
"
sizes="(max-width: 768px) 100vw, 50vw"
alt="..."
/>

浏览器根据屏幕宽度和设备像素比自动选择最佳图片,移动端加载小图,桌面端加载大图。

8.3 Pagefind 全文搜索原理#

Pagefind 是一个客户端全文搜索工具:

构建时:
dist/*.html → Pagefind 扫描 → 提取文本 → 构建倒排索引 → dist/pagefind/
运行时:
用户输入关键词 → JS 加载索引片段 → 本地搜索 → 返回结果(含上下文摘要)

为什么不需要后端

  • 索引文件是静态的,存储在 CDN 上
  • 搜索在浏览器本地执行
  • 只在用户搜索时才按需加载索引片段(不是一次性加载全部)

9. 前端技术栈深入#

9.1 Astro 组件#

.astro 文件是 Astro 的专有组件格式,分为两部分:

---
// 组件脚本(服务端,构建时执行)
// 可以访问文件系统、数据库等
import { getCollection } from 'astro:content';
const posts = await getCollection('posts');
---
<!-- 模板(生成的 HTML) -->
<div>
{posts.map(post => <PostCard post={post} />)}
</div>

关键区别--- 之间的代码在构建时在服务端执行,不会发送到浏览器。这保证了敏感逻辑和数据永远不会暴露给客户端。

9.2 Svelte 交互组件#

当需要交互时,Firefly 使用 Svelte(编译型 UI 框架):

ThemeSwitch.svelte
<script>
let isDark = $state(false);
function toggle() {
isDark = !isDark;
document.documentElement.dataset.theme = isDark ? 'dark' : 'light';
}
</script>
<button onclick={toggle}>
{isDark ? '🌙' : '☀️'}
</button>

为什么选择 Svelte 而不是 React/Vue

  • 编译时:Svelte 在构建时将组件编译为高效的 DOM 操作代码
  • 无运行时:不需要加载 React/Vue 运行时库
  • 更小的包体积:交互组件打包后通常只有几 KB

9.3 Swup 页面过渡#

Swup 是一个页面过渡库,实现 SPA 般的平滑过渡效果:

用户点击链接
Swup 拦截点击
fetch 新页面 HTML
解析并提取内容
CSS 过渡动画 (fade/swipe)
替换页面内容
更新浏览器 URL

原理:Swup 使用 History API 修改 URL,通过 AJAX 加载新页面内容,配合 CSS 过渡实现无刷新页面切换。

9.4 Iconify 图标系统#

Iconify 是一个统一的图标框架:

<!-- 使用任意图标集的任意图标 -->
<Icon name="fa7-brands:github" /> <!-- Font Awesome -->
<Icon name="material-symbols:home" /> <!-- Material Symbols -->
<Icon name="simple-icons:astro" /> <!-- Simple Icons -->

原理

  1. 构建时解析所有 Icon 组件的使用
  2. 只提取实际用到的图标数据
  3. 以 SVG sprite 或内联 SVG 的方式输出
  4. 不会加载整个图标库(可能数百 MB)

10. 安全防护体系#

10.1 静态站点的安全优势#

静态博客天生比动态博客更安全,因为:

  • 没有数据库 → 无法进行 SQL 注入
  • 没有服务端代码执行 → 无法上传 WebShell
  • 没有用户认证系统 → 无账户接管风险
  • 没有插件系统 → 无第三方代码执行风险

但仍需要防范以下问题。

10.2 HTTP 安全头详解#

Content-Security-Policy (CSP)#

CSP 是防御 XSS 攻击的核心机制。它告诉浏览器:只允许从指定的来源加载资源。

Content-Security-Policy: default-src 'self';
script-src 'self' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self' https://fonts.gstatic.com;
frame-src 'self' https:;
object-src 'none';
base-uri 'self';
form-action 'self';

指令含义

指令含义
default-src 'self'默认只允许从本站加载资源
script-src允许执行脚本的来源
style-src允许加载样式的来源
img-src允许加载图片的来源
font-src允许加载字体的来源
frame-src允许嵌入 iframe 的来源
object-src 'none'禁止 <object> <embed> 标签
base-uri 'self'限制 <base> 标签的值
form-action 'self'限制表单提交的目标

其他关键安全头#

# 防止点击劫持
X-Frame-Options: DENY
# 防止 MIME 类型嗅探
X-Content-Type-Options: nosniff
# 启用浏览器 XSS 过滤器
X-XSS-Protection: 1; mode=block
# 控制 Referer 信息泄露
Referrer-Policy: strict-origin-when-cross-origin
# 限制浏览器功能权限
Permissions-Policy: camera=(), microphone=(), geolocation=()
# 强制 HTTPS 连接
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

HSTS 的工作原理#

用户首次访问 https://example.com
服务器返回: Strict-Transport-Security: max-age=31536000
浏览器记录:此域名在未来 1 年内必须使用 HTTPS
即使之后用户输入 http://example.com
浏览器自动内部重定向到 https://example.com
中间人无法降级到 HTTP 进行攻击

10.3 邮件地址保护#

Firefly 使用 base64 编码保护页面上的邮件地址:

原始 HTML: <a href="mailto:user@example.com">Email</a>
编码后: <a href="mailto:dXNlckBleGFtcGxlLmNvbQ==">Email</a>

虽然简单,但可以有效防止大多数自动化爬虫收集邮件地址。

10.4 内容安全策略(CSP)深入#

CSP 采用白名单机制:

加载脚本时:
→ 检查 script-src 列表
→ 如果域名在列表中 → 允许加载
→ 如果不在列表中 → 阻止 + 上报违规
检测到 XSS 注入时:
<script>alert('xss')</script> ← 内联脚本(不在白名单中)
→ CSP 阻止执行
→ 攻击失败

11. 部署与 CDN#

11.1 为什么选择 Cloudflare Pages#

特性Cloudflare PagesVercelNetlify
免费额度无限带宽100GB/月100GB/月
DDoS 防护✅ 免费无限制❌ 需付费❌ 需付费
CDN 节点330+ 全球100+ 全球较少
构建次数500次/月6000次/月300分钟/月
自定义域名
SSL 证书✅ 自动✅ 自动✅ 自动

核心优势:Cloudflare 在全球拥有 330+ 数据中心(边缘节点),用户访问的是离自己最近的节点,延迟极低。

11.2 CDN 的工作原理#

无 CDN:
用户在中国 → 直接访问美国服务器 → 延迟 200ms+
有 CDN (Cloudflare):
用户在中国 → 访问最近的边缘节点(香港/东京)→ 延迟 <50ms
↓ (如果缓存命中)
直接返回缓存内容(无需回源)
↓ (如果缓存未命中)
从源站拉取 → 缓存到边缘 → 返回给用户

11.3 部署方式对比#

方式一:Git 集成自动部署(推荐)#

1. 推送代码到 GitHub
2. Cloudflare Pages 检测到推送
3. 自动执行构建:pnpm install → pnpm run build
4. 自动部署:dist/ → Cloudflare 全球 CDN
5. 自动分配域名:xxx.pages.dev

方式二:Wrangler CLI 手动部署#

Terminal window
# 安装 Wrangler
npm install -g wrangler
# 登录 Cloudflare
wrangler login
# 部署
wrangler pages deploy dist --project-name=my-blog

方式三:本地构建 + 手动上传#

  1. 本地执行 pnpm run build
  2. 通过 Cloudflare Dashboard 手动上传 dist/ 目录
  3. 或使用其他静态托管平台(Vercel、Netlify、GitHub Pages 等)

11.4 自定义域名与 DNS#

域名注册 (例如 Namecheap/阿里云)
配置 DNS 解析
将域名的 Nameserver 指向 Cloudflare
Cloudflare 管理 DNS + CDN + SSL + 安全
用户访问 yourdomain.com → Cloudflare CDN → 返回博客

DNS 解析过程

用户在浏览器输入 https://yourblog.com
1. 浏览器缓存检查 → 未命中
2. 操作系统缓存 (hosts 文件) → 未命中
3. 路由器缓存 → 未命中
4. ISP DNS 服务器
5. 根 DNS 服务器 (.)
6. .com 顶级域名服务器 (TLD)
7. yourblog.com 权威 DNS (Cloudflare)
8. 返回 IP 地址(Cloudflare Anycast IP)
9. 浏览器连接最近的 Cloudflare 边缘节点

12. DDoS 防护详解#

12.1 DDoS 攻击的类型#

Layer 7 (应用层)
├── HTTP Flood:发送大量 HTTP 请求
├── Slowloris:维持大量慢速连接
└── DNS Query Flood:大量 DNS 查询
Layer 4 (传输层)
├── SYN Flood:发送大量 TCP SYN 包(不完成三次握手)
└── UDP Flood:发送大量 UDP 包
Layer 3 (网络层)
├── ICMP Flood (Ping Flood)
└── IP Fragmentation Attack

12.2 Cloudflare 的 DDoS 防护原理#

Anycast 网络分散流量#

攻击流量
/ | \
/ | \
[节点A] [节点B] [节点C] ...
(少量) (少量) (少量)
每个节点只承担总量的一小部分

Anycast 让多个物理位置共享同一个 IP 地址。攻击流量被分散到全球 330+ 个数据中心,每个节点只承担总流量的极小一部分。

反向代理隔离#

攻击者 ←→ Cloudflare 边缘节点 (防护层) ←→ 源服务器
├ 分析流量模式
├ 挑战可疑请求 (JS Challenge / CAPTCHA)
├ 丢弃恶意流量
└ 转发合法流量到源站

所有的流量先经过 Cloudflare,恶意流量在边缘就被过滤掉了,不会到达源服务器。

速率限制(Rate Limiting)#

同一 IP:
├── 正常用户:10-30 请求/分钟 → 放行
├── 可疑行为:100+ 请求/分钟 → JS 挑战
└── 明显攻击:1000+ 请求/分钟 → 直接阻断

12.3 针对静态博客的最佳防护策略#

对于静态博客,推荐使用以下组合防护:

层级 1:Cloudflare DDoS Protection (免费)
→ 自动缓解 Layer 3/4 攻击
层级 2:Cloudflare WAF (Web Application Firewall)
→ OWASP Top 10 防护规则
→ 自定义规则(限制特定路径访问频率)
层级 3:HTTP 安全头
→ CSP、HSTS、X-Frame-Options 等
层级 4:速率限制
→ 限制 API 端点访问频率
→ 限制搜索端点
层级 5:源站保护
→ 只允许 Cloudflare IP 访问源站
→ 关闭所有不必要的端口

13. 持续集成与持续部署(CI/CD)#

13.1 Git + Cloudflare Pages 的自动化流程#

# .github/workflows/deploy.yml (可选,Cloudflare Pages 自带 CI)
工作流程:
push 到 main 分支
Cloudflare Pages 自动检测
拉取最新代码
执行构建命令 (pnpm run build)
部署到预览环境 (*.pages.dev)
(可选) 合并到 production 分支 → 部署到生产环境

13.2 预览部署#

Cloudflare Pages 为每个 Pull Request 自动创建预览环境:

PR #1 → https://abc123.myblog.pages.dev
PR #2 → https://def456.myblog.pages.dev
✅ 在合并前预览变更效果
✅ 与团队成员分享进行 review
✅ 不影响生产环境

14. 监控、分析与维护#

14.1 站点监控#

  • Cloudflare Analytics:流量、带宽、安全事件
  • Google Analytics / Umami:用户行为分析
  • Microsoft Clarity:用户行为录屏和热力图

14.2 内容维护#

Terminal window
# 创建新文章
pnpm new-post my-article
# 本地预览
pnpm dev
# 格式化代码
pnpm format
# 构建检查
pnpm check
# 生产构建
pnpm build

14.3 版本更新#

Terminal window
# 更新依赖到最新版本
pnpm update --latest
# 检查安全漏洞
pnpm audit
# 更新后务必测试构建
pnpm build

15. 总结:完整的技术链路#

从 0 到 1 搭建一个安全博客的完整技术链路:

1. 环境准备
├── 安装 Node.js (≥ 22)
├── 安装 pnpm (≥ 9)
└── 安装 Git
2. 获取代码
├── git clone 模板仓库
└── 安装依赖:pnpm install
3. 配置个性化
├── 修改站点配置 (siteConfig.ts)
├── 修改个人资料 (profileConfig.ts)
├── 配置导航栏 (navBarConfig.ts)
├── 配置侧边栏 (sidebarConfig.ts)
├── 配置壁纸 (backgroundWallpaper.ts)
├── 选择评论系统 (commentConfig.ts) [可选]
└── 更新页脚 (FooterConfig.html)
4. 撰写内容
├── 编写 Markdown 文章
├── 设置 frontmatter 元数据
└── 添加图片、代码块等资源
5. 本地测试
├── pnpm dev(开发模式,热重载)
└── pnpm build + pnpm preview(生产模式预览)
6. 安全加固
├── 配置 CSP 头 (public/_headers)
├── 配置 HSTS 头
├── 配置 X-Frame-Options
└── 配置其他安全头
7. 部署上线
├── 推送代码到 GitHub
├── 连接 Cloudflare Pages
├── 自动构建 + 部署
└── (可选) 绑定自定义域名
8. 后续维护
├── 定期更新内容
├── 更新依赖版本
├── 监控站点运行状态
└── 根据分析数据优化

关键技术栈总结#

层级技术作用
构建Astro 6.x静态站点生成
样式Tailwind CSS 4.x原子化 CSS
交互Svelte 5.xUI 交互组件
内容Markdown + MDX文章撰写
搜索Pagefind客户端全文搜索
图标Iconify图标系统
过渡Swup页面过渡动画
部署Cloudflare PagesCDN 托管
安全Cloudflare WAF + CSP应用安全防护
分析Umami / Google Analytics用户行为分析

附录:常见问题与解决方案#

Q1: 构建时出现 bangumi API 连接失败?#

原因:Bangumi (bgm.tv) API 在某些网络环境下不可访问。

解决:在 siteConfig.ts 中设置 pages.bangumi: false,或在构建时配置代理。

Q2: 如何添加自定义字体?#

src/config/fontConfig.ts 中配置,支持 Google Fonts 和本地字体。

Q3: 如何启用评论系统?#

  1. 部署评论后端(如 Twikoo 使用 Vercel 部署)
  2. commentConfig.ts 中填入后端地址
  3. 设置 type 为对应的评论系统

Q4: 图片加载慢怎么办?#

  1. 使用 WebP/AVIF 格式
  2. siteConfig.ts 中降低 imageOptimization.quality
  3. 利用 Cloudflare CDN 的自动优化功能(Polish、Mirage)

Q5: 如何实现完全免费的部署?#

  • 代码托管:GitHub (免费)
  • 构建部署:Cloudflare Pages (免费,无限带宽)
  • 域名:使用默认的 *.pages.dev 域名(免费),或购买自定义域名(约 ¥50/年)
  • 评论系统:Twikoo + Vercel (免费) 或 Giscus + GitHub Discussions (免费)

📚 参考资料

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
从0到1搭建博客技术原理完全指南
https://fzy.it.com/posts/从0到1搭建博客技术原理完全指南/
作者
Fzy
发布于
2026-07-05
许可协议
CC BY-NC-SA 4.0
相关文章 智能推荐
1
从单机到集群:分布式爬虫后端架构设计指南
系统设计 设计一套完整的分布式爬虫系统——任务队列派发、VPS 集群执行、Kafka 数据总线分发、多数据库(MySQL/MongoDB/ES/Doris/Redis)各司其职,包含故障处理和容错设计。
2
用 Scrapy 批量下载网站 PDF:从 14 个索引页到 3176 份文件
技术实践 从多个 HTML 索引页面出发,递归爬取目标域名下的所有 PDF 文件,最终下载 3176 个 PDF(1.8GB)。详解 Scrapy 爬虫设计思路、Content-Type 过滤、非 HTML 扩展名跳过、JOBDIR 持久化等实战技巧。
3
Scrapy 架构深度解析:每个文件在框架中扮演什么角色
技术原理 以 PDF 批量下载项目为实例,逐文件拆解 Scrapy 项目结构(settings.py、spider、middlewares、pipelines、items),解释引擎-调度器-下载器-爬虫-管道五层架构的协作原理。
4
从零构建 Google Trends 爬虫 API:单文件架构的工程实践
技术实践 详解一个基于 Flask + Playwright 的 Google Trends 热搜数据采集服务,涵盖双解析策略降级、指数退避重试、Pending 离线缓存、假成功防御等生产级工程实践。
5
全异步 Yahoo 热门新闻爬虫:模块化架构与三路数据输出实践
技术实践 详解一个基于 Python asyncio + Playwright + Kafka 的 Yahoo Trending 新闻爬虫,涵盖双引擎降级策略、7种选择器链、asyncio 与同步 requests 混用方案,以及本地 JSON、Kafka、ODS 三路并行数据输出设计。
随机文章 随机推荐
Fzy
Full-Stack Developer · Tech Enthusiast · Lifelong Learner
公告
欢迎来到我的博客!这是一则示例公告。
分类
标签
站点统计
文章
19
分类
10
标签
50
总字数
35,030
运行时长
0
最后活动
0 天前

目录