☰
Redmine 5.1.4 接入 Git 仓库与 Additionals 插件完整部署指南
2026/10/10 6:54:39 网站建设 项目流程

Redmine 5.1.4 这个版本,我前后给几个项目环境都部署过,每次都会被同一个问题卡一下:代码仓库到底怎么跟项目管理串起来。很多团队把 Redmine 只当成任务看板来用,研发在 Git 里提交代码,Redmine 里完全看不到痕迹,评审的时候还要跑到 Git 平台上去翻 commit,来回切换效率很低。这篇文章我按实际安装顺序,把 Redmine 5.1.4 里接入 Git 仓库、以及安装 Additionals 插件的完整过程写下来,包括内置 Git 模块的配置、Additionals 的依赖与迁移、以及进阶路线里 SSH 认证失败的排查思路,适合负责 Redmine 维护的运维同学参考,也适合刚接手项目管理系统、想把代码和任务打通的团队技术负责人照着操作。

1. 先盘清楚:Redmine 的 Git 支持有哪些档次,Additionals 又是干什么的

1.1 集成 Git 的三条路线,别一上来就选最重的

Redmine 5.1.4 本身不是一个空白系统,它核心代码里已经内置了版本库(Repository)模块,天然支持 Git。很多朋友第一次接触时会被"Git 插件"这个说法带偏,以为必须装额外的插件才能用 Git,实际上不是这样。从集成深度来看,主要有三条路:

  • 内置 Git 模块:Redmine 自带功能,只要服务器上装了 Git 命令行工具,然后在项目设置里填一个 Git 裸仓库的路径,就可以浏览代码、看提交历史、做版本对比。这是最轻量、最稳定、兼容性最好的方式。
  • 第三方 Git 托管插件(redmine_git_hosting):这类插件不仅让 Redmine 能读取 Git 仓库,还能直接在 Redmine 里创建仓库、管理系统用户、管理 SSH 公钥,相当于把 Redmine 变成了一个轻量级 Git 托管平台。功能强,但安装配置复杂度明显上升,还会改变仓库的存储方式,迁移成本高。
  • 对接外部 Git 平台(Gitea、GitLab、Bitbucket):通过插件或 API 把外部平台的仓库同步到 Redmine 显示。适合已经有正式代码托管平台的团队,但引入的依赖比较多,一般企业环境用不上。

我这次安装采用"内置模块为主、redmine_git_hosting 作为进阶方案"的组合。为什么这么选?因为生产环境最重要的是稳定可复现。内置模块是 Redmine 核心团队维护的,升级时不容易出兼容性问题;而 redmine_git_hosting 这类第三方插件虽然好用,但它的底层依赖(SSH、OpenSSH 配置、多用户权限)一旦和服务器既有配置冲突,排查起来非常费时间。如果你的团队连 Git 服务器都还没有,那就另说,后面我会单独写清楚什么时候必须上托管插件。

1.2 Additionals 解决的是"默认功能不够顺手"这一类问题

Additionals 是一个综合性的 Redmine 增强插件,不属于版本库范畴,但它几乎是 Redmine 装上之后用的最频繁的扩展之一。它解决的问题很琐碎,但都很真实:比如项目列表想加收藏功能、页面标题想显示文档名而不是文件路径、Wiki 里想插入到期日期提醒和倒计时、帮助菜单想自定义成团队自己的规范——这些都是 Redmine 默认不提供、又确实影响日常使用体验的小需求。Additionals 把这类零散增强集中到一个插件里,避免为了一个小功能装一堆插件导致依赖打架。

安装 Additionals 本身不算复杂,但有一个很容易被忽略的点:它的版本必须和 Redmine 5.1.4 匹配。Additionals 的 GitHub 仓库 README 里有一张版本兼容矩阵表,4.x 系列对应 Redmine 5.x。装之前如果不看这个,直接 clone 最新分支,很可能在bundle install阶段就报 gem 依赖错误。

