补充说明
本教程介绍 StudyBuddy 从源码编译、发布 GitHub Release 到目标服务器一键安装、卸载、升级的完整流程,适用于个人设备学习刷题环境自建发布链路。
项目:StudyBuddy|小学生刷题自测系统 仓库:https://github.com/meimolihan/StudyBuddy 编译发布主机:fnOS(Debian,本机 Go 环境齐全) 部署测试主机:Debian Linux(amd64/arm64)
重要规则
- GitHub 不允许直接覆盖已发布 Release,正式环境版本号单向递增;内测可删除重建同名 tag(本项目 tag 带
v前缀,如v0.0.1)。- install.sh 使用
releases/latest/download,脚本不需要硬编码版本号。- 编译机器 ≠ 业务运行机器;fnOS 只做编译发布,业务跑在目标主机。
- 正式二进制统一
CGO_ENABLED=0纯静态构建(纯 Go + SQLite 纯 Go 驱动,无任何 C 依赖),版本号经-ldflags "-X main.version=..."注入cmd/studybuddy/main.go。- 推送 tag 后 GitHub Actions(
.github/workflows/release.yml)自动完成:交叉编译 → 发布 Release → Docker 双仓库(Docker Hub + GHCR)→ CNB 同步。
一、编译发布机(fnOS)环境准备
1.1 安装依赖
apt update
apt install git curl build-essential
Go(≥1.21,本机 /usr/local/go/bin/go,确保 go version 正常)。无需 Node.js / ffmpeg——模板与静态资源通过 go:embed 内嵌,教材内容树 content/ 直接随产物分发。
1.2 安装 gh 命令行工具并授权 GitHub
gh auth login
选择 GitHub.com → SSH → 网页授权登录,务必勾选 repo 权限。
校验授权结果
gh auth status
输出必须包含:Token scopes: admin:public_key, gist, read:org, repo
1.3 拉取源码
git clone git@github.com:meimolihan/StudyBuddy.git
cd StudyBuddy
go mod download
项目目录结构
StudyBuddy/
├── cmd/studybuddy/ # 后端唯一入口(内嵌 Web 界面)
├── internal/ # config/auth/db/textbook/quiz/web 等包
├── scripts/install.sh # 远程一键安装脚本
├── scripts/uninstall.sh # 卸载脚本
├── scripts/studybuddy_backup.sh # 备份脚本
├── scripts/studybuddy_recover.sh # 恢复脚本
├── scripts/build-and-push.sh # 构建+打tag+推送脚本
├── tools/ # smoke/e2e/bankcheck 自检工具
├── content/ # 教材题库内容树(路径即元数据)
├── wallpapers/ # 背景壁纸(与 content 树同构)
└── deploy/Dockerfile # 多阶段构建(golang:1.23-alpine → alpine:3.19)
二、配置一键安装脚本
确认 scripts/install.sh 头部常量(无需改动,默认已正确定义):
APP_NAME="studybuddy" # 服务名 / CLI 命令名(小写)
DEFAULT_PORT=8080
APP_DIR="/var/lib/StudyBuddy" # 默认安装目录(二进制/教材/数据均在其下)
CONFIG_FILE="/etc/studybuddy.conf"
提交推送至 main 分支
git add scripts/install.sh
git commit -m "chore: update install script"
git push origin main
三、构建与发布
3.1 本地快速编译
go build -ldflags "-s -w" -o dist/studybuddy.exe ./cmd/studybuddy # Windows 本机调试
go vet ./... && go run ./tools/smoke # 提交前自检
3.2 一键发布(推荐)
./scripts/build-and-push.sh v0.0.2 --yes -m "发布说明"
内部流程:CNB 仓库自动创建(可选,需 CNB_ACCESS_TOKEN)→ tag 格式校验(v 前缀)→ 删除同名 Release/tag → 写入根目录 VERSION 文件 → 生成 RELEASE_NOTES.md(docker pull 与远程安装命令)→ git commit + 打 tag → push main + push tag → 打印 Actions 网页链接。
3.3 交叉编译 Release 静态二进制(供 install.sh 远程下载)
export VERSION=v0.0.2
rm -rf dist && mkdir -p dist
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w -X main.version=${VERSION}" -o dist/studybuddy_linux_amd64 ./cmd/studybuddy
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "-s -w -X main.version=${VERSION}" -o dist/studybuddy_linux_arm64 ./cmd/studybuddy
ls dist
纯静态二进制,无任何外部运行时依赖;
/usr/local/bin/studybuddy version可验证版本注入是否生效。
3.4 创建 GitHub Release 并上传二进制(手动模式)
VERSION=v0.0.2
gh release create "${VERSION}" \
dist/studybuddy_linux_amd64 \
dist/studybuddy_linux_arm64 \
--title "StudyBuddy ${VERSION}" \
--notes "StudyBuddy - 刷题自测系统"
推荐直接 git push origin v0.0.2,由 GitHub Actions 自动产出 Release 与 Docker 镜像。
校验 Release
访问:https://github.com/meimolihan/StudyBuddy/releases/tag/v0.0.2
- 状态:Published,不是 Draft 草稿
- Assets 内必须存在两个编译二进制,不要只看源码 zip/tar.gz。
测试下载链接有效性
curl -I https://github.com/meimolihan/StudyBuddy/releases/latest/download/studybuddy_linux_amd64
返回 302 Found 正常;返回 404 代表附件缺失。
四、目标服务器远程一键安装
目标服务器需要 root 权限,已安装 curl。
4.1 预检查国内网络
curl -sSL https://raw.githubusercontent.com/meimolihan/StudyBuddy/main/scripts/install.sh
输出 shell 脚本内容 = 网络正常;卡住超时需要网络代理,或使用镜像仓库
STUDYBUDDY_REPO=https://ghfast.top/https://github.com/meimolihan/StudyBuddy.git。
4.2 执行一键安装
bash -c "$(curl -sSL https://raw.githubusercontent.com/meimolihan/StudyBuddy/main/scripts/install.sh)"
交互步骤:
- 提示输入监听端口,回车使用默认
8080,或填写自定义端口 - 提示输入安装目录,回车使用默认
/var/lib/StudyBuddy - 脚本自动下载二进制(ELF 魔数 +
version双重自检)与 content 教材包、创建 systemd 服务、启动程序 - 输出 Web 访问地址;浏览器打开后注册首位账号即自动成为管理员(无默认账号密码)
标准静默安装(固定约定)
bash scripts/install.sh -p 9060 -d /var/lib/StudyBuddy -y
远程静默安装
bash -c "$(curl -sSL https://raw.githubusercontent.com/meimolihan/StudyBuddy/main/scripts/install.sh)" -p 9060 -d /var/lib/StudyBuddy -y
部署后运维命令
systemctl status studybuddy
journalctl -u studybuddy -f
systemctl restart studybuddy
/usr/local/bin/studybuddy version
/usr/local/bin/studybuddy help # CLI 全命令表
访问示例:http://10.10.10.251:9060
- 账号:浏览器打开后注册首位账号,自动成为管理员
- 后续账号:管理员在管理页生成邀请码后注册,默认「学生」角色(设置面板不显示账号区块)
五、一键卸载
bash -c "$(curl -sSL https://raw.githubusercontent.com/meimolihan/StudyBuddy/main/scripts/uninstall.sh)"
交互:
数据目录处理:--purge全部删除 /--keep-data保留数据 / 交互询问
卸载完成:systemd 服务移除、/usr/local/bin/studybuddy 包装删除、程序文件删除。
六、新版本发布两种模式
模式 1:递增新版本(正式环境,推荐)
不要复用旧 tag,版本号向上迭代,例如 v0.0.2 → v0.0.3
cd /vol1/1000/GitHub/StudyBuddy
./scripts/build-and-push.sh v0.0.3 --yes -m "v0.0.3"
目标服务器升级,直接重跑安装脚本,自动拉取 latest,覆盖程序与教材并重启服务,数据目录保留
bash -c "$(curl -sSL https://raw.githubusercontent.com/meimolihan/StudyBuddy/main/scripts/install.sh)" -p 9060 -d /var/lib/StudyBuddy -y
/usr/local/bin/studybuddy version
模式 2:删除重建同名 Release(仅限内测,无线上用户)
⚠️ 已有服务器依赖该版本绝对禁止执行,会造成旧版本下载 404。
cd /vol1/1000/GitHub/StudyBuddy
# 删除github release
gh release delete v0.0.2 --yes
# 删除本地与远端git tag
git tag -d v0.0.2
git push origin --delete v0.0.2
# 重新编译并重建release上传附件
export VERSION=v0.0.2
rm -rf dist && mkdir -p dist
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w -X main.version=${VERSION}" -o dist/studybuddy_linux_amd64 ./cmd/studybuddy
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "-s -w -X main.version=${VERSION}" -o dist/studybuddy_linux_arm64 ./cmd/studybuddy
gh release create "${VERSION}" \
dist/studybuddy_linux_amd64 \
dist/studybuddy_linux_arm64 \
--title "StudyBuddy ${VERSION}" \
--notes "更新说明"
七、故障排查表
| 现象 | 排查方案 |
|---|---|
| gh release create 返回 401 Unauthorized | 执行 gh auth login 重新授权,确保 token 具备 repo 权限 |
| 下载二进制返回 404 | 检查 Release 是否 Published,Assets 文件名严格匹配 install.sh |
| 安装时报「二进制校验失败」 | 下载不完整(ELF 魔数/版本自检/content-length 三重校验兜底),重跑安装脚本 |
| raw.githubusercontent.com 卡住超时 | 国内网络限制,配置代理,或 STUDYBUDDY_REPO 指向镜像仓库中转 |
| 服务启动失败 | journalctl -u studybuddy -n 100 查看日志;检查端口占用、目录权限 |
| 编译报错缺失依赖 | 项目目录执行 go mod download;Go 版本须 ≥1.21 |
| 页面课程数为 0 | content 树只在启动时扫描一次,补充教材后需 systemctl restart studybuddy |
| Actions 镜像 Job 失败 | 检查仓库 Secrets:DOCKERHUB_USERNAME/DOCKERHUB_TOKEN/CNB_ACCESS_TOKEN |
| GHCR 镜像拉取 404 | GHCR 标签强制小写,使用 ghcr.io/meimolihan/studybuddy(小写 s) |
八、前端 UI 修改流程
前端为 Go 模板 + CSS/JS(internal/web/templates/ + internal/web/static/),通过 go:embed 内嵌进二进制,无独立前端构建步骤:
- 修改模板或样式(样式统一在
style.css末尾追加段,暗色补丁 A/B 双写) - 重新编译:
go build -ldflags "-s -w" -o dist/studybuddy ./cmd/studybuddy - 重新走发布流程:提交代码 → build-and-push → 触发 Actions
- 目标服务器重跑一键安装脚本升级生效。
教材内容(content/ 目录树)与壁纸(wallpapers/)修改免编译,替换文件后重启服务即可。
九、极简速查复制块
发布新版本速记
cd /vol1/1000/GitHub/StudyBuddy
./scripts/build-and-push.sh v0.0.3 --yes -m "v0.0.3" # 或分步:
# git add . && git commit -m "release v0.0.3"
# git push origin main && git push origin v0.0.3 # 推 tag 触发 Actions 自动发布
export VERSION=v0.0.3
rm -rf dist && mkdir -p dist
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w -X main.version=${VERSION}" -o dist/studybuddy_linux_amd64 ./cmd/studybuddy
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "-s -w -X main.version=${VERSION}" -o dist/studybuddy_linux_arm64 ./cmd/studybuddy
gh release create "${VERSION}" dist/studybuddy_linux_amd64 dist/studybuddy_linux_arm64 --title "StudyBuddy ${VERSION}" --notes "更新说明"