# 工作日志 001：从 ChatGPT Sites 到公网个人技术网站

**日期：** 2026-09-18  
**项目：** Longer Tech · AI × Embedded  
**本地目录：** `F:\Personal-Tech-Site`  
**GitHub：** `longer0606/personal-tech-site`  
**Cloudflare Pages：** `personal-tech-site.pages.dev`  
**正式域名：** `https://tech.bestlonger.top`

---

## 1. 今天完成了什么

今天从 ChatGPT 的网站创建能力入手，把一个想法完整走通成了真正能够从 Internet 访问的个人技术网站。

网站最初只定义了两个核心内容方向：

1. **ChatGPT 与 AI 工具生态**
   - ChatGPT 网页版与桌面版
   - Apps
   - Skills
   - Plugins
   - MCP（Model Context Protocol）

2. **STM32 / 嵌入式开发**
   - BNO085 工业姿态模块
   - ODrive 3.6 CAN 联调
   - moteus 开源关节驱动研究
   - PID / LQR 等机器人控制方向
   - Datasheet、协议、工具链和开源项目收藏

第一版不是传统个人简历页，而是定位成：

> **个人技术知识库的入口。**

它既展示当前在做的项目，也作为以后沉淀技术文章、工程记录、资料收藏和项目复盘的主页。

---

## 2. 网站创建

通过 DevSpace MCP 在本机创建了独立目录：

```text
F:\Personal-Tech-Site
```

第一版采用最简单、最稳定的静态网站结构：

```text
Personal-Tech-Site/
├── index.html
├── styles.css
└── app.js
```

没有引入 React、Vue 或其他大型前端框架。

这样做的原因是：

- 当前网站主要是内容型个人知识站；
- 静态站部署简单；
- 加载快；
- 几乎没有服务器维护成本；
- 很适合 GitHub + Cloudflare Pages；
- 后续仍然可以逐步升级为更完整的网站架构。

页面设计采用偏工业、工程和技术仪表盘风格，包含：

- 深色 / 浅色主题；
- 响应式布局；
- ChatGPT 工具生态说明；
- STM32 项目卡片；
- 学习与收藏区；
- 滚动动画；
- 中文 / English 双语切换。

语言切换采用同一份 HTML 页面和 JavaScript 字典实现，而不是维护两套独立页面。

---

## 3. 本机验证

网站首先在本机通过 Python HTTP Server 启动：

```text
http://127.0.0.1:4173
```

完成了以下基本检查：

- HTTP 返回 200；
- HTML 页面能够加载；
- CSS 正常；
- JavaScript 语法通过；
- ChatGPT 区域正常；
- STM32 区域正常；
- 中文 / English 语言按钮正常加入页面。

这一步证明：

> **网站本身先在本机成立，再进入 Git 和公网部署流程。**

---

## 4. GitHub：把网站变成可版本管理的项目

本机已经配置 Git 和 GitHub CLI，并已登录 GitHub 账号。

在网站目录执行 Git 初始化，并完成第一次提交：

```text
git init
git add ...
git commit
```

然后创建 GitHub 仓库：

```text
longer0606/personal-tech-site
```

并把本地项目推送到远端。

当前仓库使用 Private 模式。

从这一刻开始，网站不再只是 F 盘里的几个文件，而成为一个：

- 有版本历史；
- 可以恢复；
- 可以回滚；
- 可以跨电脑获取；
- 可以持续部署；
- 可以接 CI/CD；

的正式项目。

---

## 5. Cloudflare Pages：GitHub 与公网部署打通

在 Cloudflare Workers & Pages 中导入 GitHub 仓库：

```text
longer0606/personal-tech-site
```

Cloudflare 成功识别该仓库并完成首次 Pages 部署。

自动生成默认公网地址：

```text
https://personal-tech-site.pages.dev
```

外网检查返回：

```text
HTTP/1.1 200 OK
```

这证明 GitHub → Cloudflare Pages 的自动部署链路已经建立。

此后的基本发布流程变成：

```text
本地修改
   ↓
Git commit
   ↓
Git push
   ↓
GitHub
   ↓
Cloudflare Pages 自动拉取
   ↓
生成新的公网版本
```

---

## 6. 自定义域名：tech.bestlonger.top

主域名：

```text
bestlonger.top
```

已经由 Cloudflare 托管。

原有其他子域名继续保留各自职责，例如：

```text
devspace.bestlonger.top  → DevSpace MCP / Tunnel
ai.bestlonger.top        → 保留给其他 AI 服务
tech.bestlonger.top      → 个人技术网站
```

在 Cloudflare Pages 项目的 Custom Domains 中新增：

```text
tech.bestlonger.top
```

完成域名激活以后：

- DNS 解析成功；
- Cloudflare 代理生效；
- HTTPS 生效；
- 页面返回 HTTP 200；
- 最终页面内容与 Pages 部署版本一致。

正式公网入口确定为：

```text
https://tech.bestlonger.top
```

---

## 7. 最终架构

