我最早在客户现场折腾禅道部署,遇到最多的不是禅道本身不会装,而是装完以后才发现系统盘不够用、数据目录没法迁移、备份恢复时路径全是默认值,搞得人很被动。这篇文章就把我在CentOS上部署禅道系统、自定义数据库存储路径和文件存储位置的完整过程写下来,从路径规划的逻辑讲起,到实际命令、踩坑记录、验证方法都放出来,给正在做同样事情的朋友一个可以直接照着执行的参考。
先说重点:禅道官方的一键安装包默认把MySQL数据和附件文件都放在/opt/zbox下面,这在测试环境没问题,但生产环境一旦数据量上来,系统盘分分钟塞满。所以“自定义数据库存储路径和文件存储位置”不是锦上添花,而是部署前就要想清楚的事。整篇文章的操作环境是CentOS 7.9,禅道使用开源版一键安装包,MySQL数据最终落在独立数据盘,附件存储也一并迁走。
1. 部署前的整体设计与路径规划思路
1.1 为什么要动存储路径:系统盘和数据盘分离的底层逻辑
很多人在一台机器上装禅道,图省事直接默认路径,等用了三五个月,发现/分区快满了,才想起来要迁数据。这时候再做迁移虽然可行,但风险和工作量都比一开始就规划好要大得多。这里面的核心逻辑是Linux系统盘和数据盘分离:系统盘负责操作系统、程序文件、日志,数据盘专门放数据库文件和用户上传的附件。系统盘崩了,重装系统不影响数据;数据盘要扩容,直接加一块盘挂上去就行,不用跟系统目录纠缠。
尤其MySQL这种对I/O和空间都比较敏感的服务,数据文件放在独立数据盘上还有一个好处:可以针对数据盘单独做磁盘配额、SSD加速、快照备份,而不影响系统盘的日常运维操作。禅道的附件目录也一样,用户上传的图片、文档、压缩包,日积月累体积不小,放在独立目录里方便打包迁移,也方便做增量备份。
1.2 禅道一键安装包的目录结构解读
开始动手之前,必须先搞清楚禅道一键安装包的目录结构。官方提供的Linux一键安装包内置了Apache、PHP、MySQL,解压到/opt/zbox目录下就能跑,目录结构大致是这样:
/opt/zbox ├── app │ ├── zentao # 禅道程序主目录 │ └── ... ├── bin ├── data │ └── mysql # MySQL数据目录(默认在这里) ├── etc ├── logs ├── run └── zbox # 启动/停止/重启脚本注意看data/mysql这个目录,它是一键包里MySQL实例的数据目录,包含ibdata1、ib_logfile0、各个业务库的目录。禅道的数据表、配置信息、用户数据全在这里。默认情况下它落在/opt,也就是跟随系统盘。我们要做的就是把整个data/mysql从系统盘挪到独立数据盘,再通过软链接让原来的路径依然可用。
1.3 最终方案选型:先安装后迁移,还是迁移后安装
实际操作中有人问过我:既然要自定义路径,是不是可以先挂载好数据盘,然后直接把禅道解压到数据盘上?可以,但要注意一个问题:禅道一键包的很多操作脚本和绝对路径关联,如果你把整个/opt/zbox放到数据盘,需要另外处理/opt/zbox本身作为软链接的情况,虽然也能工作,但对后续升级不太友好。官方升级包经常要覆盖/opt/zbox下的文件,如果/opt/zbox整体是软链接,升级时解压路径写死,容易出意外。
所以我个人的推荐方案是:禅道程序本体放在/opt/zbox,保留默认路径;只把MySQL数据目录和附件存储目录迁移到数据盘,用软链接把数据盘上的真实目录映射回原路径。这样做的好处有三个:
- 禅道程序升级不受影响,升级包解压覆盖的是程序文件。
- MySQL和禅道应用感知不到路径变化,配置文件不用改,减少出错面。
- 数据盘卸载/更换时,只需要重新建立软链接即可,恢复成本低。
1.4 目录规划与命名约定
我在实际操作中习惯先规划好所有路径,写在笔记里再动手。下面是我这次部署用的目录规划:
| 用途 | 默认路径 | 迁移后真实路径 | 软链接 |
|---|---|---|---|
| 禅道程序 | /opt/zbox | /opt/zbox(不动) | 无 |
| MySQL数据目录 | /opt/zbox/data/mysql | /data/zentao/mysql | /opt/zbox/data/mysql |
| 附件文件目录 | /opt/zbox/app/zentao/data/upload | /data/zentao/upload | /opt/zbox/app/zentao/data/upload |
命名上我用的/data/zentao作为总目录,下面分mysql和upload两个子目录。如果你的服务器上有多套业务,建议类似/data/zentao_prod这样带业务标识的命名,避免时间久了自己都分不清哪个目录属于哪个系统。
2. CentOS环境准备与禅道安装包部署
2.1 基础环境检查与依赖准备
我建议从一台全新的CentOS 7.9开始,这样环境干净,排查问题容易。先做三件事:检查系统版本、查看磁盘分区情况、确认数据盘存在。
cat /etc/redhat-release lsblk df -hlsblk的输出里如果看到类似sdb这样的盘还没有挂载,那就说明有独立数据盘可用。假设数据盘是/dev/sdb,先格式化再挂载:
mkfs.xfs /dev/sdb mkdir -p /data mount /dev/sdb /data要让挂载在重启后依然生效,需要写进/etc/fstab:
echo "/dev/sdb /data xfs defaults 0 0" >> /etc/fstab这里有一个坑:CentOS 7默认的xfs文件系统在做目录迁移时没什么问题,但如果你后续要对数据盘做LVM扩容,建议从一开始就用LVM来管理,不要直接建xfs分区。个人项目的机器直接挂载就行,生产环境建议LVM。
2.2 下载并解压禅道一键安装包
禅道官方下载地址经常变,我一般去官网找到Linux一键安装包的下载链接。这个包是.tar.gz格式,大概两三百MB。下载后解压到/opt:
cd /opt tar -zxvf ZenTaoPMS-18.5-zbox_64.tar.gz解压之后会出现/opt/zbox目录。这里有个容易忽略的点:解压前要确认/opt目录有足够的剩余空间,至少留2GB以上,因为里面带了MySQL程序文件。检查空间用:
df -h /opt如果/opt剩余空间不足,先想办法清理或者扩展,否则解压到一半报磁盘满,还得清理残留文件重新解压。
2.3 启动禅道服务并完成首次初始化
一键包的管理命令都在/opt/zbox/zbox这个脚本上,用法很清晰:
/opt/zbox/zbox start启动后会有两个进程在跑:Apache和MySQL。可以用以下命令确认状态:
/opt/zbox/zbox status然后浏览器访问http://服务器IP,首次访问会进入禅道安装向导,按提示设置公司名称、管理员账号密码,并配置数据库链接。注意,向导里的数据库默认信息已经填好了,一般不需要改:
| 配置项 | 默认值 |
|---|---|
| 数据库地址 | 127.0.0.1 |
| 数据库端口 | 3306 |
| 数据库名称 | zentao |
| 数据库用户 | root |
| 数据库密码 | 123456(建议安装后立即修改) |
首次初始化完成后,禅道就能正常登录了。这时候我们先不要急着传数据,先把存储路径的迁移做完,再做数据验证。
2.4 防火墙与端口访问配置
CentOS 7默认firewalld是开启的,如果不放行端口,外部浏览器访问不了禅道。一键包默认用80端口,放行命令:
firewall-cmd --zone=public --add-port=80/tcp --permanent firewall-cmd --reload如果80端口被占用,可以用一键包自带的命令改端口:
/opt/zbox/zbox -p 8080改完以后重启服务:
/opt/zbox/zbox restart访问地址就变成http://服务器IP:8080。
3. 自定义数据库存储路径:MySQL数据目录迁移实操
3.1 先搞清楚MySQL数据在哪:确认当前数据目录
迁移之前,先确认MySQL当前的datadir到底指向哪个路径。有些版本禅道会把data/mysql作为软链接引导到别处,所以不要凭经验判断,直接进MySQL查:
/opt/zbox/bin/mysql -uroot -p123456 -e "show variables like 'datadir';"正常情况下返回值为/opt/zbox/data/mysql/。同时看一眼这个目录下有哪些文件:
ls -lh /opt/zbox/data/mysql/看到ibdata1、ib_logfile0、ib_logfile1以及zentao子目录,基本就确认这是MySQL的真实数据目录了。
3.2 停止服务,迁移数据目录
这一步是整个迁移过程的关键,很多人图省事直接在线拷贝数据目录,结果拷完启动报错。正确流程是先停服务再拷贝,保证数据文件处于一致状态。
/opt/zbox/zbox stop停止后确认进程已退出:
ps -ef | grep mysql然后用mv把整个数据目录移动到数据盘。这里用mv而不是cp,因为mv在同一文件系统内是秒级完成,但跨文件系统时本质是“复制+删除”,如果数据量大耗时较长。我们这里源目录/opt/zbox/data/mysql在系统盘,目标/data/zentao/mysql在数据盘,属于跨文件系统操作,实际上还是走了拷贝,但好处是目录权限和时间戳会尽量保持。
mkdir -p /data/zentao mv /opt/zbox/data/mysql /data/zentao/mysql移动完成后,原路径/opt/zbox/data/mysql已经不存在了。
3.3 创建软链接与原目录绑定
接下来创建软链接,让禅道和MySQL依然可以通过原来的路径访问到数据:
ln -s /data/zentao/mysql /opt/zbox/data/mysql创建完检查一下:
ls -ld /opt/zbox/data/mysql输出应该类似... /opt/zbox/data/mysql -> /data/zentao/mysql,说明软链接建立成功。这时候MySQL程序通过原路径读写数据,实际落地都在数据盘,对应用完全透明。
3.4 权限修正与重启验证
这一步很多人忽略,却直接影响MySQL能否启动:MySQL的数据目录必须对mysql用户可读写。禅道一键包里MySQL是以mysql用户运行的,如果迁移到数据盘后目录属主不对,启动就会报Permission denied。
chown -R mysql:mysql /data/zentao/mysql权限修正后启动服务:
/opt/zbox/zbox start启动后马上查状态:
/opt/zbox/zbox status只要两个服务都是running状态,说明迁移已经成功了大半。
3.5 验证迁移是否生效的核心指标
服务能起来只是第一步,还要确认读写确实落到新路径。两个验证方法:
第一,再看MySQL的datadir配置:
/opt/zbox/bin/mysql -uroot -p123456 -e "show variables like 'datadir';"返回值还是/opt/zbox/data/mysql/,这符合预期,因为配置没变,但我们知道实际文件在/data/zentao/mysql。不信的话看新目录下的文件时间戳:
ls -lh /data/zentao/mysql/zentao/第二,在禅道上做一次真实操作,比如新建一个产品、提交一条Bug,然后再去数据盘查看对应表的数据文件是否更新。这种方法虽然原始,但最能验证读写链路完整。
4. 自定义文件存储位置:禅道附件存储目录迁移
4.1 找对附件存储目录:理解禅道的附件存储机制
禅道的附件并不存在数据库里,而是以文件形式保存在程序目录下。默认路径是/opt/zbox/app/zentao/data/upload/,里面按用户ID、年份、月份分目录存放。比如:
/opt/zbox/app/zentao/data/upload/1/2024/06/xxx.png这里1是用户ID,2024/06是上传时间。理解这个结构对后续备份很重要:备份数据库文件之外,附件目录要一起打包,缺一个都不完整。
4.2 附件目录迁移的三个步骤
操作套路和MySQL目录迁移一致,依然是“停止服务→移动目录→创建软链接”。
先停止服务:
/opt/zbox/zbox stop移动目录到数据盘:
mkdir -p /data/zentao mv /opt/zbox/app/zentao/data/upload /data/zentao/upload创建软链接:
ln -s /data/zentao/upload /opt/zbox/app/zentao/data/upload注意,这时候/opt/zbox/app/zentao/data目录下还有其他文件,比如cache、log等,我们只移动upload子目录,其他不要动。另外,上传目录的权限要保证www用户(或者一键包运行Web服务的用户)可写:
chown -R www:www /data/zentao/upload这里www用户是一键包内Apache运行用户的常见属主,可通过ps -ef | grep httpd确认,不同版本可能不一样。
4.3 创建一个测试附件验证路径
服务重新启动后,登录禅道后台,在“产品→文档”里创建一个文档并上传一个图片附件。上传成功后,去数据盘看:
find /data/zentao/upload -type f | head能看到新上传的文件出现在/data/zentao/upload/1/当前年份/当前月份/下面,说明附件存储已经落到新路径。
另外,可以在浏览器里打开附件的访问地址,如果图片能正常显示,说明Web服务读取链路也通了。这一步很关键,因为附件迁移如果只改了存储位置但权限有问题,会出现“上传成功但页面打不开附件”的尴尬情况。
4.4 如果不做这步会怎样(典型故障场景)
我见过一个真实案例:某团队用禅道大半年,系统盘只有50G,附件目录悄悄涨到30多G,加上MySQL数据,系统盘满了以后最先出现的问题是禅道页面打开极慢、上传附件直接报500错误,数据库写入也时断时续。最后花了一整天才完成紧急迁移,期间业务中断。如果一开始就把附件目录迁走,后续只需要定期对数据盘做快照和备份,完全不用操心系统盘空间。
更隐蔽的问题是备份脚本大多只打包/opt/zbox,如果附件和数据库都在系统盘,备份文件会越来越大,最终连备份写入的空间都不够。目录迁移后,备份脚本可以只针对/data/zentao做处理,职责明确得多。
5. 常见问题与排查技巧实录
5.1 启动后HTTP 500或数据库连不上怎么办
迁移后如果禅道页面报HTTP 500,首先看/opt/zbox/logs/下的日志,尤其mysql_error.log和apache_error.log。我遇到最多的情况是权限问题:
tail -n 100 /opt/zbox/logs/mysql_error.log日志里出现[ERROR] InnoDB: Operating system error number 13 in a file operation,说明MySQL进程无法访问数据文件。这时候执行权限修正后重启:
chown -R mysql:mysql /data/zentao/mysql /opt/zbox/zbox restart另外检查一下数据盘挂载选项,如果是noexec或nosuid,改为defaults重新挂载:
mount -o remount,defaults /data5.2 迁移后旧数据看不到了怎么办
有一种情况:迁移前禅道已经用了一段时间,数据库里有数据,附件目录也有文件;迁移后打开系统发现产品、项目还在,但附件图片打不开。这种问题十有八九是日期目录对不上,比如旧的附件路径是/opt/zbox/app/zentao/data/upload/1/2024/05,迁移时文件被放在/data/zentao/upload/1/2024/05,位置没错,但要检查软链接是否指向正确。
用readlink查看:
readlink /opt/zbox/app/zentao/data/upload如果是/data/zentao/upload,再对比目录内容是否完整。还有可能是重启后禅道缓存了旧的存储路径,执行/opt/zbox/zbox restart即可。
5.3 磁盘配额与备份恢复时的路径参数
自定义路径之后的备份恢复,最容易出问题的就是路径恢复。备份时要把两个部分都备份:数据库和附件目录。我的做法是用crontab定时执行:
tar -czf /backup/zentao_mysql_$(date +%Y%m%d).tar.gz /data/zentao/mysql tar -czf /backup/zentao_upload_$(date +%Y%m%d).tar.gz /data/zentao/upload恢复时先解压,再保证软链接存在:
tar -xzf zentao_mysql_20240101.tar.gz -C /data/zentao/ tar -xzf zentao_upload_20240101.tar.gz -C /data/zentao/ ln -sfn /data/zentao/mysql /opt/zbox/data/mysql ln -sfn /data/zentao/upload /opt/zbox/app/zentao/data/upload chown -R mysql:mysql /data/zentao/mysql chown -R www:www /data/zentao/upload恢复完成再启动服务。注意,ln -sfn里的-n参数在软链接已经是目录的情况下很重要,不然会创建嵌套链接导致路径异常。
5.4 系统盘确实没空间时的应急方案
如果系统盘已经红了,但数据盘还有空间,又来不及做详细迁移,可以用一个临时应急方案:把/opt/zbox下的大目录直接绑定挂载(bind mount)到数据盘目录。做法是:
把原目录先移过去,再绑定挂载:
mkdir -p /data/zentao_bind mv /opt/zbox/data/mysql /data/zentao_bind/mysql mkdir -p /opt/zbox/data/mysql mount --bind /data/zentao_bind/mysql /opt/zbox/data/mysql写入/etc/fstab持久化绑定:
/data/zentao_bind/mysql /opt/zbox/data/mysql none bind 0 0这个方案的好处是系统盘立刻释放空间,坏处是绑定挂载的恢复逻辑没有软链接直观,后续运维容易忘。所以它只作为应急手段,等业务空闲还是建议改成软链接方案。
我把这套部署和迁移的实操记录写下来,也是因为自己在最初几次部署时没少踩坑。一开始图省事,全默认路径;等客户数据量上来,半夜收到磁盘告警短信,才手忙脚乱赶迁移。后来我形成习惯:凡是生产环境的禅道部署,先看磁盘规划,再定存储路径,然后才装包。这套流程看上去多花了十几分钟,但后面能少折腾好几天。如果你也在准备部署禅道,先把存储规划这一步做扎实,后面会省心很多。