本地测试调试
提交应用前,必须在TNAS 设备上全面测试完整生命周期。
TOS7 开发环境快速搭建:
-
选项 A:Ubuntu 22.04 虚拟机(推荐)
- 下载 VirtualBox 或 VMware
- 从 TOS 开发者平台导入官方 TOS7 开发者虚拟机
- 虚拟机包含预配置的 TOS7 工具和模拟服务
-
选项 B:基于 Docker 的开发容器
docker run -it --name tos7-dev -v $(pwd):/workspace ubuntu:22.04 /bin/bash
apt-get update && apt-get install -y dpkg-dev lintian systemd -
选项 C:物理 TNAS 设备(用于最终测试)
- 提交前必须在实际设备上进行最终验证
- 必须运行 TOS 7.0 或更高版本
- 开启 SSH 访问以进行调试
Deb 应用测试
# 1. 安装 deb 包
sudo dpkg -i <appid>_<version>_amd64.deb
# 2. 检查服务是否运行
sudo systemctl status <appid>
# 3. 查看服务日志(实时)
sudo journalctl -u <appid> -f
# 4. 查看近期日志
sudo journalctl -u <appid> --since "1 hour ago"
# 5. 检查 Web UI 是否可访问(Web 应用)
curl http://localhost:<端口>
# 6. 测试启停
sudo systemctl stop <appid>
sudo systemctl start <appid>
sudo systemctl restart <appid>
# 7. 测试卸载
sudo dpkg --remove <appid> # 保留配置
sudo dpkg --purge <appid> # 完全删除
# 8. 验证清理(无残留文件/服务)
systemctl list-unit-files | grep <appid>
# 检查运行时数据目录
ls /Volume*/@apps/<appid> 2>/dev/null
# 检查持久化数据(共享文件夹)
ls /Volume*/<appid> 2>/dev/null
# 检查系统用户
id <appid> 2>/dev/null
# 9. 测试升级路径
sudo dpkg -i <appid>_0.9.0_amd64.deb # 安装旧版本
# ... 向 /Volume*/<appid>/ 添加一些数据 ...
sudo dpkg -i <appid>_1.0.0_amd64.deb # 升级到新版本
# 验证数据已保留并迁移
注意:
/Volume*/中的*代表用户在安装时选择的卷编号(例如 Volume1、Volume2)。
/Volume*/@apps/<appid>/— 应用运行时数据(日志、缓存、临时文件)/Volume*/<appid>/— 持久化用户数据(共享文件夹,由应用创建)
Docker 应用测试
# 1. 确保 DockerEngine 已安装并运行
# Docker Engine 可在 TOS 应用中心获取 — 如未安装,系统将提示用户进行安装。
sudo systemctl status docker
# 2. 启动应用
docker-compose -f docker-compose.yml up -d
# 3. 检查容器状态
docker ps | grep <appid>
# 4. 查看容器日志(实时)
docker logs -f <appid>
# 5. 检查资源使用
docker stats <appid>
# 6. 检查 Web UI 是否可访问
curl http://localhost:<端口>
# 7. 测试停止/重启
docker-compose -f docker-compose.yml down
docker-compose -f docker-compose.yml up -d
# 8. 测试数据持久化
docker-compose -f docker-compose.yml down
docker-compose -f docker-compose.yml up -d
# 验证数据仍然存在于 /Volume*/DockerAppData/<appid>/ 和 /Volume*/<appid>/
# 9. 测试健康检查
docker inspect --format='{{.State.Health.Status}}' <appid>
# 10. 清理
docker-compose -f docker-compose.yml down -v
开发者调试工具包
一键调试脚本:
保存为 debug.sh 并运行以验证你的应用:
#!/bin/bash
if [ -z "$1" ]; then
echo "用法: $0 <appid>"
exit 1
fi
APPID="$1"
echo "=== TOS7 应用调试: $APPID ==="
echo "--- 服务状态 ---"
systemctl status "$APPID" 2>/dev/null || echo "未找到服务"
echo "--- 进程 ---"
pgrep -a -f "/Volume*/@apps/$APPID/" 2>/dev/null || echo "未找到相关进程"
echo "--- 端口 ---"
ss -tlnp | grep "$APPID"
echo "--- 运行时数据目录 ---"
ls -laR "/Volume*/@apps/$APPID/" 2>/dev/null
echo "--- 持久化数据(共享文件夹) ---"
ls -laR "/Volume*/$APPID/" 2>/dev/null
echo "--- 近期错误 ---"
journalctl -u "$APPID" -p err --since "10 minutes ago" --no-pager
echo "--- 磁盘使用 ---"
du -sh "/Volume*/@apps/$APPID/" "/Volume*/$APPID/" 2>/dev/null
echo "=== 调试完成 ==="
服务调试
# 验证服务文件是否有效
systemd-analyze verify /etc/systemd/system/<appid>.service
# 检查服务依赖
systemd-analyze dump | grep -A5 <appid>
# 检查端口监听
ss -tlnp | grep <端口>
# 检查进程详情
ps aux | grep <appid>
# 检查运行时数据目录
ls -laR /Volume*/@apps/<appid>/
# 检查持久化数据(共享文件夹)
ls -laR /Volume*/<appid>/
# 查看 systemd 错误日志
journalctl -u <appid> -p err
# 查看系统日志
grep <appid> /var/log/syslog
Docker 调试
# 进入运行中的容器
docker exec -it <appid> /bin/sh
# 检查容器详情
docker inspect <appid>
# 检查资源限制
docker stats --no-stream <appid>
# 检查网络
docker network ls
docker network inspect <网络名>
# 查看容器文件系统变更
docker diff <appid>
# 查看镜像层
docker history <镜像>
快速开发循环
开发过程中快速迭代:
# Deb 应用:快速重装
sudo dpkg --purge <appid> && sudo dpkg -i <appid>_<version>_amd64.deb
# Docker 应用:快速重建
docker-compose down && docker-compose up -d --build
# 测试时同时查看日志
journalctl -u <appid> -f & # Deb
docker logs -f <appid> & # Docker
常见问题与解决方案
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 服务启动失败 | 缺少依赖或路径错误 | 检查 journalctl -u <appid>,验证 ExecStart 路径 |
| 端口冲突 | 其他服务占用同一端口 | ss -tlnp | grep <端口>,更换可用端口 |
| 权限拒绝 | 文件归属或权限不正确 | 验证服务文件中的 User/Group,检查文件归属 |
| Web UI 不可访问 | 服务未监听或防火墙阻止 | 检查服务是否运行,验证端口绑定(0.0.0.0 而非 127.0.0.1) |
| 容器立即退出 | 容器内应用错误 | docker logs <appid>,检查 entrypoint/command |
| 重启后数据丢失 | 未配置卷挂载 | 在 docker-compose.yml 中添加卷映射 |
| TOS 更新后应用异常 | ABI 变更或服务冲突 | 检查 low_version,在新 TOS 版本上测试 |
| 配置未加载 | 配置路径或权限错误 | 验证 WorkingDirectory 和配置文件路径 |
| 升级后配置权限丢失 | postinst 中未重新应用 chown/chmod | 在 postinst 脚本中添加 chown -R <appid>:<appid> |
| Socket 文件残留导致启动失败 | 上次运行未清理的 socket | 启动服务前添加 rm -f /var/api/<appid>.sock |
| Nginx 重载失败 | Nginx 配置语法无效 | 重载前用 nginx -t 验证 |
| Docker 卷权限不正确 | 宿主机与容器 UID/GID 不匹配 | 使用与宿主机用户匹配的 PUID/PGID 环境变量 |
| 网络就绪前服务启动 | systemd 单元缺少 After=network.target | 添加 After=network.target 和 Wants=network.target |
| Deb 因未满足依赖而无法安装 | DEBIAN/control 缺少 Depends | 缺少系统库依赖 → 在 Depends(DEBIAN/control)中添加对应包名;缺少其他应用依赖 → 在 config.ini 的 depend 字段中添加 |