Traq 3.8.6 运维命令详解

Traq v3.8.6 运维命令实测手册:服务管理与进程检查、版本确认与升级向导、mysqldump 备份恢复演练、日志与 FPM 参数、API 只读端点实测,以及建单 500 等五则排障实录。

TraqTraqDevOps工程Ubuntu22.042026/10/28

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,示例 IP 192.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 无回显即成功,失败时返回非零退出码
服务作用配置位置
nginxWeb 入口、静态资源、PHP 反代/etc/nginx/sites-available/traq.conf
php8.3-fpmPHP 进程池,执行 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 表用 contents longtext 字段存附件内容、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/typesstatuses、/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 已实测存在的上游问题)。

八、系列文档导航