Skip to content

第二卷:从本地网站到公网 ​

Volume 2: From Local Site to the Public Internet ​

卷首语

第一卷解决的是“怎样让 Harness 在规则里可靠地做事”,第二卷解决的是“怎样把我们已经做出来的东西真正送到 Internet 上”。

这次探索的起点其实很普通:我们已经有一个能在本地打开的 VitePress 网站,也已经把 DeepSeek Harness 的第一卷整理进去了。但只在 localhost 上能看,离“网站”还差很远。我们需要让它有版本历史、能自动发布、有自己的域名、能用 HTTPS,并且最重要的是——在中国大陆真实网络里,不开梯子也能打开。

所以后面的步骤不是一套预先设计好的云计算课程,而是被真实问题一步步逼出来的:先整理网站结构和阅读体验,再用 Git 把版本封存;接着把私有源码交给 GitHub,让 EdgeOne 自动构建;部署成功后又遇到大陆 401,于是继续追到域名、DNS、CNAME、HTTPS 和网络可达性;网站真的能打开以后,再回头给域名、腾讯云和 GitHub 加上基础安全保护。

阅读这一卷时,重点不要放在“腾讯云某个按钮在哪里”,而要看每一步在 Internet 的哪一层解决了什么问题。我们仍然沿用同一套学习方法:先遇到问题,再引入术语;先看数据和结果,再决定下一步。


第 1 章:先把网站做成“读得懂的东西” ​

本章导语

第一卷结束时,我们已经有了真正值得发布的内容,但“有内容”不等于“有一个能让别人看懂的网站”。这一章先处理发布之前最容易被忽视的部分:网站到底是什么、各层导航各管什么,以及为什么阅读体验本身也是架构的一部分。

我们最后把整个站点定成 Internet Exploration Website。它不是数学、物理、社科和工具的综合资料库,而是通过真实项目不断学习 Internet、Web、Agent、Cloud、Network、Deployment、Git、API、Filesystem 和 Software Architecture。

当前结构变成:

text
Internet Exploration
└─ DeepSeek Harness
   ├─ 第一卷:周复盘系统
   └─ 第二卷:从本地网站到公网

这里的核心概念是【术语】Information Architecture(IA,信息架构):不是“文件夹分了几层”,而是读者能不能理解 Site、Project、Volume 和 Document 之间是什么关系。

我们最终明确:

  • Site:Internet Exploration,回答“整个网站在做什么”;
  • Project:DeepSeek Harness,回答“我们正在通过什么真实项目学习”;
  • Volume:一次真实探索形成的一卷;
  • Document:正文、架构、测试与证据、术语、设计决策、提示词、附件与记录。

这个判断也带来一个长期规则:不提前建空卷,不为了目录好看制造不存在的内容。 只有真实探索已经发生,才新增 Volume。

接着我们把导航职责拆开:顶部是【术语】Global Navigation(全局导航),左侧 Sidebar 负责卷册和材料之间切换,右侧 TOC 只管当前文章内部。Breadcrumb 告诉读者“我在哪里”,返回上一级 回到 IA 父节点,上一阅读页 则回到这次会话中刚才真正看过的页面。

长文还有一个很实际的问题:读到几千字以后,怎么随时离开当前页?所以我们给“返回上一级”做了 position: sticky。这就是【术语】Sticky Positioning(粘性定位):按钮仍属于正文布局,但滚动到一定位置后会持续留在视野里。

这一轮还完成了六套独立主题、Callout、术语首次出现高亮和 Web Font。75 个术语不是拆成孤立词典,而是在第一次真正出现时用语义 Wrapper 标出来。这里引入【术语】Semantic Markup(语义标记):样式只是结果,更重要的是 HTML 结构明确知道“这是术语、这是定义”。

字体使用了 LXGW WenKai GB Screen。效果不错,但完整字体文件大约 24.8 MiB,这也留下了一个很真实的【术语】Performance Debt(性能债务):现在先保证内容可读,未来再做 Font Subsetting / WOFF2 等性能优化。

最重要的是,这一章把发布对象先稳定下来:我们不是把一堆 Markdown 丢到网上,而是在发布一个有明确层级、可持续增长、能长时间阅读的网站。


第 2 章:从 Markdown 到一个可以发布的版本 ​

本章导语

上一章先把“要发布什么”理顺了,这一章开始处理“这个东西怎样变成可部署的文件”。我们会把 VitePress、Build、Git 和 GitHub 连成一条线:先让本地内容变成静态产物,再给它一个可靠的版本历史。