1.3 本次安装路线图

为了让你对后面的步骤有个整体概念,我先用一张表把安装主线列出来:

阶段操作对象预期结果
环境检查Redmine 实例、Ruby、Git确认版本与命令可用
路径规划裸仓库目录、Redmine 运行用户权限正确,仓库可读写
内置 Git 接入项目设置中的版本库模块能浏览提交历史和代码差异
Additionals 安装plugins 目录、数据库迁移管理后台插件列表出现 Additionals
托管插件进阶redmine_git_hosting 与 SSH 配置服务端 SSH 认证可正常推送
验证与维护测试仓库、升级流程功能全部可用且可备份恢复

下面每一步我都会说清楚命令、原理和容易踩的坑。

2. 环境检查与路径规划:装之前不踩坑

2.1 先确认 Redmine 版本和 Ruby 环境

不管你是用什么方式装的 Redmine(源码包、Bitnami 镜像、Docker),第一步永远是对版本。Redmine 5.1.4 对应的 Ruby 要求是 2.7 到 3.1 之间,Rails 版本是 6.1。版本不匹配的问题一般不会在启动时报,而是在你执行bundle install或者插件数据库迁移时突然爆炸,所以最好提前确认。

cd /var/www/redmine ruby bin/about

这个命令会打印出 Redmine 版本、Ruby 版本、Rails 版本、以及当前已安装的插件列表。如果这里显示的版本不对,先别往下走,解决基础环境问题比排查插件问题容易十倍。

同时检查一下plugins目录是否存在、是否归当前运行用户拥有。Redmine 源码包安装后,这个目录默认存在,但有些一键安装包会把它放在别的路径,或者权限很怪。我用的是源码包,目录直接在/var/www/redmine/plugins,后面所有插件都往这里放。

2.2 Git 命令路径:Redmine 能不能找到 git 是关键

Redmine 内置 Git 模块本身不包含 Git 的读仓库逻辑,它是通过调用服务器上的 git 命令行来完成的。所以服务器必须装有 Git,而且 Redmine 运行用户必须能在 PATH 环境变量里找到 git。

git --version which git

如果输出类似/usr/bin/git,那一般没问题。但有一个特殊场景很容易中招:Bitnami 安装的 Redmine。Bitnami 出于隔离考虑,启动 Redmine 服务时的 PATH 经常不包含/usr/bin,于是 Redmine 后台扫描版本库时提示找不到 git 命令。解决办法是在 Redmine 的配置里显式指定 git 路径,在config/configuration.yml中加入 scm 相关设置,或者通过管理后台的"管理 -> 设置 -> 版本库 -> Git 命令路径"来填写绝对路径。我实际遇到的情况就是后者,填上/usr/bin/git之后刷新就正常了。

提示:填绝对路径之前先确认 git 的真实位置,不要想当然。which git输出在哪个目录就填哪个目录。

2.3 裸仓库目录规划与运行用户授权

这里是一个非常高频的翻车点。Redmine 通过 Web 进程运行,默认用户可能是www-data、redmine或者daemon,不同安装方式不一样。如果你把 Git 裸仓库放在一个 Web 进程没有读权限的目录里,Redmine 界面上版本库标签会一直转圈,然后日志里报权限错误。

我推荐的目录规划是这样的:

sudo mkdir -p /srv/git/repositories sudo chown -R redmine:redmine /srv/git/repositories

注意这个redmine用户要根据你实际的运行用户来替换。怎么确认当前 Redmine 跑在哪个用户下?用ps aux | grep redmine或者ps aux | grep puma/passenger看进程归属。确认之后,除了仓库目录的读写权限,还要验证运行用户能否调用 git:

sudo -u redmine bash -lc 'git --version'

如果这一步报git: command not found,那么问题就回到了 2.2,你需要调整 PATH 或者改配置。这一步很多人跳过,结果后面仓库怎么都加不进去,绕了一大圈才发现是运行用户调不到 git 命令。

