Redmine与Gitolite环境下的Git版本库镜像集成方案
架构设计与解决思路
在将Redmine与基于Gitolite管理的Git服务器进行集成时,通常会面临文件系统权限隔离的挑战。Redmine的内置Git适配器要求Web服务器进程(如www-data或nginx)对Git仓库目录具有读取权限。然而,直接修改Gitolite托管仓库的权限或在Redmine目录下重新初始化仓库,都会破坏现有的权限模型或导致开发流程割裂。
为了解决这一冲突,最优雅的实践是引入镜像仓库(Mirror Repository)机制。我们在Redmine所在服务器本地创建一个仅供读取的裸镜像仓库,并通过原仓库的Git Hooks(钩子)在每次代码推送后自动触发同步。这样既保证了Gitolite权限体系的完整性,又满足了Redmine的读取需求。
步骤一:配置Gitolite访问授权
首先,需要为运行Redmine的Web服务用户生成SSH密钥,并将其注册到Gitolite的管理库中,使其具备目标仓库的只读权限。
切换到Web服务用户(此处以web_user为例)并生成Ed25519密钥对:
sudo -u web_user ssh-keygen -t ed25519 -C "redmine_sync" -f /var/www/.ssh/id_ed25519 -N ""
将生成的公钥复制到Gitolite管理仓库的密钥目录中,并提交更改:
sudo cp /var/www/.ssh/id_ed25519.pub /opt/gitolite-admin/keydir/redmine_reader.pub
cd /opt/gitolite-admin
sudo vim conf/gitolite.conf
在gitolite.conf中为redmine_reader分配目标仓库的读取权限:
repo core_project
RW+ = git_admin
R = redmine_reader
提交并推送配置以使权限生效。
步骤二:初始化本地镜像仓库
在Redmine的数据存储目录下,使用Web服务用户身份克隆一个镜像仓库。镜像仓库会同步所有的引用(refs)和分支,非常适合用于只读展示。
sudo mkdir -p /var/www/redmine/data/git_mirrors
sudo chown web_user:web_user /var/www/redmine/data/git_mirrors
sudo -u web_user git clone --mirror git_admin@git-server:core_project.git /var/www/redmine/data/git_mirrors/core_project.git
如果在此阶段遇到Permission denied或fatal: Could not read from remote repository错误,请返回步骤一检查SSH密钥配置及Gitolite权限分配是否正确。
步骤三:实现基于Hooks的自动同步
为了让Redmine能够实时获取最新的提交记录,需要在Gitolite托管的原始仓库中配置post-receive钩子。当开发者推送代码后,钩子会自动将更新推送到Redmine的本地镜像库。
切换到Git管理用户,进入原始仓库的hooks目录:
sudo -u git_admin cd /opt/gitolite/repositories/core_project.git/hooks
sudo -u git_admin cp post-receive.sample post-receive
sudo -u git_admin vim post-receive
在脚本中追加以下同步逻辑:
#!/bin/bash
# 定义Redmine镜像仓库的本地绝对路径
MIRROR_PATH="/var/www/redmine/data/git_mirrors/core_project.git"
# 将当前接收到的所有引用推送到镜像库
git push --mirror "$MIRROR_PATH"
确保该钩子脚本具有可执行权限:
sudo -u git_admin chmod +x post-receive
步骤四:调整文件系统与用户组权限
由于镜像仓库由Web用户创建,而更新操作由Git管理用户通过Hook触发,因此需要确保这两个用户对镜像目录具有协同访问权限。
配置Git仓库的共享权限模型,并将Git管理用户加入Web服务用户的用户组:
sudo -u web_user git -C /var/www/redmine/data/git_mirrors/core_project.git config core.sharedRepository group
sudo usermod -aG web_user git_admin
修正镜像目录的所属组及读写权限,确保Hook执行时不会因权限不足而失败:
sudo chgrp -R web_user /var/www/redmine/data/git_mirrors/core_project.git
sudo chmod -R g+rwX /var/www/redmine/data/git_mirrors/core_project.git
步骤五:Redmine后台配置与验证
登录Redmine管理后台,进入目标项目的"设置" -> "版本库"页面。新建一个Git类型的版本库,在"路径"字段中填入镜像仓库的绝对路径(例如:/var/www/redmine/data/git_mirrors/core_project.git)。
保存配置后,切换到"版本库"标签页,确认提交历史和文件树能够正常加载。最后,在本地开发环境中向原始仓库推送一次测试提交,刷新Redmine页面,验证镜像同步机制是否按预期工作。