```text
ChatGPT / DevSpace MCP
          │
          │ 创建、修改网站
          ▼
F:\Personal-Tech-Site
          │
          │ Git commit / push
          ▼
GitHub
longer0606/personal-tech-site
          │
          │ 自动部署
          ▼
Cloudflare Pages
personal-tech-site.pages.dev
          │
          │ Custom Domain
          ▼
tech.bestlonger.top
          │
          ▼
       Internet
```

这是今天最重要的成果：

> **ChatGPT 不只是生成了一张网页，而是参与建立了一条从本地项目、版本管理、云端部署、域名、HTTPS 到公网访问的完整网站工程链路。**

---

## 8. 为什么下一步应该增加 CI

现在 Cloudflare Pages 已经实现了自动部署，也就是 **CD（Continuous Delivery / Deployment）** 的一部分。

但是仍然缺少真正的 **CI（Continuous Integration）**。

如果以后每次修改 `index.html`、`styles.css` 或 `app.js` 后直接 push，Cloudflare 会很快部署新版本。

问题是：

> 如果这一版代码有语法错误、内部链接失效、关键文件丢失，Cloudflare 仍可能把错误版本发布出去。

所以 CI 应该位于 GitHub 和正式部署之间，承担“质量门”的职责。

建议分两阶段建设。

### 阶段 A：现在就做的基础 CI

使用 GitHub Actions，每次 push / pull request 自动执行：

1. 检查必需文件是否存在；
2. 检查 HTML 重复 ID；
3. 检查站内 `#anchor` 是否都能找到目标；
4. 检查本地 CSS / JS 引用文件是否存在；
5. 用 Node.js 检查 `app.js` 语法；
6. 启动本地 HTTP Server；
7. 使用 `curl` 检查首页是否返回 HTTP 200。

这套 CI 不依赖额外收费服务，也不需要保存新的密钥。

### 阶段 B：以后升级成严格 CI → CD

当前 Cloudflare Pages 的 GitHub Integration 会在 push 后自行部署。

这意味着：

```text
Git push
├── GitHub Actions CI
└── Cloudflare Pages Deploy
```

两者可能并行。

也就是说，阶段 A 的 CI 主要起“自动检查和报警”作用，但它还不是严格意义上的部署闸门。

以后如果希望做到：

```text
Git push
   ↓
CI 全部通过
   ↓
才允许部署
   ↓
Cloudflare Pages
```

可以再把 Cloudflare 部署改成 GitHub Actions 中的第二个 Job，并使用 Cloudflare 官方 API Token / Wrangler 进行部署。

届时真正形成：

```text
CODE
 ↓
CI
 ↓ PASS
CD
 ↓
PRODUCTION
```

---

## 9. 当前自动化目标

从今天开始，网站工程希望逐步达到：

```text
写内容 / 改网页
      ↓
本地检查
      ↓
Git
      ↓
GitHub Actions CI
      ↓
Cloudflare Pages
      ↓
tech.bestlonger.top
```

以后不再手工上传网页文件，也尽量不手工重复做部署操作。

---

## 10. 下一步

网站基础设施已经完成。

下一阶段重点不再是“把网站打开”，而是把它建设成真正长期使用的个人知识系统：

- 首页；
- ChatGPT 专题；
- Apps / Skills / Plugins / MCP 专题；
- STM32 项目；
- BNO085；
- ODrive；
- moteus；
- KiCad；
- 工作日志；
- Markdown 技术文章；
- 项目时间线；
- 全文搜索；
- 标签和资料索引。

这篇日志作为该网站的：

> **Work Log #001**

以后网站的重要架构变化、部署变化和项目里程碑，都继续用相同方式记录。

---

## 11. 技术复盘：真正值得复用的不是命令，而是职责分层

这次工作最值得保留下来的知识，不是某一条 Cloudflare 或 Git 命令，而是下面这套分层模型。

| 层 | 当前实现 | 主要职责 | 出问题时先看什么 |
|---|---|---|---|
| 创作 / 执行 | ChatGPT + DevSpace MCP | 生成内容、修改文件、运行检查 | 代码、路径、工具调用 |
| 本地源码 | F:\Personal-Tech-Site | 当前可编辑工作副本 | 文件、语法、资源链接 |
| 版本控制 | Git + GitHub | 历史、远端备份、自动化触发点 | commit、push、branch |
| 持续验证 | GitHub Actions | 为每次变更提供质量证据 | Workflow、Runner、测试脚本 |
| 托管 / CDN | Cloudflare Pages | 发布静态文件并提供边缘访问 | Deployment、Git integration |
| 公网入口 | DNS + Custom Domain | 把域名映射到 Pages 项目 | DNS、Custom Domain、TLS |

这个模型非常适合排障。

例如：

- personal-tech-site.pages.dev 正常，但 tech.bestlonger.top 失败：优先检查 DNS / Custom Domain / TLS，而不是去改 HTML。
- 本机验证通过，但 GitHub CI 失败：优先检查 Runner 环境差异和测试脚本假设。
- CI 和 Pages 都成功，但线上内容不对：检查部署的 commit SHA、浏览器缓存和 Cloudflare 缓存。

