Project / VWebServer
用自己的 C++ WebServer 搭建个人笔记站
这篇记录我的个人笔记站是如何搭建起来的。它不是单纯的前端页面展示,而是把自己实现的 C++ WebServer 真正用起来,让它托管静态资源、响应浏览器请求,并承载长期维护的学习笔记。
为什么要搭建这个笔记站
我搭建这个笔记站主要有两个目的。
第一,把之前零散的 C++、Linux、MySQL 和算法笔记用ai整理成一个可以长期回看的知识库。相比散落在本地目录里的 Markdown,站点化之后更适合浏览、检索和对外展示。
第二,让自己实现的 C++ WebServer 承载一个真实页面,而不是只停留在返回 Hello World、echo server 或压测接口的阶段。因此,这个站点既是学习笔记的展示入口,也是 WebServer 项目的一个实际使用场景。
整体架构:Caddy + C++ WebServer + 静态前端页面
当前站点采用静态页面方式构建,但对外入口不再直接暴露 C++ WebServer。公网请求先进入 Caddy,由 Caddy 负责域名、HTTP/HTTPS 入口和反向代理;真正返回静态资源的仍然是我自己实现的 C++ WebServer。
Browser
↓
Domain: vertaweb.cn / www.vertaweb.cn
↓
Caddy :80 / :443
↓ reverse_proxy
127.0.0.1:8080
↓
C++ WebServer in Docker
↓
Resources/
↓
HTML / CSS / JS / Notes
前端部分主要负责展示笔记分类、文章列表和项目记录;Caddy 负责站点入口和 TLS;后端 C++ WebServer 负责监听本机端口、解析 HTTP 请求、映射静态文件路径并返回响应。目前笔记内容以静态页面方式组织,后续可以考虑加入 Markdown 构建脚本,把 Markdown 自动转换为 HTML 页面。
后端:使用自己的 WebServer 托管静态资源
这个站点的后端没有直接使用 Nginx 或现成 Web 框架,而是使用自己实现的 C++ WebServer 来托管静态资源。
WebServer 主要负责:
- 接收浏览器发来的 HTTP 请求。
- 解析请求行和请求头。
- 根据 URL 映射本地静态资源路径。
- 返回 HTML、CSS、JavaScript、图片和 favicon 等文件。
- 对不存在或不可访问的资源返回 404 / 错误响应。
- 通过日志记录请求路径、错误信息和运行状态。
这让 WebServer 从一个单纯的练习项目,变成了一个能承载真实页面的服务端程序。首页、笔记详情页、样式文件、图标和静态资源都可以作为它的真实用例。
前端:用 AI 辅助完成页面原型和样式迭代
前端部分主要通过 AI 辅助开发完成。我先确定页面结构、内容分区和视觉风格,再使用 Codex 辅助生成 HTML/CSS 原型,之后根据实际效果进行人工调整。
这个过程接近现在常说的 vibe coding:先用自然语言描述目标效果,再通过多轮调整把页面迭代到可用状态。但 AI 辅助并不意味着完全不理解代码。实际调整过程中仍然需要理解 HTML 结构、CSS 布局、响应式效果以及静态资源路径,否则生成结果很难真正部署到自己的服务器上。
在这个站点里,AI 更多承担的是原型搭建和文案润色的角色;内容结构、项目重点、交互逻辑和最终取舍仍然由我来决定。
内容组织:C++ / Linux / WebServer / 算法笔记
站点内容主要分为三类。
- C++ 后端学习笔记:包括 C++ 基础语法、现代 C++、Linux 命令、MySQL 和算法笔记。
- WebServer 项目构建记录:记录 WebServer 从阻塞式服务器到 epoll + 线程池架构的演进过程,包括非阻塞 I/O、Connection 缓冲区、HTTP 状态机、Keep-Alive、静态文件服务和压测分析。
- 个人站点搭建记录:记录如何使用自己的 WebServer 托管笔记站,以及前端页面、部署流程和后续优化计划。
这样组织以后,首页负责展示最高价值入口,All 和分类区负责归档,单篇文章负责沉淀具体实现和复盘。
部署过程:云服务器、Docker、Caddy 反向代理
站点部署在云服务器上。服务器端的项目目录为 /root/VertaNotes,静态资源放在 /root/VertaNotes/Resources。C++ WebServer 运行在 Docker 容器 verta-notes 中,只绑定本机 127.0.0.1:8080;Caddy 监听公网 80/443,再把请求转发给本机 8080。
部署流程大致包括:
- 在云服务器上准备 Linux 运行环境。
- 克隆 VWebServer 仓库,并整理部署目录为
/root/VertaNotes。 - 用 Docker 运行 C++ WebServer,容器名为
verta-notes。 - 将容器端口绑定为
127.0.0.1:8080:8080,避免 C++ WebServer 直接暴露公网。 - 上传 HTML、CSS、JS、favicon 和 notes 页面到
Resources/。 - 配置 Caddy,将域名请求反向代理到
127.0.0.1:8080,并兼容无.html后缀的文章路径。 - 通过浏览器访问域名,并用 curl 检查本机转发链路。
当前 WebServer 容器启动方式类似下面这样:
docker run -d \
--name verta-notes \
--restart unless-stopped \
-p 127.0.0.1:8080:8080 \
-v /root/VertaNotes:/app \
-w /app \
v-web-server:latest \
bash -lc 'make clean && make && ./server'
Caddyfile 的核心配置保持克制:先把 /notes/xxx 这类无扩展名文章路径改写为 /notes/xxx.html,再统一反向代理给本机 WebServer。这样公开链接更干净,原来的 .html 路径也不会失效。
vertaweb.cn, www.vertaweb.cn {
@note_pages {
path /notes/*
not path *.html
not path *.*
not path */
}
rewrite @note_pages {path}.html
reverse_proxy 127.0.0.1:8080
}
这样做的好处是:公网只需要访问标准的 80/443 端口,HTTPS、证书续期和域名入口由 Caddy 负责;C++ WebServer 保持在内网回环地址后面,专注处理 HTTP 请求和静态文件返回。
资源同步:本地修改后推到服务器
页面内容主要在本地修改,然后通过同步脚本把 Resources/ 覆盖到服务器。现在使用的脚本是 sync-verta-notes.cmd,它会打包本地资源、上传到服务器、备份旧资源目录,再替换 /root/VertaNotes/Resources。
cd "D:\Documents\New project"
.\sync-verta-notes.cmd
同步脚本的默认目标是 CloudServer:/root/VertaNotes。这样页面迭代不需要每次手动登录服务器复制文件,也减少了路径写错的概率。
遇到的问题与解决
这个站点在搭建过程中最容易遇到的问题,不是页面能不能写出来,而是“写出来之后能不能被自己的服务器正确返回”。
- 静态资源路径问题:如果 /style.css 请求找不到文件,需要检查 URL 到本地路径的映射规则。
- Content-Type 问题:HTML、CSS、JS、图片需要返回不同的 Content-Type,否则浏览器可能无法正确解析。
- 端口访问问题:最开始可以直接把容器映射到公网 80 或 8080,但接入 Caddy 后更合适的方式是让 WebServer 只监听本机
127.0.0.1:8080,公网只暴露 80/443。 - 反向代理问题:Caddy 的
reverse_proxy目标必须和 Docker 端口绑定一致。如果容器没有绑定到127.0.0.1:8080,Caddy 就无法把请求转发给 WebServer。 - 页面刷新 404 问题:纯静态多页面需要保证文件路径真实存在;如果以后使用前端路由,则需要后端做路径回退。
- 后台运行问题:WebServer 通过 Docker 的
--restart unless-stopped管理,Caddy 通过系统服务运行,避免 SSH 断开后服务退出。
这些问题看起来和前端页面关系不大,但它们正好能验证 WebServer 是否真的具备托管静态站点的能力。
后续计划:内容构建、HTTPS 运维和自动化部署
域名、Caddy 反向代理和 HTTPS 入口已经接上,后续更适合继续完善内容生产和部署自动化。
- 继续检查 HTTPS 证书续期和 Caddy 服务状态。
- 接入 Cloudflare 做 DNS / 缓存 / 安全防护。
- 增加 Markdown 自动构建流程。
- 优化移动端适配。
- 继续完善文章搜索和分类索引。
- 把同步脚本进一步做成更完整的发布流程。
- 增加访问日志统计。
这篇文章的定位是:用一个真实站点证明自己的 C++ WebServer 能跑起来、能部署、能承载静态资源。