网站使用 VitePress。它属于【术语】SSG(Static Site Generator,静态站点生成器):在构建阶段把 Markdown 和配置转换成 HTML、CSS 和 JavaScript,而不是每个读者打开页面时再临时查数据库。

本地开发时,我们通过开发服务器预览;真正发布之前则运行 Production Build。这里要区分:

text
Development = 本机开发和预览
Production  = 最终给读者看的正式环境

【术语】**Build(构建)**就是把源文件转换成可部署文件;Build 结束后得到的 HTML、CSS、JS、字体等则叫【术语】Build Artifact(构建产物)。

但如果每次改网站都只是“覆盖文件”,很快就会不知道自己改过什么。所以我们把网站工程纳入 Git。

Git 真正解决的是“变化的历史”:

text
Working Tree
→ Staging Area
→ Commit
→ Branch
→ Remote

【术语】**Working Tree(工作区)**是硬盘上正在编辑的文件;【术语】**Staging Area(暂存区)**是已经挑选出来、准备进入下一次 Commit 的改动;【术语】**Commit(提交)**则是一个可以追踪的版本快照。

实际流程是:

text
git status
→ git add
→ git diff --cached
→ git commit
→ git push

我们还碰到了两个 Windows 用户很容易误判的小提示:LF will be replaced by CRLF 只是换行符规范提醒;Git 把中文路径显示成转义字符串,也不代表真实文件名坏了。

源码最后放进一个 Private GitHub Repository。这里第一次把“私有源码”和“公开网站”分开理解:

text
Private Source
→ Build
→ Public Artifact

读者能看网页,不等于能看私有 Git 历史。

为了公开版本不暴露个人环境信息,本卷不再写出本机盘符、个人目录或 GitHub 用户名;正文只保留 <Website Project>、<Obsidian Vault>、<Private GitHub Repository> 这类角色名称。


第 3 章:把 Push 变成自动上线——EdgeOne 与 CI/CD ​

本章导语

GitHub 解决了“源码放在哪里、版本怎么追踪”,但读者还是看不到网站。这一章把远程仓库接到 EdgeOne,让一次 git push 自动变成“拉代码、安装依赖、构建、发布”的完整流水线。

我们选择 EdgeOne Makers 做静态托管。当前 Production Branch 是 master,区域是:

text
Global (MLC excluded)

EdgeOne 的构建逻辑可以概括成:

text
GitHub master 收到新 Commit
→ Clone
→ Install
→ Build
→ Deploy
→ Production

这就是【术语】CI/CD 真正出现的地方。

  • 【术语】CI(Continuous Integration,持续集成):平台自动获取源码、安装依赖、构建和验证;
  • 【术语】CD(Continuous Deployment,持续部署):构建成功以后继续自动发布到 Production;
  • 【术语】Pipeline(流水线):这些自动步骤连起来形成完整流程;
  • 【术语】Trigger(触发器):让流水线开始的事件,这里就是 master 收到新的 Push。

Phase 5 的一次真实更新验证了:Push 到 GitHub 后,EdgeOne 自动完成新 Production Deployment,整个过程大约几十秒。

因此以后网站正常更新不需要手动点 Redeploy。标准流程变成:

text
修改
→ localhost 验收
→ Production Build
→ git commit
→ git push
→ EdgeOne 自动部署
→ 公网抽查

这一步很关键,因为网站第一次从“一个手工项目”变成“一个有发布流水线的系统”。


第 4 章:第一次公网失败——部署成功为什么大陆还是 401 ​

本章导语

自动部署成功以后,我们本来以为最难的部分结束了,但真实网络马上给了一个反例:EdgeOne 显示 Success,中国大陆手机却打不开默认域名。这一章就是从这次失败开始,真正区分“部署成功”和“用户能访问”。

EdgeOne 的默认项目域名在平台侧已经发布成功,但中国大陆无梯子访问时曾出现:

text
401 Unauthorized

这件事逼我们把两个经常被混在一起的概念分开:

  • 【术语】Deployment(部署):平台有没有成功把网站发布出来;
  • 【术语】Reachability(可达性):目标用户的真实网络能不能访问它。

所以:

text
Deployment Success ≠ Mainland Reachability

401 是【术语】**HTTP Status Code(HTTP 状态码)**之一。这里它并不说明 VitePress Build 失败,而是默认项目域名在当前区域和访问策略下没有给大陆直连用户正常放行。

