Go 后端 + Vue 3 + Element Plus 前端的个人主页,用来记录项目、文章和最近在读内容。
主页资料、联系方式、最近在读、统计卡片、导航文案和项目文章都由 Go API 从数据库读取;管理员登录后可以在网页里的“内容管理”面板直接修改 JSON 并保存,不需要改代码。
项目文章使用富文本块存储,支持段落、列表、代码块、图片/GIF 和链接卡片。
签到日历、每日 Todo 和每日笔记由 Go API 写入数据库;访客只能查看,管理员登录后才能维护 Todo、完成任务、签到和编辑笔记。未配置 DATABASE_URL 时使用本地 SQLite,配置后会写入 Supabase Postgres。
每日 Todo 全部完成后才会解锁当天签到;已经存在的历史签到不会因为新增 Todo 规则失效。
启动后端 API:
go run ./cmd/server默认数据库路径是 data/homepage.db,也可以手动指定:
go run ./cmd/server -db data/homepage.db文章内容目录也可以手动指定:
go run ./cmd/server -content content/articles开启管理员写入能力需要设置环境变量:
$env:ADMIN_USERNAME = "admin"
$env:ADMIN_PASSWORD = "你的管理员密码"
$env:SESSION_SECRET = "一段足够长的随机字符串"
go run ./cmd/server也可以在本地创建 tmp/supabase.env,后端启动时会自动读取。tmp/ 已被 git 忽略,不会提交:
DATABASE_URL=postgresql://postgres.<project-ref>:<database-password>@<pooler-host>:5432/postgres?sslmode=require
ADMIN_USERNAME=admin
ADMIN_PASSWORD=你的管理员密码
SESSION_SECRET=一段足够长的随机字符串也可以不放明文密码,改用 SHA-256:
$env:ADMIN_USERNAME = "admin"
$env:ADMIN_PASSWORD_SHA256 = "<管理员密码的 sha256 hex>"
$env:SESSION_SECRET = "一段足够长的随机字符串"
go run ./cmd/server启动后端并登录管理员后,右侧签到卡片会出现“内容管理”按钮。
内容管理面板分两块:
Profile JSON:主页个人资料、联系方式、在线作品、最近在读、统计卡片、标签标题和按钮文案。Articles JSON:所有项目文章。每篇文章包含slug、category、date、title、excerpt、tags和blocks。
保存后内容会写入数据库的 site_content 表。线上配置 DATABASE_URL 后会写入 Supabase Postgres,本地未配置时写入 data/homepage.db。
新增项目时,在 content/articles 里新增一个 .json 文件即可。文件名建议带排序前缀,例如:
content/articles/
001-remote-sensing-data-workflow-platform.json
002-your-next-project.json
文章字段示例:
{
"slug": "your-next-project",
"category": "项目",
"date": "2026-06-04",
"title": "你的项目标题",
"excerpt": "一句话说明项目解决的问题。",
"tags": ["Go", "Vue", "SQLite"],
"blocks": [
{ "type": "heading", "level": 2, "text": "项目定位" },
{ "type": "paragraph", "text": "这里写项目正文。" },
{ "type": "code", "language": "go", "filename": "main.go", "code": "package main" }
]
}这些文件只作为首次初始化数据库的默认内容。数据库里已经存在 site_content 后,后端会优先使用数据库内容,避免你在线上管理面板改过的文章被代码文件覆盖。
启动前端开发服务:
cd frontend
npm install
npm run dev生产构建:
cd frontend
npm run build
cd ..
go run ./cmd/server构建后,Go 服务会自动托管 frontend/dist。
当前 GitHub Pages 地址是静态前端,不能直接运行 Go 服务或写 SQLite。线上要让签到、每日 Todo 和每日笔记真正可用,需要拆成两部分:
- GitHub Pages:继续托管
frontend/dist。 - Go API:部署到支持后端服务的平台,例如 Render、Railway、Fly.io 或自己的 VPS。签到和 Todo 数据建议接 Supabase Postgres。
前端会读取 VITE_API_BASE_URL。例如 Go API 部署到:
https://personal-webside-api.onrender.com
就在 GitHub 仓库的 Settings -> Secrets and variables -> Actions -> Variables 里添加:
VITE_API_BASE_URL=https://personal-webside-api.onrender.com
然后重新运行 Deploy Pages 工作流,线上 Pages 就会把 /api/profile、/api/articles、/api/admin/content、/api/checkins、/api/todos/today、/api/admin/login、/api/admin/checkins/{date}、/api/admin/todos/* 请求发到这个 Go API。
后端服务至少需要这些环境变量:
ADMIN_USERNAME=admin
ADMIN_PASSWORD=<管理员密码>
SESSION_SECRET=<一段足够长的随机字符串>
DATABASE_URL=postgresql://postgres.<project-ref>:<database-password>@<pooler-host>:5432/postgres?sslmode=require
DB_PATH=/app/data/homepage.db
CONTENT_DIR=/app/content/articles
CORS_ALLOWED_ORIGINS=https://iqboshi.github.io
DATABASE_URL 用来保存主页内容、项目文章、签到、每日 Todo 和每日笔记。未配置时会使用本地 SQLite,所以如果使用 Dockerfile 部署且不接 Supabase,建议把持久盘挂载到 /app/data,这样 homepage.db 才不会在重启或重新部署后丢失。
Supabase 的建表 SQL 在 supabase/checkins.sql。后端启动时也会自动创建这些表。
仓库根目录已经包含 render.yaml,可以直接用 Render Blueprint 部署 Go API:
- 进入 Render Dashboard。
- 选择
New -> Blueprint。 - 绑定 GitHub 仓库
iqboshi/personal-webside。 - Render 会读取
render.yaml并创建personal-webside-api。 - 按提示填写这些环境变量:
DATABASE_URL=<Supabase Postgres 连接串>
ADMIN_USERNAME=<管理员账号>
ADMIN_PASSWORD=<管理员密码>
SESSION_SECRET 会由 Render 自动生成。部署完成后会得到一个类似这样的 API 地址:
https://personal-webside-api.onrender.com
然后到 GitHub 仓库:
Settings -> Secrets and variables -> Actions -> Variables
添加或更新:
VITE_API_BASE_URL=https://personal-webside-api.onrender.com
最后重新运行 Deploy Pages 工作流,GitHub Pages 上的签到日历就会请求这个线上 Go API。
Render 免费 Web Service 空闲 15 分钟后会休眠,第一次访问可能需要等待一会儿。因为签到数据写在 Supabase,所以休眠和重启不会丢数据。
本地 Docker 运行示例:
docker build -t personal-webside-api .
docker run --rm -p 8080:8080 `
-e ADMIN_USERNAME=admin `
-e ADMIN_PASSWORD=your-password `
-e SESSION_SECRET=replace-with-long-random-secret `
-e CORS_ALLOWED_ORIGINS=http://127.0.0.1:5173,https://iqboshi.github.io `
-v ${PWD}/data:/app/data `
personal-webside-api