Files
auto_control/doc/DEPLOY.md
T

11 KiB
Raw Blame History

部署指南

本文介绍如何从零部署 platform-tools 设备自动化后台。


1. 环境准备

1.1 Python 环境

  • Python 3.10+(推荐 3.12)
  • 安装后确认 python --version 和 pip 可用
# 验证
python --version    # 应输出 3.10+
pip --version

1.2 设备池(已摘除 OpenSTF 依赖)

设备池由平台自身管理(SQLite devices 表 + 本机 adb 在线状态),不再依赖 OpenSTF。 新增设备在管理后台「工具 → 设备池管理」添加(serial 形如 100.100.10.x:5555)。

USB 设备(serial 无冒号)插在部署机(220)时,经 220 的 adb server 驱动:

  • 220 的 adb 容器需为 host 网络模式(5037 已监听所有网卡,含 Tailscale)
  • 平台配置 USB_ADB_HOST(默认 100.100.10.1)/ USB_ADB_PORT(默认 5037)

1.3 adb 工具

项目自带 adb 二进制在 bin/adb/ 目录:

  • Windows:bin/adb/adb.exe + 依赖 dll(已包含)
  • Linux:bin/adb/adb(需 chmod +x)
  • macOS:bin/adb/adb(需 chmod +x)

如需替换为自己的 adb 版本,把对应平台的 adb 放进 bin/adb/ 即可,config.py 会自动识别操作系统。

1.4 设备准备

设备需满足:

  • 开启 USB 调试(设置 → 开发者选项)
  • 转网络调试:USB 连上后 adb -s <serial> tcpip 5555(管理后台「adb 终端」有一键快捷命令)
  • 设备加入 Tailscale(同一账号,获得 100.100.10.x IP)
  • 在「工具 → 设备池管理」添加 IP:5555(自动尝试连接,任务运行时 u2 自动推送 atx-agent)

2. 安装部署

2.1 获取代码

# 方式一:直接拷贝项目目录
# 方式二:解压打包文件(python scripts/pack.py 生成的 zip)

2.2 安装依赖

cd platform-tools
pip install -r requirements.txt

依赖清单(requirements.txt):

包 版本 用途
Flask >=2.3,<4.0 Web 框架
Flask-Login >=0.6 用户认证
Flask-SQLAlchemy >=3.0,<4.0 SQLite ORM
APScheduler >=3.10,<4.0 定时调度
requests >=2.28 HTTP 客户端
uiautomator2 >=3.0 Android UI 自动化
uiautodev >=0.14 UI 元素抓取
pyaxmlparser >=0.3.27 APK 元信息解析
rapidocr_onnxruntime >=1.4 屏幕 OCR(条件判断的 OCR识别 选择器,中英文模型随包内置,跨平台)

服务器(无显示器/Linux)环境建议把 opencv-python 换成 opencv-python-headless(rapidocr 依赖 cv2,两者取一)。

uiautomator2 首次连接设备时会自动推送 atx-agent 到设备,无需手动安装。

2.3 修改配置

密钥类配置统一放项目根目录 .env(已被 .gitignore 排除,不会提交到 git; config.py 不再内置任何密钥):

# .env 示例
WEB_SECRET_KEY=随机字符串(会话密钥,python -c "import secrets;print(secrets.token_hex(32))" 生成)
TAILSCALE_API_KEY=你的Tailscale_API_key
# USB_ADB_HOST=100.100.10.1   # 220 的 Tailscale IP(USB 设备远程 adb server,默认值已可用)

其他配置按需调整:

配置项 默认值 何时修改
WEB_HOST 0.0.0.0 仅本机访问改为 127.0.0.1
WEB_PORT 18050 端口冲突时修改
ADB_PATH 自动识别 用自定义 adb 时修改
USB_ADB_HOST 100.100.10.1 USB 设备所在部署机(220)的 Tailscale IP
USB_ADB_PORT 5037 220 adb 容器监听端口(host 网络模式)
TAILSCALE_TAILNET 按邮箱前缀 tailnet 名称/ID(个人账号一般为登录邮箱前缀)

未配置 WEB_SECRET_KEY:启动时随机生成(每次重启登录态失效,生产务必配置固定值)。 工具页 Tailscale 管理前置:.env 写入 TAILSCALE_API_KEY 后重启服务; 未配置时管理分区显示明确提示,不影响其他功能。 (历史遗留的 STF_URL/STF_TOKEN/STF_SSH_* 等配置已废弃,代码不再读取。)

2.4 启动服务

命令行启动

python web_server.py

(推荐配合 scripts/supervise.sh 进程守护,见 3.1 节)

2.5 验证部署

  1. 控制台看到 启动服务: http://localhost:18050/ 即成功
  2. 浏览器访问 http://localhost:18050/
  3. 用 admin/admin123 登录
  4. 监控页应显示 STF 设备池中的设备

3. 生产部署建议

3.1 进程守护

用进程守护工具确保服务自动重启:

Windows(NSSM):

nssm install platform-tools "C:\Python312\python.exe" "D:\platform-tools\web_server.py"
nssm start platform-tools

Linux(systemd):

# /etc/systemd/system/platform-tools.service
[Unit]
Description=Platform Tools Web Server
After=network.target

[Service]
Type=simple
User=www
WorkingDirectory=/opt/platform-tools
ExecStart=/usr/bin/python3 web_server.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

通用脚本(Linux/macOS,无需 systemd):

