# vps.git 工作日志(2026-03-20) > 记录人:晨曦 / Orion > 范围:今天在 `vps.git` 上执行的排查、迁移、升级与清理操作 > 说明:本日志按实际执行顺序整理,便于后续审计、回顾与回滚分析。 --- ## 1. 迁移前探测与现状确认 对 `vps.git` 做了只读探测,确认了原始部署情况: - 宿主机为 Ubuntu 24.04.1 LTS - 原先运行的裸机服务: - `nginx` - `gitea.service` - `keycloak.service` - `mysql.service` - 原始端口/流量结构: - `nginx` 对外提供 80/443 - `gitea` 裸机监听 3000,由 nginx 反代 - `keycloak` 裸机监听 8443,由 nginx 反代 - `mysql` 裸机监听 localhost:3306 - 原始数据位置: - Gitea 配置:`/etc/gitea/app.ini` - Gitea 数据:`/var/lib/gitea` - Keycloak 配置:`/opt/keycloak/conf/keycloak.conf` - Keycloak H2 数据:`/opt/keycloak/data/h2` - MySQL 数据:`/var/lib/mysql` - 原始版本: - Gitea `1.22.4` - Keycloak `26.0.6` - MySQL `8.0.45` 同时确认: - Git over SSH 当前无人使用 - Gitea 与 Keycloak 均通过域名正常对外暴露 - Keycloak 的 `Hangman-Lab` realm 为后续重点保留对象 --- ## 2. 迁移方案设计与落盘 在 workspace 中编写并落盘了以下迁移材料: - `VPS_GIT_DOCKER_MIGRATION_PLAN.md` - `VPS_GIT_DOCKER_COMPOSE_DRAFT.yaml` - `VPS_GIT_DOCKER_ENV_TEMPLATE.env` - `VPS_GIT_DOCKER_MIGRATION_CHECKLIST.md` - `VPS_GIT_DOCKER_MYSQL_INIT_DRAFT.sh` 这些材料覆盖了: - Docker 化目标架构 - compose 草案 - `.env` 模板 - MySQL 初始化逻辑 - 实施顺序与回滚顺序 - 验证点与风险点 --- ## 3. 在 vps.git 上安装 Docker 环境 执行了 Docker 环境准备: - 安装 Docker Engine - 安装 Docker Compose Plugin - 验证 `docker --version` 与 `docker compose version` 然后创建了部署目录: - `/root/git-kc` - `/root/git-kc/backups` - `/root/git-kc/docs` - `/root/git-kc/gitea` - `/root/git-kc/keycloak/import` - `/root/git-kc/mysql/data` - `/root/git-kc/mysql/init` 并把 workspace 里的草案文件同步到 `vps.git`。 --- ## 4. 生成部署配置与准备 Gitea 容器配置 在 `vps.git` 上: - 根据模板生成了 `/root/git-kc/.env` - 为 MySQL root、Gitea DB、Keycloak DB、Keycloak bootstrap admin 生成了随机密码 - 将宿主机 `git` 用户的真实 UID/GID 写入 `.env` 复制并调整了 Gitea 配置: - `/etc/gitea/app.ini` → `/root/git-kc/gitea/app.ini` - 将 Gitea 的数据库地址改为:`mysql:3306` - 将 Gitea DB 密码改为 Docker MySQL 内的新密码 - 明确关闭了第一阶段的 Git over SSH: - `DISABLE_SSH = true` - `START_SSH_SERVER = false` 同时对 compose 做了兼容修正,使 Gitea 尽量贴近旧裸机布局: - `HOME=/home/git` - `GITEA_WORK_DIR=/var/lib/gitea` - `GITEA_CUSTOM=/var/lib/gitea/custom` - 额外挂载 `/home/git:/home/git` - 显式使用宿主机 `git` 用户 UID/GID 运行容器 --- ## 5. 迁移前备份 执行了迁移专用备份: - 备份了 Gitea 配置 - 备份了 nginx 相关站点配置 - 导出了 Gitea MySQL 数据库 `` - 停止旧 Keycloak 后,导出了 Keycloak realm / users 到目录文件 Keycloak 导出文件位于: - `/root/git-kc/keycloak/import/` 同时保留了升级前的 SQL dump 与 compose / env / app.ini 备份。 --- ## 6. 启动 Docker MySQL 并迁移 Gitea 数据库 执行了 MySQL Docker 化: - 启动 Docker MySQL 容器 - 首次启动时通过 `01-init-databases.sh` 自动创建: - `` - `` - `gitea@'%'` - `keycloak@'%'` - 将原始 Gitea 数据库导入 Docker MySQL 导入后核对了核心数据: - users = 8 - repos = 72 - - external_login_user = 7 确认 Gitea 业务主数据迁移成功。 --- ## 7. Keycloak H2 → MySQL 迁移与导入问题修复 ### 7.1 初次导入失败原因 Keycloak 首次导入失败,定位到: - `Hangman-Lab` realm 中存在 JS policy - 报错:`Script upload is disabled` 进一步确认: - 不是整个 `authorizationSettings` 无法导入 - 而是其中 `type = "js"` 的 policy 被新版本 Keycloak 导入路径拒绝 具体涉及的 client: - `gitea` - `iredmail` - `youtrack-dev` 脚本内容实际都是同一段默认放行模板: ```js // by default, grants any permission associated with this policy $evaluation.grant(); ``` ### 7.2 最小修补 经确认后,执行了最小修补方案: - 移除 `gitea` client 的 `authorizationSettings` - 彻底移除已废弃 client: - `iredmail` - `youtrack-dev` - 同时移除它们的残留引用: - client role definitions - service-account 用户 - 相关 client role 映射 修补仅发生在迁移使用的导出文件中: - `/root/git-kc/keycloak/import/Hangman-Lab-realm.json` ### 7.3 导入成功 随后: - 重建 `` - 重新导入 `master` / `Hangman-Lab` / `Dialectic` - 启动 Docker Keycloak 成功 - 确认 discovery 文档正常,issuer 正常 并在导入完成后: - 去掉了 compose 中的一次性 `--import-realm` - 去掉了临时加入的 `KC_FEATURES=scripts` 确保后续 Keycloak 重启不会重复导入。 --- ## 8. Gitea Docker 切换与启动修复 Gitea 初次容器启动失败,原因是: - 容器以 root 身份运行 - Gitea 拒绝以 root 启动 修复措施: - 在 compose 中显式设置: - `user: "${GITEA_UID}:${GITEA_GID}"` 调整后: - Gitea 容器成功启动 - 健康检查正常 - 通过 nginx 暴露的 Gitea 页面可访问 - Gitea 的 OIDC 登录入口可正确跳转至 Keycloak --- ## 9. nginx 切换 保留宿主机 nginx 架构不变,仅修改 Keycloak upstream: - 从:`https://localhost:8443` - 改为:`http://localhost:8080` 操作后: - 执行 `nginx -t` - reload nginx - 验证 `login.hangman-lab.top` discovery 正常 - 验证 `git.hangman-lab.top` 仍正常 --- ## 10. 裸机部署清理 在确认 Docker 版跑通后,删除了旧裸机部署: ### 已删除 - Gitea 裸机: - `gitea.service` - `/usr/local/bin/gitea` - `/etc/gitea` - Keycloak 裸机: - `keycloak.service` - `/etc/default/keycloak` - `/opt/keycloak` - MySQL 裸机: - `mysql.service` - 旧 MySQL 包 - `/var/lib/mysql` - `/etc/mysql` ### 保留 保留了以下正在被 Docker 使用的宿主机路径: - `/var/lib/gitea` - `/home/git` 原因: - 这两者属于 Docker Gitea 当前的 live 挂载目录,不是旧垃圾。 --- ## 11. 升级到最新版本 在 Docker 迁移稳定后,继续升级到了当时的最新版本,并保持固定版本写死: ### Gitea - 从:`1.22.4` - 升级到:`1.25.5` 验证: - 容器健康正常 - 页面访问正常 - OIDC 跳转正常 ### Keycloak - 从:`26.0.6` - 升级到:`26.5.6` Keycloak 升级期间自动执行了数据库 model migration,日志中可见: - `Hangman-Lab` migrated to 26.1.0 / 26.2.0 / 26.3.0 / 26.4.0 / 26.4.3 升级完成后验证: - 容器健康正常 - discovery 正常 - issuer 正常 - Gitea OIDC 跳转正常 升级前备份保存在: - `/root/git-kc/backups/upgrade-2026-03-20-151958/` 包含: - `.sql` - `.sql` - `compose.yaml.bak` - `.env.bak` - `app.ini.bak` --- ## 12. 磁盘清理与空间回收 后续又做了宿主机空间清理: ### journald - 将 `/var/log/journal` 限制到 `300MB` - 实际回收后 journald 占用约 `252.9MB` ### Docker 旧镜像 删除了未使用的旧镜像: - `gitea/gitea:1.22.4` - `quay.io/keycloak/keycloak:26.0.6` ### APT - 按要求保留了 apt 元数据和缓存 - 同时检查了 `apt-get -s autoremove` - 当前无明显可自动移除的孤儿包 --- ## 13. 当前最终状态(截至日志记录时) Docker 正在运行的服务: - `mysql:8.0.45` - `gitea/gitea:1.25.5` - `quay.io/keycloak/keycloak:26.5.6` 验证通过项: - `https://git.hangman-lab.top/` 可访问 - `https://login.hangman-lab.top/` 可访问 - `https://login.hangman-lab.top/realms/Hangman-Lab/.well-known/openid-configuration` 可访问 - Gitea 的 OIDC 登录入口会正确跳转至 Keycloak 当时磁盘空间大致为: - 总盘:`23G` - 已用:`12G` - 可用:`11G` - 使用率:约 `53%` --- ## 14. 本次迁移中对业务配置做过的显式变更 这是后续最需要知道的一部分: 1. **Gitea 第一阶段明确关闭了 Git over SSH** - `DISABLE_SSH = true` - `START_SSH_SERVER = false` 2. **Keycloak 导入时对 `Hangman-Lab` realm 做了最小修补** - 移除了 `gitea` 的 `authorizationSettings` - 删除了已废弃 client: - `iredmail` - `youtrack-dev` - 同时删除了它们关联的 service-account / client role 引用 3. **nginx Keycloak upstream 已改为宿主机本地 HTTP 反代** - `http://localhost:8080` --- ## 15. 后续建议 - 用浏览器人工完成一次 Gitea → Keycloak SSO 登录验收 - 用实际仓库完成一次 HTTPS clone / push 验收 - 如未来要恢复 Git over SSH,再单独设计第二阶段方案 - 如要继续精简磁盘,可再评估 apt 元数据清理,但本次按要求保留 --- ## 结论 今天在 `vps.git` 上完成了: - 裸机 Gitea / Keycloak / MySQL → Docker 迁移 - Keycloak H2 → MySQL 迁移 - Gitea / Keycloak 升级到当时最新版本 - 旧裸机部署清理 - journald 限额与旧镜像清理 当前服务已切换为 Docker 运行,并完成了基础联通验证。