用 Django + Tailwind CSS + HTMX 搭建个人站点

为什么选 Django 而不是 Next.js

说实话最初也考虑过 Next.js,但个人站点需要的是:服务端渲染、零 JS 框架开销、SQLite 即走即用、后台管理开箱即用。Django 5 的异步视图已经够快,模板引擎渲染纯 HTML 的速度远超任何 SSR 框架。加上 Django Admin 可以直接管理内容,省掉了写后台的时间。

Python 生态也是关键。uv 做包管理,gunicorn 做 WSGI 服务器,部署链路简洁。

项目结构

nexus/
├── nexus_core/         # 首页、笔记、动态
├── blog/               # 笔记系统
├── links/              # 链接聚合
├── monitor/            # 服务器监控
├── music/              # 音乐播放器
├── templates/          # 模板(继承 base.html)
├── static/css/         # 全局 + 页面专属样式
├── static/js/          # 全局 + 页面专属逻辑
└── config/             # Django 配置

每个 app 职责单一,模板用 {% extends "base.html" %} 继承。

HTMX:不写一行 JS 的交互

HTMX 让我用 HTML 属性声明交互行为:

<button hx-get="/notes/load-more/"
        hx-target="#notes-list"
        hx-swap="beforeend">
  加载更多
</button>

Django 视图直接返回 HTML 片段,HTMX 负责插入 DOM。不需要 API 端点,不需要 JSON 序列化。笔记搜索、标签筛选、音乐播放器的歌词同步,全都用 HTMX 搞定。

Tailwind CSS:暗色主题快速开发

Tailwind 的 utility class 让我在一个 HTML 文件里完成所有样式。首页 Bento Grid 用 grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) 实现响应式卡片布局。暗色主题用 bg-gray-950 打底,indigo 色系做点缀。

部署:frp + Nginx 反向代理

服务器在 solar(家里),没有公网 IP,用 frp 做内网穿透:

# frpc.toml
serverAddr = "公网服务器IP"
serverPort = 7000

[[proxies]]
name = "nexus-web"
type = "http"
localPort = 8000
customDomains = ["felixfeng.online"]

Nginx 在阿里云上做反向代理,处理 SSL、gzip 和静态文件:

server {
    listen 443 ssl;
    server_name felixfeng.online;

    location /static/ {
        alias /path/to/staticfiles/;
    }

    location / {
        proxy_pass http://127.0.0.1:9000;
        proxy_set_header Host $host;
    }
}

gunicorn 以 4 worker 进程运行 Django,SQLite 单文件数据库扛个人流量绰绰有余。

总结

Django + HTMX + Tailwind 的组合,用最少的代码量实现了完整的个人站点。没有构建步骤的焦虑,没有 node_modules 的黑洞,没有状态管理的心智负担。对个人项目而言,简单就是最好的架构。