2.4 时区与日志检查习惯

这一步虽然不是必须,但我强烈建议先养成习惯:排查 Redmine 问题时,第一现场永远是log/production.log。在处理版本库问题时,Redmine 会在这里记录 fetch 和 git 命令执行的报错信息。

tail -f /var/www/redmine/log/production.log

打开一个终端窗口挂着,后面配置仓库和插件的时候,你会看到很多界面上看不出来的细节。

3. 内置 Git 模块接入企业仓库:从裸仓库到 Issue 联动

3.1 初始化 Git 裸仓库

Redmine 的 Git 集成要求仓库是裸仓库(bare repository),也就是没有工作区的仓库。这个设计很合理:Redmine 只负责读对象数据、展示提交历史和代码差异,不需要 checkout 出文件,所以裸仓库既节省空间又避免了工作区冲突。

cd /srv/git/repositories git init --bare --initial-branch=main myproject.git

--initial-branch=main是 Git 2.28 以后的参数,指定初始分支名。如果你们团队还在用master,也可以不写这个参数,但这不重要,重要的是初始分支名要和后续 Push 的分支一致。git init --bare之后,目录里没有源代码,只有objects、refs、HEAD等管理文件,这就是裸仓库的核心特征。

对开发同事来说,使用方式没有任何变化:

git remote add origin redmine-server:/srv/git/repositories/myproject.git git push -u origin main

从这里开始,代码就进入 Redmine 的可视范围了。

3.2 在 Redmine 项目设置中登记仓库

仓库初始化好之后,回到 Redmine 界面。进入某个项目,点"设置 -> 版本库 -> 新建版本库",核心配置项如下:

  • 版本控制系统:选择 Git
  • 仓库路径:填/srv/git/repositories/myproject.git这个绝对路径
  • 标识:给仓库起一个显示名称,比如main-repo
  • 分支/标签:一般默认即可,Redmine 会动态读取

保存之后,Redmine 会尝试读取这个裸仓库。如果配置正确,项目左侧的"版本库"标签下立刻就能看到文件列表和提交记录。第一次读取如果仓库历史很长,可能需要等几秒,Redmine 是异步 fetch 的,日志里会有记录。

常见的一种情况是保存后版本库页面显示"The entry or revision was not found in the repository"(条目或版本在仓库中不存在)。这个报错 80% 是因为仓库路径填错,或者 Redmine 运行用户读不了那个目录。先检查路径是否有拼写错误,再用 2.3 里的sudo -u redmine验证一下读权限,基本都能解决。

3.3 提交信息自动关联 Issue:团队协作的隐形纽带

内置 Git 模块最有价值的点,是提交信息可以和 Issue 自动关联。开发者在提交代码时,只要在 commit message 里写上#问题编号,Redmine 就会在对应问题下自动显示这条提交记录,同时版本库页面也能反查到这个问题。

比如:

git commit -m "修复登录超时问题 #123"

提交并推送后,Redmine 会通过 git log 解析提交信息,在问题 #123 的活动历史里出现"关联的修订版本"记录。对于团队管理来说,这意味着从需求到代码的完整链路被串起来了:产品看点状态,开发点提交记录,测试点问题修复历史,都在同一个系统里完成。

这个"引用关键词"不是写死的,Redmine 允许自定义。路径在"管理 -> 设置 -> 版本库",里面有关键词配置,默认支持refs、references、Related等,修复类关键词fixes甚至可以配合状态流转自动关闭问题。如果你的团队想统一用close #123这种格式,在那里配置就行。

3.4 查看提交历史和差异对比的正确姿势

仓库接入之后,日常用的最多的就是两个功能:一是版本库页面的提交历史,按时间倒序列出所有 commit,点击任意一条可以看这次提交改了哪些文件、每处改动的内容是什么;二是文件浏览,可以直接在网页上查看某个文件的最新内容,还可以点进历史版本查看演进过程。

