Traq 3.8.6 运维命令详解
Traq v3.8.6 运维命令实测手册:服务管理与进程检查、版本确认与升级向导、mysqldump 备份恢复演练、日志与 FPM 参数、API 只读端点实测,以及建单 500 等五则排障实录。
Traq 3.8.6 运维命令详解
目标:覆盖 Traq v3.8.6 上线后的日常运维面——服务与进程管理、版本确认与升级、数据库备份恢复、日志与监控、API 运维接口、排障实录。Traq 本身不提供任何 CLI 管理命令(无 artisan/wp-cli 之类的工具),运维以「systemctl + mysql + curl + 文件操作」为主,本篇按此口径组织,全部命令与输出实测(实测日期 2026-10-28,环境 Ubuntu 22.04.5 LTS,站点
http://127.0.0.1:8143,示例 IP192.168.1.100)。
一、服务与进程管理
1.1 三个服务单元
Traq 站点由三个系统服务承载,标准管理命令(systemd 标准行为,输出为预期结果标注):
sudo systemctl status nginx php8.3-fpm mariadb
sudo systemctl restart nginx php8.3-fpm mariadb
# 预期结果:status 输出三个单元的 Active: active (running) 状态;
# restart 无回显即成功,失败时返回非零退出码
| 服务 | 作用 | 配置位置 |
|---|---|---|
| nginx | Web 入口、静态资源、PHP 反代 | /etc/nginx/sites-available/traq.conf |
| php8.3-fpm | PHP 进程池,执行 Traq 代码 | /etc/php/8.3/fpm/{php.ini,pool.d/www.conf} |
| mariadb | 数据存储 | /etc/mysql/ |
改完 PHP 配置用 sudo systemctl reload php8.3-fpm(平滑)或 restart;改 Nginx 站点配置先 sudo nginx -t 再 reload。
1.2 配置语法与端口检查(实测)
# sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# ss -ltn | grep 8143
LISTEN 0 511 0.0.0.0:8143 0.0.0.0:* users:(("nginx",pid=16116,fd=9))
1.3 进程快照
ps -eo pid,cmd | grep -E "nginx|php-fpm|mariadbd" 正常形态:1 个 nginx: master process + 若干 nginx: worker process;1 个 php-fpm: master process + 若干 pool www worker;1 个 mariadbd。PHP-FPM 池默认参数(/etc/php/8.3/fpm/pool.d/www.conf 实测默认值):pm = dynamic、pm.max_children = 5、pm.start_servers = 2、pm.min_spare_servers = 1、pm.max_spare_servers = 3——站点负载以读写为主、单请求轻量,默认值足够百人级团队使用,峰值 CPU 高时可先调 pm.max_children。
二、版本确认与升级
2.1 三个版本确认点(实测)
# ① 页脚版本:任意页面 HTML 内
# curl -sS http://127.0.0.1:8143/ | grep -o "Traq [0-9.]*" | head -1
Traq 3.8.6
# ② 版本常量文件(含数据库版本与 API 版本)
# grep -E "TRAQ_(VER|DB_VER|API_VER)" /var/www/traq/vendor/traq/version.php
define("TRAQ_VER", "3.8.6"); // Pretty obvious...
define("TRAQ_VER_CODE", 30806); // Used to check for new versions
define("TRAQ_DB_VER", 30800); // Database version
# ③ 升级向导页(数据库结构版本落后时会给升级入口)
# curl -sS -b cookie.txt http://127.0.0.1:8143/install/upgrade.php | grep -oE "<title>[^<]*|up to date"
<title>Traq Upgrade
up to date
TRAQ_VER(程序版本)与 TRAQ_DB_VER(库结构版本)是两个独立刻度;库结构当前版本存在 traq_settings 表 db_version 键(实测值 30800),升级向导据此判断要不要跑升级步骤。
2.2 标准升级流程
官方升级路径是「覆盖文件 → 网页升级向导」,没有命令行升级工具:
# ① 备份(数据库 + 配置 + 程序目录,见 3.1)
mysqldump --single-transaction traq > /opt/backups/traq-$(date +%Y%m%d).sql
cp -a /var/www/traq/vendor/traq/config /opt/backups/traq-config-$(date +%Y%m%d)
# ② 下载新版发布包并解压覆盖(vendor 一并覆盖,配置目录手工保留)
cd /tmp && wget https://github.com/nirix/traq/releases/download/vX.Y.Z/traq-vX.Y.Z.tar.gz
tar xzf traq-vX.Y.Z.tar.gz -C /var/www/traq
cp -a /opt/backups/traq-config-$(date +%Y%m%d)/. /var/www/traq/vendor/traq/config/
chown -R www-data:www-data /var/www/traq
# ③ 浏览器打开升级向导,按页操作
# http://192.168.1.100:8143/install/upgrade.php
升级向导逻辑(实测源码核对):读取库中 db_version,低于新版 TRAQ_DB_VER 时展示 welcome 页,点击执行 step/1 跑增量升级(install/helpers/upgrade/v3x.php 中的分版本升级例程),完成后把 db_version 更新为新版代码(如 30806)。当前库已是最新(实测页面显示 up to date),无需执行。
回滚:升级失败时恢复备份即可——还原 vendor/traq/config/、用旧版发布包覆盖回程序目录,再 mysql traq < 备份.sql。db_version 随库回滚,旧版程序即可正常运行。
三、数据库备份与恢复
3.1 备份(实测)
Traq 全部业务数据(含附件)都在一个库的 24 张表里,单条 mysqldump 即完整备份:
# mkdir -p /opt/backups
# mysqldump --single-transaction traq > /opt/backups/traq-$(date +%Y%m%d).sql
# ls -lh /opt/backups/
total 32K
-rw-r--r-- 1 root root 29K Oct 28 02:40 traq-20261028.sql
# grep -c "CREATE TABLE" /opt/backups/traq-20261028.sql
24
--single-transaction 对 InnoDB 一致性快照不锁表,适合在线备份。冷备需求可直接加 --flush-logs 或配合文件层整目录打包(程序目录 + /opt/backups)。
3.2 恢复演练(实测)
# mysql -e "CREATE DATABASE traq_restore CHARACTER SET utf8mb4;"
# mysql traq_restore < /opt/backups/traq-20261028.sql
# mysql -N -e "SELECT COUNT(*) FROM traq_restore.traq_tickets; SELECT COUNT(*) FROM traq_restore.traq_users;"
1
1
# mysql -e "DROP DATABASE traq_restore;"
数据计数与原库一致,恢复链路验证通过。正式恢复(替换原库):
mysql -e "DROP DATABASE traq;"
mysql -e "CREATE DATABASE traq CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql traq < /opt/backups/traq-20261028.sql
3.3 常用巡检 SQL(实测表结构)
# 用户清单
mysql -e "SELECT id,username,group_id,email FROM traq.traq_users;"
id username group_id email
1 admin 1 admin@example.com
# 设置项(改设置先查这里,对应 AdminCP 表单)
mysql -e "SELECT setting,value FROM traq.traq_settings LIMIT 5;"
# 工单量与最近工单
mysql -e "SELECT id,summary,status_id,is_closed,created_at FROM traq.traq_tickets ORDER BY id DESC LIMIT 5;"
⚠️ 附件不走文件系统:
traq_attachments表用contentslongtext 字段存附件内容、size存字节数(实测表结构核对)。这意味着备份一个库就备份了全部附件,但附件量大的站点要注意单库体积增长与 MySQL 的 max_allowed_packet 上限。
3.4 建议的备份周期
| 对象 | 命令 | 建议周期 |
|---|---|---|
| 数据库(全量含附件) | mysqldump --single-transaction traq > ...sql | 每日 |
| 配置目录 | cp -a /var/www/traq/vendor/traq/config ... | 变更时 |
| 程序目录 | 记录当前版本号,需要时按版本重新下载发布包 | 变更时 |
四、日志与监控
4.1 日志文件清单(实测路径)
| 日志 | 路径 | 内容 |
|---|---|---|
| 访问日志 | /var/log/nginx/access.log | 全部 HTTP 请求 |
| Nginx 错误日志 | /var/log/nginx/error.log | 网关层错误(upstream 连不上 FPM 等) |
| PHP-FPM 主日志 | /var/log/php8.3-fpm.log | 进程池启停、worker 告警 |
| PHP 应用错误 | 需按排障 7.4 开启 log_errors 后落在指定文件 | Uncaught Exception、SQL 错误 |
Traq 自身不写应用日志,应用层异常全靠 PHP 错误日志兜底(排障 7.4 是开启方法)。
4.2 日志轮转
Ubuntu 包自带轮转配置(/etc/logrotate.d/nginx 与 /etc/logrotate.d/php8.3-fpm),默认按日轮转保留 14/10 天,无需自建。
4.3 健康检查(可挂监控)
# curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8143/login
200
/login 不依赖登录态与数据库写入,作为存活性探针最稳;进一步可用 /api/types(返回 JSON 数组)同时验证数据库读链路。
五、API 运维接口
Traq 内置只读为主的 API(常量 TRAQ_API_VER 为 1.1,实测 version.php),端点实测如下:
5.1 匿名只读端点
# curl -sS http://127.0.0.1:8143/api/types
[{"id":1,"name":"Defect","bullet":"-","changelog":"1","template":""},{"id":2,"name":"Feature Request","bullet":"+","changelog":"1","template":""},{"id":3,"name":"Enhancement","bullet":"*","changelog":"1","template":""},{"id":4,"name":"Task","bullet":"*","changelog":"1","template":""}]
# curl -sS http://127.0.0.1:8143/api/statuses
[{"id":1,"name":"New","status":1,"changelog":false},{"id":2,"name":"Accepted","status":1,"changelog":false},{"id":3,"name":"Started","status":2,"changelog":false},{"id":4,"name":"Closed","status":0,"changelog":true},{"id":5,"name":"Completed","status":0,"changelog":true}]
(/api/priorities 同形态。)项目工单列表按项目 slug 访问,支持翻页参数:
# curl -sS http://127.0.0.1:8143/api/demo/tickets
{"page":1,"total_pages":1,"tickets":[{"id":1,"ticket_id":1,"summary":"Sample ticket from CLI test","body":"Created to verify ticket creation works.","is_closed":0,"is_private":0,"votes":0,"tasks":[],"extra":[],"time_proposed":null,"time_worked":null,"created_at":"2026-10-28 02:37:52","updated_at":null,"project":{"id":1,"name":"Demo Project"},"user":{"id":1,"username":"admin",...}}]}
⚠️ 已知小缺陷:该端点返回体首部可能带一行 PHP Warning(
Undefined array key 1 in .../controllers/tickets.php,排序参数处理的上游小问题,实测 3.8.6 存在),不影响其后的 JSON 有效性;若你的解析器对输出前缀零容忍,可过滤首个{之前的内容。
5.2 会话与身份端点
# 匿名(Guests 组)
# curl -sS http://127.0.0.1:8143/api/auth
{"id":0,"username":"guest","name":null,"group_id":3,"locale":null,"group":{"id":3,"name":"Guests","is_admin":false},"permissions":[]}
# 带登录会话 Cookie
# curl -sS -b cookie.txt http://127.0.0.1:8143/api/auth
{"id":1,"username":"admin","name":"Administrator","group_id":1,"locale":null,"group":{"id":1,"name":"Administrators","is_admin":false},"permissions":[]}
API 走 Web 会话鉴权(登录后带 Cookie 调用),个人中心 /usercp/create_api_key 可生成 API Key。已上缺陷记录:/api/auth 对管理员也返回 is_admin:false,而库中 traq_usergroups.is_admin=1(实测对比)——这是上游把整型与字符串做 === "1" 严格比较的类型缺陷,仅影响该端点的展示字段,不影响 AdminCP 与实际权限判断。
六、账号与数据日常管理
无 CLI,日常管理走 AdminCP(/admin):
| 任务 | 入口 | 备注 |
|---|---|---|
| 建用户/改用户/删用户 | /admin/users、/admin/users/new | 支持批量操作 /admin/users/mass_actions |
| 用户组与权限 | /admin/groups、/admin/roles | 组是全局,角色按项目指派(见配置篇 6.2) |
| 建/删项目 | /admin/projects、/admin/projects/new | 项目级设置在 /{slug}/settings |
| 工单字典 | `/admin/tickets/types | statuses、/admin/severities、/admin/priorities` |
| 插件启停 | /admin/plugins | 见配置篇第七章 |
| 设置 | /admin/settings | 见配置篇第四章 |
批量场景(如批量拉黑注册用户)可直接对 traq_users 表操作,但改表后建议清除对应会话(用户重新登录即刷新权限)。
七、排障实录
7.1 建单 500:Field 'version_id' doesn't have a default value
现象:脚本/接口方式提交新建工单(POST /{project}/tickets/new)返回 500,浏览器表单却正常。
定位(开启 FPM 错误日志后复现,实测异常):
Fatal error
Uncaught Exception: SQLSTATE[HY000]: General error: 1364 Field 'version_id' doesn't have a default value in /var/www/traq/vendor/avalon/framework/src/Database/PDO/Statement.php:154
原因:控制器按权限逐项读取里程碑/版本/组件/严重度等属性字段,脚本提交缺了 version 等字段时插入 NULL,而 traq_tickets.version_id 等列为 NOT NULL 无默认值。浏览器表单总会带上这些 select(无选项时值为 0),所以不受影响。
解决:脚本化提交请带上完整属性字段(实测通过的最小集):summary、description、type、status、priority、severity、version=0、component=0、milestone=0、assigned_to=0、is_private=0。
7.2 升级向导显示「Config file not found」
install/upgrade.php 启动即要求 vendor/traq/config/database.php 存在(实测提示语 Config file not found.)。多为升级时用新版包覆盖目录后忘了回填配置目录——按 2.2 流程第 ② 步回填即可。
7.3 整站 302 到 /install
主应用每次请求检测 database.php,不存在就 302 Location: /install。说明配置文件丢了或路径错了,恢复配置文件即恢复站点;配合配置篇 8.4 判断是「重装」还是「找回」。
7.4 页面 500 且默认日志无信息
生产 display_errors = Off 时按此路径开日志(实测有效):
# /etc/php/8.3/fpm/pool.d/www.conf 追加(或改 php.ini 的 log_errors/error_log):
php_admin_value[error_log] = /var/log/php8.3-fpm-error.log
php_admin_flag[log_errors] = on
catch_workers_output = yes
# systemctl restart php8.3-fpm
复现后读 /var/log/php8.3-fpm-error.log 即可拿到异常原文(7.1 的异常就是这么抓到的)。排障结束记得关回,避免日志膨胀。
7.5 API 返回里混着 PHP Warning
见 5.1 已知缺陷说明:/api/{project}/tickets 在部分参数组合下输出体前带 Warning 行。处理:脚本消费端做「截取首个 { 之后」的防御性解析,或等待上游修复(属 v3.8.6 已实测存在的上游问题)。
八、系列文档导航
- 环境与安装全过程:《Ubuntu 22.04 安装 Traq 3.8.6 指南》
- 配置文件、AdminCP 设置项与权限模型逐项详解:《Traq 3.8.6 配置参数详解》
- 定位、功能全景与量化选型对比:《Traq 介绍与选型指南》