Files
auto_control/.env.example
T
butubb f22263ab45 feat: 数据库连接层改造——库目标由 .env 装配 + 环境防呆(迁 MySQL 第一步)
为把数据库从单文件 SQLite 迁到 MySQL 5.7 铺路。本期不改后端:
DB_HOST 为空时仍走 SQLite,本地开发无感。

- config.py: 新增 DEPLOY_ENV(默认 dev)与 DB_HOST/PORT/USER/PASSWORD/NAME/
  CHARSET/COLLATION、DATABASE_URL、两个逃生阀(DB_ALLOW_ENV_MISMATCH /
  DB_ALLOW_SQLITE_FALLBACK)
- core/db_config.py(新增): URI 组装;按方言分叉的引擎参数(utf8mb4、
  pool_pre_ping、pool_recycle=1800、READ COMMITTED、STRICT_TRANS_TABLES);
  连接探活;app_meta 方言中立读写(MySQL 里 key 是保留字,需反引号)
- 防混库三层: ①库名与环境绑定(dev→auto_control_dev / prod→auto_control)
  ②库标签 app_meta.deployment_env 与 .env 声明比对 ③启动横幅打印当前库
  (生产用 WARNING 级)。不符直接拒绝启动并说明两边分别是什么
- web_server.py: 硬编码 sqlite URI → db_config;配置错在装配期就 exit 2;
  init_db 之后跑库标签校验 + 横幅
- core/models.py: PRAGMA 监听器加 sqlite 类型守卫——它挂在 Engine 基类上,
  MySQL 连接执行 PRAGMA 会直接导致建连失败
- requirements.txt 加 PyMySQL;scripts/start.sh 依赖守卫加 pymysql,
  并在 exec 前打印 DEPLOY_ENV/DB_NAME/DB_HOST
- .env.example 新增「数据库」段;DEVELOPMENT.md §4.1/4.2、DEPLOY.md §2.2 同步

验证: 用 DATABASE_URL 指向 users.db 的一致快照副本跑通主要只读接口
(health/devices/jobs/pool/groups/discovery/summary 全 200,app_meta 读写正常);
DEPLOY_ENV=prod 且无 DB_HOST 时退出码 2;开 DB_ALLOW_SQLITE_FALLBACK 后可回退。
2026-09-13 10:27:14 +08:00