Redmine 5.1.4 在这个模块上比较成熟,分支切换、标签浏览都支持。代码评审时我们团队的习惯是:评审者打开版本库页面,按分支筛选提交,逐条看 diff,看完直接在对应 Issue 下写评论。整个过程不需要离开 Redmine,也不需要给评审者开 Git 平台的权限,这在跨团队协作时能省不少事。

3.5 初始仓库为空时的小技巧

如果你的项目是从零开始的,仓库里还没有任何提交,Redmine 在版本库页面会提示"仓库仓库是空的"之类的内容,这是正常的。但要注意一点:如果初始分支名和 Redmine 默认读取的分支不一致,比如裸仓库初始分支是master,而开发同事推送的是main,版本库页面可能显示为空。遇到这种情况,在分支选择器里切换一下分支即可,不用重新配置仓库。

4. Additionals 插件安装实录:从代码下载到功能启用

4.1 版本匹配是第一步,不是 clone 是第一步

Additionals 插件的官方仓库是https://github.com/AlphaNodes/additionals,安装位置在 Redmine 的plugins目录下:

cd /var/www/redmine/plugins git clone https://github.com/AlphaNodes/additionals.git cd additionals git checkout 4.x

注意我写了git checkout 4.x这一行,这是整个 Additionals 安装里最容易翻车的地方。Additionals 有很多版本分支和标签,直接 clone 默认分支不一定与 Redmine 5.1.4 兼容。我建议去看一眼 README 里的"Requirements"段落,里面会明确写当前分支支持哪些 Redmine 版本。以 Installation 时的情况为例,Additionals 4.2.x 支持 Redmine 5.1.x,这个组合是经过多人验证的。

4.2 bundle install 安装依赖:耐心等,别中断

Redmine 的插件本质上是 Rails 引擎,Additionals 引入了自己的 gem 依赖,所以下载完代码不是结束,而是刚开始。

cd /var/www/redmine bundle install --without development test

这一步会安装插件依赖的 gem,时长取决于网络和系统环境,可能几分钟到十几分钟。有几个点需要特别注意:

  • bundle 命令要以 Redmine 项目根目录为工作目录,不能在plugins/additionals里执行,否则 bundler 找不到 Redmine 的 Gemfile。
  • 不要用--jobs强行并行编译,有些 gem(尤其带原生扩展的)并行编译反而容易出错。
  • 如果中途报nokogiri或ffi相关编译错误,一般是系统缺少编译依赖,先安装对应的开发包再重试,比硬绕过去靠谱。

4.3 插件数据库迁移:这一步不做等于白装

插件会创建自己的数据表和保存配置项的存储记录,所以需要执行迁移命令。这是所有 Redmine 插件的统一操作:

bundle exec rake redmine:plugins:migrate RAILS_ENV=production

执行完会看到类似"迁移插件 Additionals 成功"的输出。迁移命令是可重复执行的,Redmine 会记录每个插件的迁移版本号,升级插件后再次执行只会执行新增的迁移,不会重复跑旧迁移。这也是为什么后面你每次升级 Additionals 时,都要把这个命令重新跑一遍的原因。

然后重启 Redmine。使用 Passenger 部署的话,执行:

touch /var/www/redmine/tmp/restart.txt

如果是 systemd 服务:

systemctl restart redmine

重启后进入"管理 -> 插件"页面,列表里应该能看到 Additionals 及其版本号。看到版本号只说明插件的骨架注册成功了,功能还需要配置。

4.4 按团队习惯启用功能,别一股脑全开

Additionals 的特点之一是功能模块很多,安装后默认不会全部开启,需要在项目设置或插件设置里逐个启用。我这次实际启用的模块和理由如下:

功能模块作用适用场景
项目收藏项目列表加星标收藏,常用项目置顶项目数量多的团队,避免每次翻列表
Wiki 宏扩展在 Wiki 里插入日期提醒、倒计时等动态内容需要页面提示截止日期的场景
页面标题增强显示文档标题而不是文件路径文档浏览体验提升明显
自定义菜单增加团队自己的全局菜单项放常用入口或外部链接

这些功能对日常使用体验的提升很直接,尤其项目收藏和页面标题增强,几乎是装了就能感受到差别。但我不建议把 Additionals 的所有开关一次性全部打开,一是部分功能会改变 Redmine 原有页面的布局,二是功能多了之后,一旦出现页面异常,排查范围会被扩大。

4.5 Additionals 和 Git 模块的组合用法

既然标题里同时提到了 Git 和 Additionals,我多说一句两者联动的地方。Additionals 的 Wiki 增强功能可以让你在每个项目的 Wiki 首页做一个"项目状态页",把当前分支、最新提交、关联任务整理成一张看板。具体做法是:在 Wiki 页面里插入自定义宏,将提交动态和任务到期提醒集中展示。这种用法在我们的项目里效果很好,产品经理打开项目首页就能看到代码进展和任务风险,不需要再单独翻版本库和问题列表。

5. 升级路线:redmine_git_hosting 托管方案与 SSH 认证排错

5.1 什么时候才需要上重量级托管插件

内置 Git 模块的定位是"读取和展示",它不负责创建仓库、管理用户权限、处理 SSH 密钥。如果你的团队只有三五个人,代码仓库已经由运维手动创建好了,那内置模块完全够用。但如果你希望 Redmine 能承担 Git 托管职责——开发同事在 Redmine 界面里创建新仓库、管理 SSH 公钥、自主建分支——那就要上redmine_git_hosting这类托管插件了。

这里要先给你打个预防针:托管插件改变了仓库的存储方式和管理模型。安装之后,插件会把仓库路径重新组织,以项目标识作为子目录,原有裸仓库需要迁移。这意味着从内置模块切换到托管方案,不是简单插一个插件,需要规划数据迁移。所以我的建议是:先想清楚需求边界,再决定走哪条路,如果只是想让 Redmine 能看代码和关联任务,内置模块永远是最稳的选择。

5.2 redmine_git_hosting 的安装与关键配置

如果确认需要托管方案,安装步骤可以参考下面的流程:

cd /var/www/redmine/plugins git clone https://github.com/jbox-web/redmine_git_hosting.git cd /var/www/redmine bundle install bundle exec rake redmine:plugins:migrate RAILS_ENV=production touch tmp/restart.txt

安装本身和 Additionals 流程类似,但配置上复杂很多,核心在config/configuration.yml中加入插件参数。通常需要指定:

redmine_git_hosting: gitUser: git gitRepositoriesBasePath: /srv/git/repositories

gitUser是执行 git 命令的系统用户,gitRepositoriesBasePath是仓库根目录。这背后涉及 SSH 公钥管理和用户身份切换,插件文档里对这两个参数有详细说明。你需要根据自己的 SSH 环境调整,不能照抄。

这里我还想强调一个容易忽略的点:redmine_git_hosting 这类插件对 Redmine 版本、Ruby 版本的敏感程度远高于 Additionals。安装前一定要确认 README 里的兼容矩阵,否则bundle install阶段就会因为 Ruby 版本不支持而失败。

5.3 SSH 认证失败的高频原因和完整排查链路

既然热搜词里反复出现"ssh认证失败 git",我把这个问题单独拿出来说。用托管插件后,开发同事推送代码走的是 SSH 协议,最常见的报错是Permission denied (publickey)。这个报错让很多人头疼,但排查链路其实很固定,从客户端到服务端逐层缩小范围:

第一步:确认公钥已经添加到 Redmine 个人账号。在 Redmine 中打开个人账号设置,找到 SSH 密钥管理区域,把客户端的~/.ssh/id_ed25519.pub内容粘贴进去。注意要确认粘贴的是公钥而不是私钥,这个错误出现的频率比想象中高。