这时我们也第一次认真理解 Global (MLC excluded):

【术语】MLC(Mainland China,中国大陆)。这个区域配置准确的意思是“EdgeOne 的加速范围不包含中国大陆节点”,而不是“中国大陆用户一定永远打不开”。

这里又牵出【术语】**CDN(Content Delivery Network,内容分发网络)**和【术语】Edge Node(边缘节点):CDN 会把内容分散到不同地理节点,用户再由调度系统连接合适节点。

因此我们先不急着买中国大陆服务器,也不急着做 ICP,而是提出一个更小、更可验证的问题:

默认 edgeone.dev 不行,那使用自己的 Custom Domain 能不能让大陆用户正常进入 EdgeOne?

这就把下一步自然推到了域名。


第 5 章:买域名不是买套餐——域名、实名认证、ICP备案和成本 ​

本章导语

上一章的问题已经很明确:我们需要一个自己能控制的公网入口。但一进入域名购买页,各种 .com、.cn、DNS 专业版、SSL、轻量服务器和组合套餐同时出现,很容易把“真正需要的东西”和“顺手卖给你的东西”混在一起。这一章先把购买和合规理清。

最终我们选择:

text
internetlab.cn

首年价格:

text
33 元

选择 .cn 不是因为它能自动获得中国大陆 CDN 节点,而是因为这个名字短、没有数字和连字符、和 Internet Exploration 的长期方向相符,同时面向大陆读者、成本也低。

这里顺便区分:

  • 【术语】gTLD:.com 这类通用顶级域;
  • 【术语】ccTLD:.cn 这类国家和地区顶级域。

腾讯云还推荐了组合域名、付费 DNS、付费 SSL、轻量服务器。我们最终都没有买。

【术语】**Upsell(附加销售)**就是在购买核心产品时继续推荐附加服务。判断标准不是“它有没有用”,而是“当前架构现在需不需要”。对这个静态站来说:

text
域名        需要
付费 DNS    暂不需要
付费 SSL    不需要
服务器      不需要

域名注册还涉及【术语】**Registrant(域名注册人)**和实名认证。实名认证只是证明“这个域名由谁持有”,它和【术语】**ICP Filing(ICP备案)**不是同一件事。

我们当时选择的是:

text
Global (MLC excluded) + Custom Domain

因此没有为了当前部署额外购买大陆云资源去做 ICP。

还有一个很实际的操作问题:腾讯云中国站和 Tencent Cloud International 在同一个 Edge Profile 里频繁切换,会反复要求登录。最后我们把它们分到两个【术语】**Browser Profile(浏览器配置文件)**里。不同 Profile 会隔离 Cookie 和 Session,于是两个云控制台不再互相覆盖登录状态。


第 6 章:先证明域名属于你——TXT 与域名归属验证 ​

本章导语

域名买下来以后,我们又遇到一个看起来很“多余”但其实非常合理的问题:腾讯云知道域名是我们的,不代表 EdgeOne 也自动知道。跨平台之间必须有一种能公开验证、又不需要共享账号密码的证明方式,这就是 DNS 所有权验证。

在 EdgeOne 添加 Custom Domain 时,我们把:

text
internetlab.cn
→ Production

关联到项目。

接着 EdgeOne 要求在 DNS 里添加一条 TXT 记录。主机记录类似:

text
edgeonereclaim

记录值是一段 EdgeOne 生成的验证字符串,本卷公开版统一写成:

text
<redacted-verification-token>

【术语】**TXT Record(TXT 记录)**可以在 DNS 中保存文本。它最常见的用途之一就是域名控制权验证。

验证逻辑很简单:

text
EdgeOne 给出随机字符串
→ 只有能控制 internetlab.cn DNS 的人才能写入
→ EdgeOne 再从公网 DNS 查询
→ 查询到正确 TXT
→ 接受域名归属权

这里学到的是:

text
“域名已经注册成功”
≠
“所有其他平台都会自动相信这个域名归你”

平台之间需要通过公开协议建立信任,而不是互相共享后台账号。


第 7 章:让域名真正把流量送到网站——DNS、A、CNAME 与 TTL ​

本章导语

TXT 只解决了“这个域名是不是你的”,还没有解决“别人访问这个域名时到底应该去哪里”。这一章开始配置真正的流量路由,也正是在这里,我们碰到了一个很有教学价值的错误:把域名目标放进了 A Record 的上下文。

DNSPod 是当前的【术语】Authoritative DNS(权威 DNS)。它保存 internetlab.cn 的正式解析记录。

