为把数据库从单文件 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 后可回退。
119 lines
5.8 KiB
Bash
119 lines
5.8 KiB
Bash
# ==============================================================================
|
||
# 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
|
||
# ==============================================================================
|