第二步:确认服务端 sshd 允许公钥认证。检查 Redmine 服务器的/etc/ssh/sshd_config:

grep -E "PubkeyAuthentication|AuthorizedKeysFile" /etc/ssh/sshd_config

PubkeyAuthentication必须为yes,否则一切公钥都登不上。改完配置记得systemctl restart sshd。

第三步:确认托管用户和 shell 配置。托管插件通常用专门系统用户(如git)执行仓库操作,这个用户不能是普通可登录用户,一般配置git-shell或插件的专用 shell。如果系统用户配置错误,认证会直接被拒绝。检查:

grep "^git:" /etc/passwd

如果 shell 字段是/bin/bash而不是限制 shell,公钥认证即使成功也会因为无法执行受限命令而失败。

第四步:看服务端日志。/var/log/auth.log或/var/log/messages里会记录 SSH 拒绝的具体原因,这一步能直接定位到是密钥匹配失败、还是用户配置问题。

第五步:测试连接。配置完成后,用ssh -T git@redmine-server测试,托管插件一般会输出欢迎信息或可执行的命令列表。能连上就说明认证链路通了,剩下的就是仓库初始化配置问题。

这五步按顺序走下来,90% 的 SSH 认证问题都能定位。我这里之所以把排查链路写在安装流程里,是因为很多同学装完托管插件之后发现推送不上去,第一反应是重装插件,其实问题根本不在插件层面。

6. 安装后的验证清单与日常维护要点

6.1 功能验证清单:装没装成,用这张表说话

安装完成不等于配置完成,配置完成不等于业务可用。我每次交付环境前都会按下面这张表逐项验证,任何一项不通过都要当场解决,而不是留到上线后:

检查项操作期望结果
Redmine 版本ruby bin/about显示 5.1.4
Git 命令可用管理后台版本库设置显示 Git 可用及命令路径
仓库读取项目版本库页面文件列表和提交历史正常显示
提交关联推送带#问题号的 commitIssue 下出现关联修订记录
Additionals管理 -> 插件列表出现且版本匹配
Additionals 功能项目设置中启用项目收藏项目列表出现收藏星标
SSH 认证(托管方案)ssh -T git@服务器连接成功无报错

6.2 升级 Redmine 和插件时的正确顺序

Redmine 的插件升级有一个原则:先升级 Redmine 主程序,再升级插件,最后执行插件迁移。升级插件之前,先看插件的 README 兼容矩阵,确认它支持当前的 Redmine 版本。Additionals 做得比较好,它对版本兼容的说明很明确;redmine_git_hosting 这类依赖重的插件,升级前最好先在测试环境完整走一遍,避免生产环境直接在bundle install阶段爆炸。

升级后的迁移命令就是前面用过的:

bundle exec rake redmine:plugins:migrate RAILS_ENV=production

只要 Redmine 和插件版本都兼容,这个命令可以安全重复执行。

6.3 备份策略里必须包含三项内容

最后说备份。Redmine 的备份容易漏东西,很多人只备数据库,结果插件配置和仓库全丢了。我建议至少把下面三样纳入备份范围:

  • 数据库:Redmine 的问题、项目配置、插件设置全在数据库里。
  • Redmine 应用目录:plugins/目录下的插件代码,以及config/configuration.yml。
  • 仓库目录:/srv/git/repositories下的所有裸仓库,连同 hooks 和描述文件一起备份。

裸仓库备份非常简单,直接打包整个目录就行,恢复时解压到原路径、确认权限正确、Redmine 界面刷新即可重新识别。这个方案实测了很多次,是同类场景里最可靠的做法。

按照这套流程走一遍,Redmine 5.1.4 的 Git 仓库接入和 Additionals 插件配置基本不会出现意外。如果中途卡住了,先回看日志,再对照本文的环境检查部分逐步排查——大部分问题其实都出在最初的环境准备阶段。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询