### 11.1 为什么第一版故意使用静态网站

当前网站的核心需求是技术文章、项目展示、工作日志、少量 JavaScript 交互和中英文切换。它暂时不需要用户登录、服务端业务逻辑、实时数据库、支付或动态 API。

因此使用 HTML + CSS + JavaScript 的静态站，可以减少一整层运行时复杂度：

~~~text
Browser
   ↓ HTTPS
Cloudflare Edge
   ↓
HTML / CSS / JS
~~~

没有自己维护的长期运行服务器，也没有数据库连接池、后端依赖和服务器进程。

这不是“技术简单”，而是：

> **当前需求没有为额外复杂度提供足够收益。**

等以后 Markdown 构建、搜索、动态索引或用户功能确实需要时，再升级技术栈。

### 11.2 GitHub 不只是备份，而是交付系统的共同锚点

本机代码经过：

~~~text
git add
git commit
git push
~~~

进入 GitHub 后，每个版本都有一个明确的 commit SHA。这个 SHA 同时可以被 GitHub Actions、Cloudflare Pages、人工回滚和后续 Release / Tag 使用。

因此 GitHub 在这里承担的不只是“远端存储”，更重要的是：

> **给 CI、CD 和人工运维提供一个共同、不可歧义的版本坐标。**

### 11.3 当前 CI 与 CD 是并行关系

当前真实结构是：

~~~text
             ┌── GitHub Actions CI
git push ────┤
             └── Cloudflare Pages Deploy
~~~

这和很多教程里简化成的：

~~~text
git push → CI → deploy
~~~

并不一样。

当前模式的特点：

- CI 失败会被明确标红；
- Cloudflare Pages 可能已经开始甚至完成部署；
- CI 目前是质量信号，而不是强制部署闸门。

对于当前个人静态站，这个复杂度是合适的。

如果未来希望严格做到“CI PASS 后才允许生产部署”，就应当把 Cloudflare 部署动作收进 GitHub Actions，在测试 Job 成功以后再运行部署 Job。

### 11.4 一次真实的 CI Race Condition

在把 Work Log #001 做成网页以后，曾出现一次非常有价值的 CI 失败：

~~~text
curl: (7) Failed to connect to 127.0.0.1 port 4173
~~~

当时测试逻辑是：

~~~bash
python -m http.server 4173 --bind 127.0.0.1 &
sleep 1
curl http://127.0.0.1:4173/
~~~

问题不是网页坏了。问题在于 sleep 1 只表示“等了一秒”，并不能证明 HTTP Server 已经 ready。

CI Runner 的调度和进程启动时间并不保证每次完全一致，因此这属于典型的 readiness / race condition。

后续改成：

~~~bash
for attempt in {1..10}; do
  if curl --fail --silent http://127.0.0.1:4173/; then
    break
  fi
  sleep 1
done
~~~

工程经验是：

> **测试一个外部进程时，应检测真实的就绪条件，而不是用固定 sleep 猜测它应该已经启动。**

### 11.5 为什么工作日志里的流程图要使用 Archify

最初日志用纯文本箭头表示 Local → GitHub → Cloudflare → Internet。这种表示适合终端或快速笔记，但不适合面向读者的正式技术文章。

因此网页版 Work Log #001 改为使用 Archify 生成交互式 Workflow 图：

~~~text
assets/diagrams/site-delivery-workflow.archify.json
assets/diagrams/site-delivery-workflow.html
~~~

图中刻意保留了当前真实架构：

- GitHub 向 GitHub Actions CI 分支；
- GitHub 同时向 Cloudflare Pages 自动部署分支；
- CI 没有被画成 Cloudflare 的前置节点。

这是一个重要原则：

> **架构图应该表达系统现在实际怎样工作，而不是把未来希望实现的状态画成现在已经实现。**

Archify 的 showcase 验证结果：

- 9 / 9 artifact checks 通过；
- composition errors = 0；
- warnings = 0。

### 11.6 推荐的排障顺序

以后网站发布出现问题，优先按照下面顺序定位：

~~~text
1. 本地文件是否正确？
       ↓
2. 本地 HTTP 是否返回 200？
       ↓
3. Git commit / push 是否正确？
       ↓
4. GitHub Actions 是否通过？
       ↓
5. pages.dev 是否返回 200？
       ↓
6. tech.bestlonger.top 是否解析？
       ↓
7. HTTPS / 页面内容是否正确？
~~~

这个顺序的核心思想是：

> **从离源码最近的一层开始，逐层向公网边缘验证，不跨层猜故障。**

---

## 12. 本篇日志的编辑原则

从 Work Log #001 开始，网站公开日志不再只回答“今天做了什么”，而要至少回答四个问题：

1. **为什么这样设计？**
2. **系统实际是怎样工作的？**
3. **过程中遇到了什么真实问题？**
4. **别人读完以后，可以把什么经验复用到自己的项目？**

这将作为后续 Work Log 的内容标准。