项目自带 scripts/supervise.sh:web_server 崩溃自动重启、带退避和重启上限(防崩溃死循环)。

# 用 venv 的 python 守护
PYTHON=./.venv/bin/python bash scripts/supervise.sh

进程守护只保证服务重启,不恢复已运行的任务(worker 状态在内存)。

悬空设备自愈:崩溃后残留的设备占用(STF 仍显示占用)可配置启动自动清理。单实例部署时在 .env 设置 AUTO_RELEASE_STALE_OCCUPY=true,web_server 启动会自动释放本账户残留占用;多实例共用 STF 账户时不要开(会误放另一实例的任务)。默认关,仅启动时提示。

Docker(生产 python-app 容器):

docker-compose 已配置 restart: unless-stopped,web_server 进程退出 → 容器退出 → Docker 自动重启。建议再加健康检查,让编排感知服务存活:

# docker-compose.yaml 的 python-app 服务下添加
healthcheck:
  test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:18050/api/health', timeout=3)"]
  interval: 30s
  timeout: 5s
  retries: 3
  start_period: 10s

3.2 反向代理(可选)

如需 HTTPS 或 80 端口,用 Nginx 反向代理:

server {
    listen 80;
    server_name auto.example.com;

    location / {
        proxy_pass http://127.0.0.1:18050;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

3.3 安全加固

  • 修改默认密码:登录后立即在"用户"Tab 修改 admin 密码
  • 最小权限分配:需要多人使用后台时,在"用户"Tab 创建普通用户并只勾选必要权限 (任务管理/设备控制/应用管理/日志查看),不要把 admin 密码共享出去
  • 修改 SECRET_KEY:编辑 web_server.py,把 app.config["SECRET_KEY"] 改成随机字符串
  • 限制访问:生产环境把 WEB_HOST 改为 127.0.0.1,配合反向代理
  • 防火墙:只开放必要端口

3.4 日志管理

  • 日志自动滚动(10MB 一份,保留 5 份)
  • 日志目录 logs/,可在"日志"Tab 在线查看
  • 长期运行建议定期清理或配置 logrotate

3.5 数据备份

  • 数据库 data/users.db 包含用户/分组/任务数据
  • APK 文件在 data/apks/
  • 建议定期备份 data/ 目录

4. 网络配置

4.1 端口说明

端口 服务 说明
18050 Web 后台 主服务端口(config.py 可改)
20242 uiautodev 元素抓取服务(自动启动,固定端口)
7100 STF STF 服务端口(STF 自己的配置)
5555 adb 设备 adb 网络端口(设备端)

4.2 Windows 端口问题(仅 Windows)

Windows 可能将某些端口范围划为动态排除范围,导致绑定失败(WinError 10013)。

# 查看排除的端口范围
netsh interface ipv4 show excludedportrange protocol=tcp

如果 18050 在排除范围内,修改 config.py 的 WEB_PORT 到一个不在排除范围内的端口。

4.3 局域网访问

  • WEB_HOST = "0.0.0.0" 允许局域网访问
  • 需要添加防火墙入站规则(Windows 手动添加,或参考 netsh advfirewall firewall add rule)
  • 局域网其他机器访问 http://部署机IP:18050/

5. 更新升级

5.1 代码更新

# 1. 停止服务
# 2. 替换代码文件(或解压新的 zip)
# 3. 重新安装依赖(如有新增)
pip install -r requirements.txt
# 4. 启动服务
python web_server.py

5.2 数据库迁移

  • SQLite 表结构变化时,init_db() 会自动 db.create_all() 创建新表
  • 旧 groups.json / jobs.json 首次启动自动迁移到 SQLite
  • 迁移后 JSON 文件归档为 .migrated(保留备份,不再迁移)

5.3 注意事项

  • 修改 core/ 目录下的文件后必须重启 web_server(debug=False 不热重载)
  • 修改 templates/ 下的 HTML 文件:Flask 模板默认不缓存,但建议重启确保生效
  • 修改 tasks/ 下的文件后必须重启(任务注册在启动时完成)

6. 故障排查

6.1 启动失败

现象 原因 解决
ModuleNotFoundError: No module named 'flask' 依赖未安装 pip install -r requirements.txt
WinError 10013 端口被排除/权限不足 改端口或用管理员运行
WinError 10048 端口被占用 改端口或杀占用进程
STF 获取设备列表失败 STF 地址/token 错误 检查 config.py 的 STF_URL 和 STF_TOKEN

6.2 设备连接失败

现象 原因 解决
DeviceOfflineError 设备掉线/STF provider 卡死 检查设备网络/STF 状态
u2.connect 超时 atx-agent 无响应 重启设备/重新推送 atx-agent
adb connect failed 设备网络不通/端口未开放 检查设备 IP 和 5555 端口
STF 设备显示离线 STF 状态缓存 用"扫描前台App"复测

6.3 任务不执行

现象 原因 解决
任务列表有任务但不执行 任务未启用 / cron 未到点 检查 enabled 和 schedule
立即执行无反应 无可用设备 检查设备池是否有空闲设备
worker 状态 error 查看日志的 last_error 查看 logs/core.log 和 logs/task.log
看门狗误杀 长操作未心跳 在长循环内加 self.heartbeat()

6.4 日志查看

# 查看核心日志
# 方式一:Web 后台"日志"Tab
# 方式二:直接看文件
# logs/core.log   — STF/adb/worker/task_manager
# logs/task.log   — 任务执行
# logs/web.log    — Web 请求
# logs/action.log — 操作执行