代码学习极客

返回 · 2026-05-10T15:49:00+00:00

py-blog:一个单文件博客

最近在搭建博客时实在是忍无可忍,最后决定自己搞一个够用就可以的博客,又想到也许可能有人会有和我一样的需求,于是写一篇文章来进行简要说明

摘要

  • 它是什么blog.py 里装着完整站点——FastAPI + SQLite + Jinja2,没有 Node、没有单独构建步骤。
  • 它想成为的样子:一块够用就好、边界清晰的小地方:你能读完代码,也能先写完文章再考虑扩展。
  • 它不假装的样子:不是富文本工作台,不是评论托管商,也不是主题商店;图床、评论若需要,从外面接进来即可。
  • 怎么用:装依赖、运行脚本;环境与表格详见文末及 README.md。
  • 尺度感:更像个人站与学习样本;仓库里没有成套自动化测试与 lint,别把它当成「对标头部 CMS 的框架」来期待。
  • 基础保障:迭代时会借助 Cursor 做一次简易功能测试,对核心路径做冒烟式确认;这与「尚未接入 CI / 单测」并存,属于轻量人工门禁而非完备质量体系。

有些人上手博客时,更在意的是:多久能发出第一篇。也有一类产品会把目录、插件、主题和流水线排在写字之前——那条路完全合理,只是不一定是你此刻需要的那条路。

py-blog 更接近另一种假设:你手头已经有 Markdown,想要一个能贴上域名、偶尔改两行样式的容器。它不必证明自己「体系完备」,只要在你打开仓库时,不会因为路径太深而不知从何看起。

它试着扮演的角色

这个项目更愿意被想象成:

  • 一页能跑起来的站点:Markdown 上传后保存时预渲染成 HTML,访客打开页时不再重复解析一遍。
  • 依赖很少的运行图景:SQLite、单管理员、密码登录外加常见的 Session / CSRF——足够应付「一个人维护」的场景。
  • 放在反代后面也很好相处:默认监听本机端口,前面挂 Nginx、配 HTTPS 是常见用法;备案文案可以用环境变量塞进页脚。

技术面目很简单:单文件 Python,HTTP、存储和模板渲染都在同一个文件里讲完,没有前端打包链路。

单文件对它意味着什么

形态不是口号,而是它给自己的规矩:

  • 「从哪里读起」只有一个答案:没有纵深很深的包结构;能读一点 Python,就能顺着路由和模板字符串往下看。
  • 「从哪里改样式」也多半在同一个文件里:搜得到字符串,就改得到界面,不必在十几个目录间跳转。
  • 部署时脑子里只装一件事:装依赖、执行 python blog.py,终端里会看到启动信息与(若未预设密码)一次性管理员口令——没有 Webpack,也没有 Node。

所以如果有人在群里问「主体代码在哪」,答案可以短到一个文件名。这对自用、自学或随手 fork,都算一种减负。

它不打算成为什么

边界写得清楚,反倒轻松:默认安装里不包含一整套周边产业

  • 没有内置富文本编辑器——正文假定你用习惯的编辑器写 Markdown。
  • 没有内置评论——需要时再接 Giscus、Disqus、Waline 一类服务。
  • 没有主题市场——观感不满意时,改模板字符串就是了;它接受自己「不那么开箱即炫」。

图片默认走外链 URL,而不是把存储、备份和迁移绑死在进程里。换句话说,它承认自己只是站点的一层壳,不把世上所有需求都吞进仓库。

怎么使用

克隆仓库并安装依赖后,直接运行:

git clone https://github.com/WHC2006/py-blog.git
cd py-blog
pip install -r requirements.txt
python blog.py

浏览器访问 http://127.0.0.1:8765,前台在 /,管理员登录在 /admin/login

若未设置 BLOG_ADMIN_PASSWORD首次启动会在终端打印一次随机管理员密码,请及时保存;也可通过环境变量显式设定密码与站点标题等。SQLite 与运行数据默认落在 data 目录(可通过环境变量调整)。

常用环境变量一览如下(完整说明仍以仓库内 README.md 为准):

变量 默认 说明
BLOG_HOST 127.0.0.1 监听地址
BLOG_PORT 8765 监听端口
BLOG_DATA_DIR data SQLite 与运行数据目录
BLOG_SITE_TITLE 站点标题
BLOG_ADMIN_PASSWORD 管理员密码;未设置则首次启动随机生成并打印
BLOG_SECRET_KEY Session 签名密钥;未设置则自动生成并持久化
BLOG_ICP_TEXT 页脚备案文案
BLOG_ICP_URL 备案查询链接

更多能力(KaTeX、目录树、排序方式等)见 README 的「功能一览」。

对你来说,它可能意味着什么

这里没有对错,只有匹配与否:

  • 若你需要:个人站点、一份「愿意读完」的后端示例、在一个文件里看清 FastAPI / SQLite / Jinja2 怎样拼在一起——它大概率够用。
  • 若你指望:多作者协作、复杂权限、插件生态、重度运营与 SEO 工具箱——那不是它的赛道;勉强对齐只会双方都累。

另外:仓库目前没有自动化测试套件,也没有配套 lint,谈不上工业级的回归矩阵。维护侧会用 Cursor 跑一轮简易功能测试:启动服务、点一遍后台与前台的关键链路,确认基础能力未被明显打断——相当于冒烟,而不是替代测试工程。

稳定性仍然离不开你自己环境与负载下的验证;高流量、严合规的生产形态,需要你再做架构与运维上的加固——这是实情,不是套话。

在腾讯云上部署(极简提示)

在腾讯云 CVM 或轻量应用服务器上,常见做法是本机运行 python blog.py,前面用 Nginx 反向代理到默认的 127.0.0.1:8765,并配置 HTTPS;备案展示可通过 BLOG_ICP_TEXTBLOG_ICP_URL 注入页脚。完整 Nginx 示例与环境变量说明见 README.md。若域名前有 EdgeOne 或 WAF,宜为 /admin/* 放行,避免后台登录 POST 被拦。


MIT,源码:https://github.com/WHC2006/py-blog.git
它更适合被看成一小块可自行改写的底座:合拍就用,不合拍就换——仅此而已。