# sourcehut 自托管部署 基于 Docker Compose 的 [sourcehut](https://sr.ht) 自托管部署,运行于 `*.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 镜像](https://github.com/k8ieone/sourcehut-docker),但这些镜像存在若干问题需要修复。以下是每个定制目录的修改说明。 ### `meta-custom/` | 修改 | 原因 | |------|------| | Jinja2 `{% do %}` 扩展修复 | 上游 core.sr.ht 已合并修复([patch 39036](https://lists.sr.ht/~sircmpwn/sr.ht-dev/patches/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](https://git.sr.ht/~sircmpwn/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 版本差异添加兼容层。 ## 快速开始 ```bash # 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`),无需修改。 ## 上游参考 - [k8ieone/sourcehut-docker](https://github.com/k8ieone/sourcehut-docker) — 本部署使用的 Docker 基础镜像 - [sr.ht-apkbuilds](https://git.sr.ht/~sircmpwn/sr.ht-apkbuilds) — Alpine 打包脚本(todo.sr.ht 从此构建) - [Jinja2 do 扩展修复](https://lists.sr.ht/~sircmpwn/sr.ht-dev/patches/39036) — 上游补丁 - [sourcehut 官方文档](https://man.sr.ht/installation.md) — 安装参考