修复 README 里的 Markdown 格式错误
初始提交:sourcehut Docker Compose 自托管部署
基于 Docker Compose 的 sourcehut 自托管部署,运行于 *.cytrogen.icu。
┌─────────────────────────────────────────┐
│ Docker Compose 网络 │
│ │
:22222 ──────────►│ ┌─────┐ ┌──────┐ ┌──────┐ │
(SSH git push) │ │ git │──►│ │ │ │ │
│ └─────┘ │ │ │ │ │
:5001 ───────────►│ ┌──────┐ │ post │ │ │ │
(meta web) │ │ meta │──►│ gres │ │redis │ │
│ └──────┘ │ │ │ │ │
:5002 ───────────►│ ┌─────┐ │ │ │ │ │
(hub web) │ │ hub │──►│ │ │ │ │
│ └─────┘ │ │ │ │ │
:5003 ───────────►│ ┌──────┐ │ │ │ │ │
(git web) │ │ │──►│ │──►│ │ │
│ └──────┘ └──────┘ └──────┘ │
:5004 ───────────►│ ┌──────┐ │
(todo web) │ │ todo │──►postgres + redis │
│ └──────┘ │
└─────────────────────────────────────────┘
6 个服务:
postgres — PostgreSQL 16 (Alpine),4 个数据库(meta/git/todo/hub)
redis — Redis 7 (Alpine),48MB 内存限制
meta — 用户认证与账户管理 (meta.cytrogen.icu)
git — Git 仓库托管 + SSH (git.cytrogen.icu)
todo — 工单/Issue 跟踪 (todo.cytrogen.icu)
hub — 项目聚合门户 (hub.cytrogen.icu)
所有 Web 服务绑定 127.0.0.1,通过前端反向代理(Caddy/nginx)对外提供 HTTPS。仅 git SSH 端口 (22222) 对外开放。
本部署基于 k8ieone 的 sourcehut Docker 镜像,但这些镜像存在若干问题需要修复。以下是每个定制目录的修改说明。
meta-custom/| 修改 | 原因 |
|---|---|
Jinja2 {% do %} 扩展修复 |
上游 core.sr.ht 已合并修复(patch 39036)但 k8ieone 镜像未包含 |
templates/ — 模板汉化 |
将 meta.sr.ht 全部用户界面翻译为中文 |
base-templates/ — 基础模板汉化 |
汉化导航栏、错误页面等公共模板 |
git-custom/| 修改 | 原因 |
|---|---|
| 安装 openssh-server | 镜像不含 SSH 服务器,无法 git push |
| SSH key dispatch 配置 | 配置 sshd 使用 gitsrht-dispatch 进行公钥认证 |
| 安装 pgpy | git.sr.ht 运行时依赖,镜像缺失 |
| libgit2 属主修复 | gunicorn 以 root 运行但 SSH 推送创建的仓库属于 git 用户,libgit2 (pygit2) 拒绝 root 读取非 root 仓库。启动时对仓库顶层目录 chown root:git 解决 |
Jinja2 {% do %} 修复 |
同 meta-custom |
hub-custom/| 修改 | 原因 |
|---|---|
| 安装 pgpy | hub.sr.ht 运行时依赖,镜像缺失 |
Jinja2 {% do %} 修复 |
同 meta-custom |
todo-custom/todo.sr.ht 是最复杂的定制——k8ieone 不提供预构建的 todo 镜像,需要从源码完整构建。
| 修改 | 原因 |
|---|---|
| 多阶段 Dockerfile(从源码构建) | k8ieone 无 todo.sr.ht 预构建镜像,使用 sr.ht-apkbuilds 从源码编译 |
compat_oauth.py — OAuth API 兼容层 |
core.sr.ht 0.78.6 重命名了 OAuth API(AbstractOAuthService → OAuthService、DelegatedScope → OAuthScope、SrhtFlask 不再接受 oauth_service=),而 todo.sr.ht 0.77.5 仍使用旧 API |
| kombu 版本升级 | Celery 5.5.3 要求 kombu>=5.4,但 Alpine 3.20 仅提供 5.3.7 |
Jinja2 {% do %} 修复 |
同 meta-custom |
nginx.conf + start.sh |
容器入口:启动 gunicorn (web)、GraphQL API、Celery worker、nginx 反代 |
fix_jinja2_do.py (4 份副本,各服务目录各一份):运行时修补 srht/flask.py,在 ChoiceLoader 之后添加 jinja2.ext.do 扩展。上游已修复但 k8ieone 镜像未包含此修复。compat_oauth.py (仅 todo-custom/):为 core.sr.ht 0.78.6 + todo.sr.ht 0.77.5 版本差异添加兼容层。# 1. 克隆仓库
git clone ssh://git@git.cytrogen.icu:22222/~cytrogen/srht-deploy
cd srht-deploy
# 2. 创建配置文件
cp .env.example .env
cp config/config.ini.example config/config.ini
# 3. 编辑配置
# - .env: 设置 PostgreSQL root 密码
# - config/config.ini: 修改下方「配置说明」中列出的字段
vi .env
vi config/config.ini
# 4. 生成密钥(需要在 meta 容器内执行)
# 先启动 meta 服务以获取 srht-keygen 工具
docker compose up -d meta
docker compose exec meta srht-keygen service # → service-key
docker compose exec meta srht-keygen network # → network-key
docker compose exec meta srht-keygen webhook # → webhooks private-key
# 将生成的密钥填入 config/config.ini
# 5. 将 init-databases.sh 放入 postgres 初始化目录
mkdir -p postgres_sh
cp init-databases.sh postgres_sh/
# 6. 启动所有服务
docker compose up -d
# 7. 创建管理员账户
docker compose exec meta metasrht-manageuser -t admin -e YOUR_EMAIL USERNAME
config/config.ini.example 中需要修改的关键字段:
| 字段 | 说明 |
|---|---|
[sr.ht] service-key |
会话加密密钥,用 srht-keygen service 生成 |
[sr.ht] network-key |
内部通信密钥,用 srht-keygen network 生成 |
[mail] smtp-password |
SMTP 发信密码 |
[webhooks] private-key |
Webhook 签名密钥,用 srht-keygen webhook 生成 |
[*.sr.ht] oauth-client-id/secret |
各服务的 OAuth 凭据,在 meta 注册后获取 |
[mail] pgp-key-id |
PGP 签名邮件的密钥 ID(可选) |
数据库连接字符串和 Redis 地址使用 Docker 服务名(postgres、redis),无需修改。