119 lines
5.8 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ==============================================================================
# auto_control 环境变量示例
# - 复制为项目根目录的 .env 再按需修改(.env 已被 .gitignore 排除,不会进 git)
# - 加载方式:config.py 逐行解析后用 os.environ.setdefault 注入
# → 因此"真实环境变量"优先于 .env(容器/CI 里用 env 覆盖更方便)
# - 标【必须】的项务必设置;其余留空即用代码默认值
# - 完整说明见 doc/DEVELOPMENT.md §4 配置速查、doc/DEPLOY.md §2.2
# ==============================================================================
# ==================== 数据库 ====================
# 平台用 MySQL(正式用法)。DEPLOY_ENV 声明"这份配置连的是哪个环境的库",
# 并与库名一一绑定,启动时会互相校验,不符直接拒绝启动:
# DEPLOY_ENV=dev → 期望库名 auto_control_dev(本地开发,可随意折腾)
# DEPLOY_ENV=prod → 期望库名 auto_control (正式数据)
# 首次连接的库会被打上环境标签(app_meta.deployment_env);标签与 DEPLOY_ENV
# 不符时拒绝启动——这是防止「开发配置连到生产库」的最后一道闸。
DEPLOY_ENV=dev
DB_HOST=
DB_PORT=3306
DB_USER=
DB_PASSWORD=
DB_NAME=auto_control_dev
# 排序规则用 _bin(逐码点比较,等价 SQLite 的大小写敏感语义),别改成 _general_ci
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_bin
# 完整连接串:优先级最高,用于脚本临时指向别的库(一般不用配)
# DATABASE_URL=mysql+pymysql://user:pass@host:3306/auto_control_dev?charset=utf8mb4
# 逃生阀(默认关,仅在明确知道后果时打开)
# DB_ALLOW_ENV_MISMATCH=1 环境与库名/库标签不符时仍启动(危险)
# DB_ALLOW_SQLITE_FALLBACK=1 生产环境 DB_HOST 为空时允许回退 SQLite(回滚用)
# DB_ALLOW_ENV_MISMATCH=0
# DB_ALLOW_SQLITE_FALLBACK=0
# ==================== Web 服务 ====================
# 会话密钥【必须,生产务必固定】:不配则每次启动随机生成,重启后登录态失效。
# 生成:python -c "import secrets; print(secrets.token_hex(32))"
WEB_SECRET_KEY=请填写随机密钥
# 监听地址与端口是 config.py 里的常量(不进 .env):WEB_HOST=0.0.0.0、WEB_PORT=18050
# 需要修改直接改 config.py(18050 是为了避开 Windows 动态端口段)
# ==================== 设备与 adb ====================
# USB 设备(serial 无冒号)所在的部署机 —— 平台经它的 adb server 驱动这些设备。
# 默认 100.100.10.1:5037(220 的 Tailscale IP + adb 容器端口,host 网络模式)。
# USB_ADB_HOST=100.100.10.1
# USB_ADB_PORT=5037
# 设备自动发现(扫描网段找开放 5555 的设备)。
# 扫描网段在「工具 → 设备池管理」界面里配置(存数据库 app_meta),此处只管端口与周期。
# DISCOVERY_PORT=5555
# DISCOVERY_INTERVAL=60
# 把本机的 adb 客户端指向远程 adb server(注意:这三个键由 adb/adbutils 自己读取,
# 不是本项目代码读的;两个变量名都要设,adb 实际认 ADDRESS,部分库读 HOST)。
# 用途:让本机 adb 直接看到 220 侧插着的 USB 设备。
# ANDROID_ADB_SERVER_ADDRESS=192.168.20.220
# ANDROID_ADB_SERVER_HOST=192.168.20.220
# ANDROID_ADB_SERVER_PORT=5037
# ==================== Tailscale 管理(工具 → Tailscale 管理) ====================
# API key:Tailscale 后台 → Settings → API Access Tokens 生成
TAILSCALE_API_KEY=请填写Tailscale_API_key
# tailnet 名/ID(一般填登录邮箱,如 [email protected])
# [email protected]
# ==================== MCP Server(外部 AI 接入,:8033) ====================
# 注意:mcp_server 只读进程环境变量,**不读本文件**!
# 容器场景由 scripts/start.sh 用下面这些变量拉起进程;
# 本机手动启动请直接在命令行前加环境变量(见 doc/MCP.md §2)。
#
# MCP_ENABLED=1 # 仅 start.sh 消费:=0 则不自动拉起 MCP
# MCP_ALLOW_WRITE=1 # 写操作总开关(0=只读;start.sh 内强制为 1)
# MCP_PLATFORM_URL=http://127.0.0.1:18050
# MCP_PLATFORM_USER=admin
# MCP_PLATFORM_PASS=请填写平台admin密码 # 【改过 admin 密码必须同步,否则 MCP 登录失败】
# MCP_ALLOWED_SERIALS= # 设备白名单(逗号分隔);空=不限制(语义缺口见 backlog)
# MCP_HTTP_HOST=0.0.0.0
# MCP_HTTP_PORT=8033
# MCP_SCREENSHOT_WIDTH=540 # 返回给模型的截图宽度
# MCP_JPEG_QUALITY=70
# MCP_AUDIT_FILE=/tmp/mcp_audit.log
# MCP_PLATFORM_TIMEOUT=30
# ==================== AI Agent(mcp_agent,命令行/独立运行时用) ====================
# 注意:同样只读进程环境变量、不读本文件。
# Web 的「AI 控制台」配置走数据库(app_meta 的 agent_* 键),与本组变量互不影响。
#
# AGENT_API_BASE=https://api.deepseek.com
# AGENT_MODEL=deepseek-v4-flash-vision-exp
# AGENT_API_KEY=请填写模型 API Key
# DEEPSEEK_API_KEY= # AGENT_API_KEY 的兼容别名
# AGENT_MCP_URL=http://127.0.0.1:8033/mcp
# AGENT_DEFAULT_SERIAL=
# AGENT_MAX_STEPS=40
# AGENT_TIMEOUT=120
# AGENT_LANG=zh
# ==================== 开发/测试 ====================
# 设置后不启动 cron 调度器(跑测试脚本时避免真实触发任务、占用设备)
# DISABLE_SCHEDULER=1
# ==============================================================================
# 已废弃的历史配置(STF 已从代码层摘除,下列键代码不再使用,保留仅为兼容旧 .env)
# STF_URL / STF_TOKEN / STF_SSH_TARGET / STF_SSH_PASSWORD /
# STF_DOCKER_CONTAINER / STF_ADB_CONTAINER / STF_SCRIPT_PATH /
# AUTO_RELEASE_STALE_OCCUPY
# 迁移背景见 doc/STF_REMOVAL.md
# ==============================================================================