EdgeOne 给出的正式目标是:

text
internetlab.cn.pages.dnsoe9.com

我们最终需要的是:

text
Host: @
Type: CNAME
Line: 默认
Value: internetlab.cn.pages.dnsoe9.com
TTL: 600

其中 @ 表示根域名 internetlab.cn 本身。

配置过程中曾出现:

text
请填写正确的 IPv4 地址

这不是 EdgeOne 给错了值,而是 DNSPod 当时还把这一行按 A Record 来理解。这个错误反而把三种记录的区别讲得最清楚:

text
A Record      → 域名直接指向 IPv4
CNAME Record  → 域名指向另一个域名
TXT Record    → 保存文本

【术语】**CNAME(Canonical Name Record)**可以理解为“这个域名其实是另一个域名的别名”。我们不把 internetlab.cn 固定到某一个 IP,而是把后续节点选择交给 EdgeOne。

浏览器实际经历的过程大致是:

text
internetlab.cn
→ DNS 查询
→ CNAME 到 EdgeOne 目标
→ EdgeOne 调度
→ Edge Node
→ Production

【术语】**TTL(Time To Live)**设置为 600 秒,也就是 10 分钟。它不是“网站十分钟更新一次”,而是 DNS Resolver 可以把这条解析结果缓存多长时间。

因此所谓【术语】DNS Propagation(DNS 生效传播),很多时候不是新记录真的要一点点复制到全世界,而是各地旧缓存要等 TTL 到期后重新查询。

最终 EdgeOne 把状态从“请添加 CNAME”变成“已生效”。这说明域名路由这一层真正打通了。


第 8 章:给网站加上 HTTPS——证书、TLS 与自动跳转 ​

本章导语

CNAME 生效以后,浏览器终于知道“应该去 EdgeOne 找这个网站”,但还差最后一层信任:浏览器怎么确认自己连接的真是 internetlab.cn,而且中间传输没有被明文窃听?这一章就是 HTTPS。

EdgeOne 的域名状态此时已经是:

text
状态:已生效
HTTPS:未配置
Production

我们没有去买付费 SSL,而是直接选择 EdgeOne 免费证书,并使用自动验证。

【术语】HTTPS可以简单理解为 HTTP over TLS。

【术语】**TLS(Transport Layer Security)**负责建立加密连接;【术语】**Certificate(数字证书)**负责向浏览器证明“这个服务确实有权代表 internetlab.cn”。证书由【术语】**CA(Certificate Authority,证书颁发机构)**签发。

因为 CNAME 已经指向 EdgeOne,自动验证就有了前提。EdgeOne 可以完成:

text
域名验证
→ 证书申请
→ 证书签发
→ 部署到 Edge Node
→ 后续自动续签

最终控制台显示:

text
HTTPS 配置:已部署

浏览器访问 https://internetlab.cn 时,会先做【术语】TLS Handshake(TLS 握手):检查域名、证书有效期、CA 信任链和数字签名,再协商会话密钥,之后才真正传输 HTML、CSS、JS 和字体。

我们还测试了:

text
http://internetlab.cn

浏览器会自动变成:

text
https://internetlab.cn

这叫【术语】HTTP → HTTPS Redirect。它和 CNAME 不是一回事:CNAME 发生在 DNS 层,Redirect 发生在 HTTP 层。


第 9 章:真正的验收——中国大陆不开梯子能不能访问 ​

本章导语

到这里,所有控制台都已经“绿了”,但我们已经吃过一次亏:控制台 Success 不能代替真实用户。所以这一章不再看配置,而是直接拿目标环境做现场测试。

测试条件:

text
网络:中国大陆移动数据
VPN / 梯子:关闭

实际结果:

text
https://internetlab.cn    ✅ 正常
http://internetlab.cn     ✅ 正常,并自动跳到 HTTPS

这一步验证的是【术语】Field Test(现场测试):不在开发机和控制台里推断,而是在真正目标网络上验证。

它也给 Global (MLC excluded) 一个更准确的现实解释:

没有中国大陆 Edge Node,不等于中国大陆客户端完全无法连接境外 EdgeOne 节点。

因此当前路线已经满足“大陆用户无梯子可以阅读”。

但我们没有把一次移动网络测试夸大成“全国所有运营商都一定稳定”。更严谨的说法是:

text
当前大陆移动数据 Field Test:通过

Wi-Fi、不同运营商和性能测速仍属于后续测试,而不是本次已经完成的事实。


第 10 章:上线以后先锁住控制权——域名、腾讯云与 GitHub 安全 ​

本章导语

网站终于能被真实读者打开以后,问题从“怎么让别人进来”变成“怎么避免别人把它改掉”。这一章不追求把所有安全开关全开,而是先保护最值钱的控制面:域名、云控制台和源码账号。

这里先区分:

  • 【术语】Data Plane(数据平面):真正给读者传网页的链;
  • 【术语】Control Plane(控制平面):能修改域名、DNS、EdgeOne、GitHub 和 Production 的后台。

我们先在域名注册层开启:

text
禁止转移锁 ✅
禁止更新锁 ✅
CNNIC 隐私保护 ✅

【术语】Transfer Lock 防止域名被未经授权转移到其他 Registrar;【术语】Update Lock 限制关键注册信息和 Nameserver 被修改。

CNNIC 隐私保护的服务期选择了 10 年,控制台已经接受并显示到 2036 年。这里要特别说明:

text
隐私保护服务到 2036
≠ 域名本身已经续费到 2036

域名依然按自己的注册期限续费。

我们没有继续开启 Registry Lock 和 DNSSEC。原因不是“它们没用”,而是当前没有必要为了多一个安全开关增加兼容性和维护复杂度。

接下来保护账号。腾讯云添加了虚拟 MFA;GitHub 也用 Authenticator App 开启了 Two-Factor Authentication。

【术语】**MFA(Multi-Factor Authentication,多因素认证)**要求登录者不仅知道密码,还要拥有第二种验证因素。

Authenticator 使用【术语】TOTP(Time-based One-Time Password)。真正敏感的不是 30 秒变化一次的 6 位验证码,而是二维码里长期保存的 Secret / Seed。因此本卷不会公开 MFA 二维码、Secret、Recovery Codes、账号 ID、手机号或邮箱。

GitHub 的安全特别重要,因为当前发布链是:

text
GitHub master
→ EdgeOne 自动构建
→ Production
→ internetlab.cn

这就是【术语】Supply Chain Security(软件供应链安全):源码账号本身已经成为生产系统的一部分。

安全配置在这里主动停下。HSTS、OCSP Stapling、DNSSEC、Registry Lock、Passkey、严格 Branch Protection 都保留为后续真实需求,而不是为了“更安全”无限加开关。


第 11 章:把整条链收起来——以后更新网站到底还要做什么 ​

本章导语

前十章把内容、版本、部署、域名、DNS、HTTPS、网络和安全都走了一遍。最后这一章不再增加新平台,而是把这些层重新拼回一张图:以后普通更新到底需要碰哪些东西,又有哪些初始化步骤已经永远不必重复。

最终系统可以简化成:

text
Obsidian Source of Truth
→ Adapter
→ VitePress
→ Git
→ Private GitHub Repository
→ EdgeOne CI/CD
→ Production
→ internetlab.cn
→ DNS / CNAME
→ Edge Network
→ TLS / HTTPS
→ Reader

以后普通内容更新只需要:

text
修改内容
→ 本地验收
→ Production Build
→ git commit
→ git push
→ EdgeOne 自动部署
→ 公网抽查

不需要每次重新:

  • 买域名;
  • 实名认证;
  • 配 TXT;
  • 配 CNAME;
  • 申请证书;
  • 手动 Redeploy。

这一卷真正学到的不是“腾讯云怎么用”,而是 Internet 的不同层分别在解决什么问题:

text
内容层      → 写什么
构建层      → 怎么变成网页
版本层      → 怎么记录变化
仓库层      → 源码放哪里
CI/CD       → 怎么自动发布
Hosting     → 网页放在哪里
Domain      → 人怎么记住入口
DNS         → 这个入口指向哪里
Edge/CDN    → 请求由哪个节点服务
TLS/HTTPS   → 怎么确认身份并加密
Browser     → 用户最终怎么访问
Security    → 谁有权改变这一切

只要把这些层分清,很多“看起来像同一个问题”的故障就不会再混在一起:

text
Build 成功
≠ 大陆能访问

域名买到了
≠ DNS 已经指向网站

TXT 验证成功
≠ 流量已经进入 EdgeOne

CNAME 生效
≠ HTTPS 已经准备好

HTTPS 已部署
≠ 控制账号已经安全

第二卷到这里结束。网站第一次真正从“本地工程”变成了一个有版本历史、自动发布、自定义域名、HTTPS、真实网络可达性和基础控制面安全的公网系统。