完善开源交付文档与Docker部署安全配置

This commit is contained in:
liuwei
2026-05-07 12:36:16 +08:00
parent 8579b7ec27
commit 4515b605b9
9 changed files with 434 additions and 126 deletions

View File

@@ -15,5 +15,7 @@ temp
# 本地私有配置与运行态文件不进入镜像,避免把真实密钥或登录态烘焙到镜像层。
.env
.env.*
config.yaml
wechat_ipad/config.toml
wechat_ipad/providers/*/runtime_state.toml

View File

@@ -21,8 +21,18 @@ WECHAT_SERVER_URL=http://host.docker.internal:8059/
WECHAT_SERVER_IP=host.docker.internal
WECHAT_SERVER_PORT=8059
WECHAT_SERVER_TYPE=legacy_855
# 当 WECHAT_SERVER_TYPE=server_864 时必须提供。
WECHAT_SERVER_KEY=
WECHAT_WXID=
WECHAT_DEVICE_NAME=
WECHAT_DEVICE_ID=
# 留空时会默认写到 `wechat_ipad/providers/<server_type>/runtime_state.toml`。
WECHAT_STATE_FILE=
# Dashboard / 开源仓库安全项
ABOT_DASHBOARD_USERNAME=admin
ABOT_DASHBOARD_PASSWORD=ChangeThisPassword_2026!
# 建议填入一串随机长字符串,用于 Flask Session 签名。
ABOT_DASHBOARD_SECRET_KEY=
# 如需启用 TrendRadar webhook再显式配置不建议继续使用示例值。
ABOT_TRENDRADAR_WEBHOOK_TOKEN=please_change_this_token

View File

@@ -49,9 +49,14 @@ ENV ABOT_ENVIRONMENT=production \
WECHAT_SERVER_URL=http://127.0.0.1:8059/ \
WECHAT_SERVER_IP=127.0.0.1 \
WECHAT_SERVER_PORT=8059 \
WECHAT_SERVER_KEY= \
WECHAT_WXID= \
WECHAT_DEVICE_NAME=ABOTPad \
WECHAT_DEVICE_ID= \
ABOT_DASHBOARD_USERNAME=admin \
ABOT_DASHBOARD_PASSWORD=ChangeThisPassword_2026! \
ABOT_DASHBOARD_SECRET_KEY= \
ABOT_TRENDRADAR_WEBHOOK_TOKEN=please_change_this_token \
DASHBOARD_HOST=0.0.0.0 \
DASHBOARD_PORT=8888

183
README.MD
View File

@@ -1,28 +1,31 @@
# ABOT
ABOT 是一个基于插件体系构建的微信机器人项目,包含消息处理主链路、管理后台、MySQL/Redis 存储、定时任务与多类 AI / 内容插件能力。当前仓库更适合有一定 Python 与部署基础的维护者进行二次开发、私有部署与功能扩展。
ABOT 是一个面向长期维护的微信机器人项目,包含消息接入、插件体系、管理后台、MySQL / Redis 存储、定时任务以及 AI 扩展能力。
当前仓库已经完成一轮面向开源发布的工程整理,适合用于二次开发、私有部署和多版本 `wechat_ipad server` 接入演进。
## 项目定位
## 项目特点
- 面向“可持续迭代的机器人平台”,不是一次性脚本
- 核心能力包括消息接入、插件化处理、后台管理、数据归档与 AI 扩展
- 当前默认假设你具备 MySQL、Redis、Docker、环境变量配置的基础经验
- 插件化机器人主链路,便于按业务拆分能力
- 自带 Dashboard 管理后台,支持状态查看、插件管理、消息与联系人相关页面
- 支持 `legacy_855` 与 `server_864` 两类 `wechat_ipad server` 适配入口
- 配置统一走 `.env + config.yaml`,登录态运行时状态落到 provider 独立目录
- 提供 Docker / Docker Compose 基础部署骨架,便于快速上线验证
## 当前主要能力
## 当前能力范围
- 微信消息接入与机器人主循环
- 插件加载、启停、热更新与后台管
- MySQL + Redis 存储
- AI 自动回复、消息总结、成员画像等能力
- 签到、积分、排行榜、内容推送、媒体处理等业务插件
- 微信消息接入与实时处理
- 插件加载、启停、热更新
- MySQL + Redis 数据存储
- 联系人、群信息、消息归档、统计与部分运营分析页面
- AI 自动回复、消息总结、成员画像、内容推送等扩展能力
## 快速开始
### 方式一Docker Compose
适合第一次快速跑通部署骨架。
适合第一次快速跑通完整部署骨架。
1. 复制 Docker 环境变量示例
1. 复制 Docker 环境变量模板
```bash
cp .env.docker.example .env
@@ -34,7 +37,16 @@ Windows PowerShell
Copy-Item .env.docker.example .env
```
2. 按实际环境修改 `.env` 中的数据库密码、`WECHAT_SERVER_URL`、`WECHAT_SERVER_TYPE` 等参数
2. 至少修改以下变量
- `ABOT_DB_PASSWORD`
- `WECHAT_SERVER_URL`
- `WECHAT_SERVER_IP`
- `WECHAT_SERVER_PORT`
- `WECHAT_SERVER_TYPE`
- `WECHAT_SERVER_KEY`:仅 `server_864` 必填
- `ABOT_DASHBOARD_PASSWORD`
- `ABOT_DASHBOARD_SECRET_KEY`
3. 启动服务
@@ -42,13 +54,19 @@ Copy-Item .env.docker.example .env
docker compose up -d --build
```
更多说明见 [docs/Docker部署说明.md](/d:/learn/abot/docs/Docker部署说明.md:1)。
4. 访问 Dashboard
- 默认地址:`http://127.0.0.1:8888`
- 默认用户名:`admin`
- 默认密码以你的 `.env` 中 `ABOT_DASHBOARD_PASSWORD` 为准
更完整的上线说明见 [docs/Docker部署说明.md](/d:/learn/abot/docs/Docker部署说明.md:1)。
### 方式二:本地直跑
1. 准备 Python 3.10+
2. 准备 MySQL、Redis
3. 复制配置文件
3. 复制配置模板
```bash
cp config.example.yaml config.yaml
@@ -71,40 +89,57 @@ pip install -r requirements.txt
pip install pysilk-mod
```
5. 启动主程序
5. 启动项目
```bash
python main.py
```
## 配置说明
## 配置约定
### 全局配置
### 静态配置
项目支持从 `.env` 自动加载环境变量,并在 [config.example.yaml](/d:/learn/abot/config.example.yaml:1) / `config.yaml` 中使用
推荐只维护以下两类文件
- `${ENV_NAME}`
- `${ENV_NAME:默认值}`
- `.env`
- `config.yaml`
示例:
- `${ABOT_DB_PASSWORD}`:必须提供
- `${ABOT_DB_HOST:127.0.0.1}`:可缺省时回退
`config.yaml` 支持 `${ENV_NAME}` / `${ENV_NAME:default}` 占位符,因此更推荐把敏感配置写进 `.env`,把结构与默认值保留在 YAML 模板里。
### wechat_ipad 配置
现在 `wechat_ipad` 的静态连接参数已经统一走 `.env` / `config.yaml`
当前 `wechat_ipad` 的静态连接配置统一走环境变量
- `WECHAT_SERVER_URL`
- `WECHAT_SERVER_IP`
- `WECHAT_SERVER_PORT`
- `WECHAT_SERVER_TYPE`
- `WECHAT_SERVER_KEY`:仅 `server_864` 必填
登录后的 `wxid / device_id / device_name` 不再要求你手工维护,它们会自动写入本地状态文件
运行时状态不再要求工维护,会自动写
- 默认路径:`wechat_ipad/providers/<server_type>/runtime_state.toml`
- 可通过 `WECHAT_STATE_FILE` 覆盖
- 启动时会自动兼容历史 `wechat_ipad/config.toml` 中已有的登录态
- `wechat_ipad/providers/<server_type>/runtime_state.toml`
这意味着:
- 每个 provider 的登录态彼此隔离
- 切换 `855 / 864` 不会默认串用同一份状态
- 开源仓库不需要再长期维护多份分散配置文件
## Docker 交付说明
当前仓库已经提供以下开源友好交付物:
- [Dockerfile](/d:/learn/abot/Dockerfile:1)
- [docker-compose.yml](/d:/learn/abot/docker-compose.yml:1)
- [docker-entrypoint.sh](/d:/learn/abot/docker-entrypoint.sh:1)
- [.env.docker.example](/d:/learn/abot/.env.docker.example:1)
容器化方案的边界是:
- `abot`、`mariadb`、`redis` 已拆成独立服务
- `wechat_ipad server` 仍建议跑在宿主机或独立机器
- Dashboard 账号、密码、Session Secret、Webhook Token 都支持环境变量覆盖
## 目录结构
@@ -112,11 +147,11 @@ python main.py
abot/
├── admin/ # 管理后台
├── base/ # 插件基础接口与管理能力
├── db/ # 数据库访问层与迁移脚本
├── docs/ # 部署、设计、使用文档
├── db/ # 数据库访问层与 SQL 脚本
├── docs/ # 部署、设计与路线图文档
├── plugins/ # 业务插件
├── utils/ # 通用工具与服务
├── wechat_ipad/ # 微信相关客户端与 server 对接代码
├── wechat_ipad/ # 微信接入与 provider 适配层
├── Dockerfile
├── docker-compose.yml
├── config.example.yaml
@@ -124,64 +159,68 @@ abot/
└── main.py
```
## 管理后台
## Dashboard 与默认安全项
- 默认端口:`8888`
- 配置文件:[`admin/dashboard/config.toml`](/d:/learn/abot/admin/dashboard/config.toml:1)
- 公开仓库中的账号密码与 webhook token 已改为占位值,部署前务必自行修改
Dashboard 默认配置文件位于 [admin/dashboard/config.toml](/d:/learn/abot/admin/dashboard/config.toml:1)。
## Docker 化现状
为了适配公开仓库,这一层已经做了两件事:
本仓库现在提供的是“开源友好”的基础部署骨架:
- 仓库中的默认密码已不再使用弱口令 `admin123`
- Docker / 环境变量可以直接覆盖后台账号、密码和 webhook token
- 应用、MariaDB、Redis 已拆分为独立服务
- 提供 `docker-compose.yml`、`.dockerignore`、`.env.docker.example`
- 静态连接配置统一通过 `.env` 注入,更适合开源仓库和多环境部署
- wechat 登录态缓存默认落到对应 provider 目录下
正式部署前仍建议你明确设置:
当前仍建议你在正式生产前继续补充:
- `ABOT_DASHBOARD_USERNAME`
- `ABOT_DASHBOARD_PASSWORD`
- `ABOT_DASHBOARD_SECRET_KEY`
- `ABOT_TRENDRADAR_WEBHOOK_TOKEN`
- HTTPS / 反向代理
- 备份策略
- CI/CD
- 监控与告警
## License 与开源边界
## 开源说明
### 主许可证
### License 要不要改
当前仓库主代码采用 [MIT License](/d:/learn/abot/LICENSE:1)。
当前主代码仍按 MIT License 分发,通常不必为了“开源”单独换许可证。
一般情况下,不需要为了“把仓库开源”额外改成别的许可证;但你仍需要确认两件事:
但你需要额外关注:
1. `LICENSE` 中的版权主体是否就是你希望公开使用的名字
2. 仓库里的第三方资源、字体、二进制是否都允许再分发
- 字体文件的再分发许可
- `wechat_ipad/ipad859go` 二进制来源与授权
- `resource/` 下业务资料是否适合公开
- 第三方前端静态资源的许可证保留
相关说明见 [THIRD_PARTY_LICENSES.md](/d:/learn/abot/THIRD_PARTY_LICENSES.md:1)。
详情见 [THIRD_PARTY_LICENSES.md](/d:/learn/abot/THIRD_PARTY_LICENSES.md:1)。
### 不建议公开提交的内容
### 不建议直接公开提交的内容
- `.env`
- `config.yaml`
- `wechat_ipad/providers/*/runtime_state.toml` 中的真实 `wxid` / `device_id`
- `wechat_ipad/providers/*/runtime_state.toml`
- 真实数据库密码、LLM API Key、Webhook Token
- 未确认授权来源的字体、二进制与业务素材
## 已知仍需你自行确认的事项
以下内容我已经在文档中标出来,但不适合由我直接替你做法律判断:
- `LICENSE` 版权主体是否需要改成你当前对外公开的名称
- `fonts/` 下字体文件的再分发许可
- `wechat_ipad/ipad859go` 的来源与授权
- `resource/` 目录中的业务资料是否适合公开仓库传播
## 路线图
当前更优先的方向不是继续无上限堆新功能,而是继续补工程底座
当前更值得优先推进的方向
- Docker 化与部署规范
- 文档与回归清单
- 插件治理
- 可观测性与任务中心
- 开源边界与资产合规
- 继续完善 `864 provider` 真机联调与高频接口覆盖
- 补齐 Docker / 部署回归清单
- 插件治理、任务中心、可观测性增强
- 开源资产合规清点
已整理的工程 backlog 见 [docs/工程优化与Feature清单.md](/d:/learn/abot/docs/工程优化与Feature清单.md:1)。
已整理的工程规划文档:
## 贡献与使用说明
- [docs/工程优化与Feature清单.md](/d:/learn/abot/docs/工程优化与Feature清单.md:1)
- [docs/wechat_ipad多版本Server适配路线图.md](/d:/learn/abot/docs/wechat_ipad多版本Server适配路线图.md:1)
- 欢迎基于自己的场景二次开发
- 提交前请避免把本地私有配置、运行日志、登录态一并提交
- 涉及平台接口、内容抓取、自动推送等能力时,请自行评估目标平台规则与当地法律要求
## 使用与贡献说明
- 欢迎按自己的场景二次开发
- 提交代码前请确认未误带本地私有配置、日志和登录态
- 涉及内容抓取、自动推送、第三方平台接口的能力,请自行评估合规与风控要求

View File

@@ -4,13 +4,18 @@ port = 8888
[auth]
username = "admin"
password = "admin123"
# 公开仓库不再提供弱默认密码:
# 1. 新部署环境首次启动时会自动把这里的账号信息播种到后台管理员表;
# 2. 若你的数据库里已经存在管理员账号,则后续以数据库中的真实密码为准;
# 3. 正式环境建议继续通过环境变量覆盖,而不是长期使用仓库示例值。
password = "ChangeThisPassword_2026!"
[trendradar_webhook]
# 是否启用 TrendRadar webhook 适配接口
enabled = true
# 固定 token建议配置支持请求头 X-Webhook-Token / query token / payload.token 三种传法
token = "watHcBbQIxtmyqGRSHKeTDRVjkHOceiRfFytUkQUwmV"
enabled = false
# 固定 token建议配置支持请求头 X-Webhook-Token / query token / payload.token 三种传法
# 仓库中的值仅为占位示例,正式环境请改成你自己的随机长 token。
token = "please_change_this_token"
# 默认推送目标群(可配置多个)
default_group_ids = []
# 是否允许 payload 覆盖目标群(开启后可通过 target_group_ids/group_id 指定)

View File

@@ -153,23 +153,146 @@ class DashboardServer:
config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.toml')
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
return toml.load(f)
config_data = toml.load(f)
else:
# 如果配置文件不存在,创建默认配置
default_config = {
config_data = {
"server": {"host": "0.0.0.0", "port": 8888},
"auth": {"username": "admin", "password": "admin123"}
"auth": {"username": "admin", "password": "ChangeThisPassword_2026!"},
"trendradar_webhook": {
"enabled": False,
"token": "please_change_this_token",
"default_group_ids": [],
"allow_payload_target_groups": False,
"send_timeout_seconds": 20,
},
}
with open(config_path, 'w', encoding='utf-8') as f:
toml.dump(default_config, f)
return default_config
toml.dump(config_data, f)
return self._apply_dashboard_env_overrides(config_data)
except Exception as e:
self.LOG.error(f"加载Dashboard配置文件失败: {e}")
# 这里属于 Dashboard 构造早期阶段:
# 1. `self.LOG` 还没在 `__init__` 中完成赋值;
# 2. 若此时配置文件损坏,仍然需要把错误稳定打印出来;
# 3. 因此这里直接回退到模块级 logger避免异常再次被属性缺失覆盖。
logger.error(f"加载Dashboard配置文件失败: {e}")
# 返回默认配置
return {
fallback_config = {
"server": {"host": "0.0.0.0", "port": 8888},
"auth": {"username": "admin", "password": "admin123"}
"auth": {"username": "admin", "password": "ChangeThisPassword_2026!"},
"trendradar_webhook": {
"enabled": False,
"token": "please_change_this_token",
"default_group_ids": [],
"allow_payload_target_groups": False,
"send_timeout_seconds": 20,
},
}
return self._apply_dashboard_env_overrides(fallback_config)
@staticmethod
def _safe_env_bool(value, default: bool) -> bool:
"""把环境变量里的开关值安全转成布尔值。"""
if value in (None, ""):
return default
text = str(value).strip().lower()
if text in {"1", "true", "yes", "y", "on"}:
return True
if text in {"0", "false", "no", "n", "off"}:
return False
return default
@staticmethod
def _safe_env_int(value, default: int) -> int:
"""把环境变量里的数字安全转成整数。"""
try:
if value in (None, ""):
return default
return int(value)
except (TypeError, ValueError):
return default
@staticmethod
def _safe_env_group_ids(value) -> list[str]:
"""把逗号分隔的群列表环境变量转成数组。"""
raw_text = str(value or "").strip()
if not raw_text:
return []
return [item.strip() for item in raw_text.split(",") if item.strip()]
def _apply_dashboard_env_overrides(self, config_data: dict) -> dict:
"""用环境变量覆盖 Dashboard 配置中的敏感项与部署项。"""
merged_config = dict(config_data or {})
merged_config["server"] = dict(merged_config.get("server", {}) or {})
merged_config["auth"] = dict(merged_config.get("auth", {}) or {})
merged_config["trendradar_webhook"] = dict(merged_config.get("trendradar_webhook", {}) or {})
# 这里优先让运维通过环境变量覆盖后台配置:
# 1. Docker / PaaS 场景下更容易统一管理账号、端口与 token
# 2. 也避免公开仓库里的示例 TOML 被误当成最终生产配置;
# 3. 未配置环境变量时仍回退到本地文件,兼容现有非容器部署方式。
server_section = merged_config["server"]
auth_section = merged_config["auth"]
webhook_section = merged_config["trendradar_webhook"]
server_section["host"] = str(os.environ.get("DASHBOARD_HOST", server_section.get("host", "0.0.0.0")) or "0.0.0.0")
server_section["port"] = self._safe_env_int(
os.environ.get("DASHBOARD_PORT", server_section.get("port", 8888)),
8888,
)
auth_section["username"] = str(
os.environ.get("ABOT_DASHBOARD_USERNAME", auth_section.get("username", "admin")) or "admin"
).strip()
auth_section["password"] = str(
os.environ.get("ABOT_DASHBOARD_PASSWORD", auth_section.get("password", "ChangeThisPassword_2026!"))
or "ChangeThisPassword_2026!"
)
auth_section["session_timeout_minutes"] = self._safe_env_int(
os.environ.get("ABOT_DASHBOARD_SESSION_TIMEOUT_MINUTES", auth_section.get("session_timeout_minutes", 480)),
480,
)
auth_section["max_failed_attempts"] = self._safe_env_int(
os.environ.get("ABOT_DASHBOARD_MAX_FAILED_ATTEMPTS", auth_section.get("max_failed_attempts", 5)),
5,
)
auth_section["lock_seconds"] = self._safe_env_int(
os.environ.get("ABOT_DASHBOARD_LOCK_SECONDS", auth_section.get("lock_seconds", 900)),
900,
)
auth_section["cookie_secure"] = self._safe_env_bool(
os.environ.get("ABOT_DASHBOARD_COOKIE_SECURE", auth_section.get("cookie_secure", False)),
False,
)
auth_section["cookie_samesite"] = str(
os.environ.get("ABOT_DASHBOARD_COOKIE_SAMESITE", auth_section.get("cookie_samesite", "Lax")) or "Lax"
).strip()
webhook_section["enabled"] = self._safe_env_bool(
os.environ.get("ABOT_TRENDRADAR_WEBHOOK_ENABLED", webhook_section.get("enabled", False)),
False,
)
webhook_section["token"] = str(
os.environ.get("ABOT_TRENDRADAR_WEBHOOK_TOKEN", webhook_section.get("token", "")) or ""
).strip()
env_default_groups = os.environ.get("ABOT_TRENDRADAR_DEFAULT_GROUP_IDS", "")
if env_default_groups not in (None, ""):
webhook_section["default_group_ids"] = self._safe_env_group_ids(env_default_groups)
webhook_section["allow_payload_target_groups"] = self._safe_env_bool(
os.environ.get(
"ABOT_TRENDRADAR_ALLOW_PAYLOAD_TARGET_GROUPS",
webhook_section.get("allow_payload_target_groups", False),
),
False,
)
webhook_section["send_timeout_seconds"] = self._safe_env_int(
os.environ.get(
"ABOT_TRENDRADAR_SEND_TIMEOUT_SECONDS",
webhook_section.get("send_timeout_seconds", 20),
),
20,
)
return merged_config
def _create_app(self) -> Flask:
"""创建Flask应用"""

View File

@@ -81,10 +81,15 @@ services:
WECHAT_SERVER_IP: ${WECHAT_SERVER_IP:-host.docker.internal}
WECHAT_SERVER_PORT: ${WECHAT_SERVER_PORT:-8059}
WECHAT_SERVER_TYPE: ${WECHAT_SERVER_TYPE:-legacy_855}
WECHAT_SERVER_KEY: ${WECHAT_SERVER_KEY:-}
WECHAT_WXID: ${WECHAT_WXID:-}
WECHAT_DEVICE_NAME: ${WECHAT_DEVICE_NAME:-}
WECHAT_DEVICE_ID: ${WECHAT_DEVICE_ID:-}
WECHAT_STATE_FILE: ${WECHAT_STATE_FILE:-}
ABOT_DASHBOARD_USERNAME: ${ABOT_DASHBOARD_USERNAME:-admin}
ABOT_DASHBOARD_PASSWORD: ${ABOT_DASHBOARD_PASSWORD:-ChangeThisPassword_2026!}
ABOT_DASHBOARD_SECRET_KEY: ${ABOT_DASHBOARD_SECRET_KEY:-}
ABOT_TRENDRADAR_WEBHOOK_TOKEN: ${ABOT_TRENDRADAR_WEBHOOK_TOKEN:-please_change_this_token}
ports:
- "${DASHBOARD_PORT:-8888}:8888"
volumes:

View File

@@ -52,6 +52,11 @@ wechat_ipad:
server_ip: "\${WECHAT_SERVER_IP:host.docker.internal}"
server_port: "\${WECHAT_SERVER_PORT:8059}"
server_type: "\${WECHAT_SERVER_TYPE:legacy_855}"
# 864 风格 server 依赖固定 key这里一并写入自动生成的配置模板
# 1. 避免容器部署场景下还要手工进容器补 config.yaml
# 2. 855/859 保持可留空,不影响现有默认行为;
# 3. 真正的值仍由 `.env` / compose 环境变量注入,不会写死在镜像层。
server_key: "\${WECHAT_SERVER_KEY:}"
wxid: "\${WECHAT_WXID:}"
device_name: "\${WECHAT_DEVICE_NAME:}"
device_id: "\${WECHAT_DEVICE_ID:}"
@@ -60,6 +65,34 @@ wechat_ipad:
EOF
fi
# Dashboard 单独使用 config.toml
# 1. 公开仓库里的默认账号和 webhook token 不适合作为最终线上值;
# 2. 这里允许通过环境变量在容器启动期覆盖默认配置,降低“改完 .env 还要再改一份 TOML”的成本
# 3. 若用户自己挂载了定制版 config.toml也仍然可以继续复用因为运行时还会再做环境变量兜底覆盖。
if [ ! -f /app/admin/dashboard/config.toml ]; then
cat > /app/admin/dashboard/config.toml <<EOF
[server]
host = "0.0.0.0"
port = ${DASHBOARD_PORT:-8888}
[auth]
username = "${ABOT_DASHBOARD_USERNAME:-admin}"
password = "${ABOT_DASHBOARD_PASSWORD:-ChangeThisPassword_2026!}"
session_timeout_minutes = 480
max_failed_attempts = 5
lock_seconds = 900
cookie_secure = false
cookie_samesite = "Lax"
[trendradar_webhook]
enabled = false
token = "${ABOT_TRENDRADAR_WEBHOOK_TOKEN:-please_change_this_token}"
default_group_ids = []
allow_payload_target_groups = false
send_timeout_seconds = 20
EOF
fi
# wechat_ipad 登录态现在默认落到 provider 自己目录下:
# 1. 静态连接配置已统一走 `.env` / `config.yaml`
# 2. 855 当前默认会写到 `wechat_ipad/providers/legacy_855/runtime_state.toml`

View File

@@ -1,25 +1,24 @@
# ABOT Docker 部署说明
本文档面向希望通过 Docker / Docker Compose 快速启动 ABOT 的维护者。
本文档面向希望通过 Docker / Docker Compose 快速部署 ABOT 的维护者,重点覆盖首次启动、`855 / 864` 配置差异、Dashboard 安全项以及常见上线注意点
## 1. 部署架构
当前仓库提供的 Compose 方案拆分为三个服务:
当前 Compose 方案拆分为三个服务:
- `abot`应用主程序与管理后台
- `abot`:主程序与管理后台
- `mariadb`MySQL 兼容数据库
- `redis`:缓存与运行时状态存储
说明:
- `wechat_ipad server` 仍建议在宿主机或独立机器,不直接内置到应用容器中
- `abot` 容器通过 `WECHAT_SERVER_URL` / `WECHAT_SERVER_IP` 连接该服务
- `wechat_ipad server` 仍建议运行在宿主机或独立机器
- `abot` 容器通过 `WECHAT_SERVER_URL / WECHAT_SERVER_IP / WECHAT_SERVER_PORT` 连接该服务
- 宿主机上的 `./wechat_ipad/providers` 会映射到容器内,用于保留各 provider 的运行时登录态
## 2. 首次启动
## 2. 首次部署
### 2.1 准备环境变量
复制示例文件:
### 2.1 复制环境变量模板
```bash
cp .env.docker.example .env
@@ -31,14 +30,29 @@ Windows PowerShell
Copy-Item .env.docker.example .env
```
至少确认以下变量
### 2.2 至少修改这些变量
基础项:
- `ABOT_DB_PASSWORD`
- `DASHBOARD_PORT`
- `ABOT_DASHBOARD_PASSWORD`
- `ABOT_DASHBOARD_SECRET_KEY`
微信接入项:
- `WECHAT_SERVER_URL`
- `WECHAT_SERVER_IP`
- `WECHAT_SERVER_PORT`
- `WECHAT_SERVER_TYPE`
- `DASHBOARD_PORT`
当你接的是 `864` 风格 server 时,额外必须配置:
- `WECHAT_SERVER_KEY`
若你需要启用 TrendRadar webhook再额外配置
- `ABOT_TRENDRADAR_WEBHOOK_TOKEN`
## 3. 启动命令
@@ -46,36 +60,13 @@ Copy-Item .env.docker.example .env
docker compose up -d --build
```
启动后:
启动完成后:
- Dashboard 默认访问:`http://127.0.0.1:8888`
- Dashboard 默认访问:`http://127.0.0.1:${DASHBOARD_PORT}`
- 日志目录映射到宿主机:`./logs`
- MariaDB / Redis 数据保存在 Docker volume 中
## 4. wechat_ipad 配置说明
现在 `wechat_ipad` 的静态连接参数统一走 `.env`
- `WECHAT_SERVER_URL`
- `WECHAT_SERVER_IP`
- `WECHAT_SERVER_PORT`
- `WECHAT_SERVER_TYPE`
登录后的 `wxid / device_id / device_name` 会自动写入本地状态缓存:
- 默认路径:`wechat_ipad/providers/<server_type>/runtime_state.toml`
- Compose 已将宿主机的 `./wechat_ipad/providers` 目录映射进容器
- 因此容器重建后,已有登录态仍会保留
兼容说明:
- 启动时仍会尝试兼容历史 `wechat_ipad/config.toml`
- 但新的人工维护入口已经变成 `.env`
- 后续不再建议继续手工编辑旧 TOML 文件
## 5. 常用命令
查看服务状态:
查看状态:
```bash
docker compose ps
@@ -87,6 +78,80 @@ docker compose ps
docker compose logs -f abot
```
## 4. 容器内配置生成逻辑
容器启动时会自动处理两类配置:
### 4.1 `config.yaml`
若容器内不存在 `config.yaml`,入口脚本会自动生成最小可运行模板,并注入:
- 数据库连接
- Redis 连接
- `wechat_ipad` 静态连接参数
- `WECHAT_SERVER_KEY`
### 4.2 `admin/dashboard/config.toml`
若容器内不存在该文件,入口脚本也会自动生成一份基础模板。
即使该文件存在,运行时仍支持通过环境变量覆盖以下敏感项:
- `ABOT_DASHBOARD_USERNAME`
- `ABOT_DASHBOARD_PASSWORD`
- `ABOT_DASHBOARD_SECRET_KEY`
- `ABOT_TRENDRADAR_WEBHOOK_TOKEN`
这样做的目标是:
- 公开仓库不再依赖固定弱口令
- Docker 环境只维护 `.env` 一处
- 非容器部署仍可继续使用本地 TOML 配置
## 5. wechat_ipad 配置说明
### 5.1 静态连接配置
统一通过 `.env` 注入:
- `WECHAT_SERVER_URL`
- `WECHAT_SERVER_IP`
- `WECHAT_SERVER_PORT`
- `WECHAT_SERVER_TYPE`
- `WECHAT_SERVER_KEY`
说明:
- `legacy_855 / 855 / 859` 可不填 `WECHAT_SERVER_KEY`
- `server_864 / 864` 必须提供 `WECHAT_SERVER_KEY`
### 5.2 运行时状态
登录后的 `wxid / device_id / device_name / login_time` 会自动写到 provider 自己的状态文件中:
- 默认路径:`wechat_ipad/providers/<server_type>/runtime_state.toml`
Compose 已将整个 `./wechat_ipad/providers` 目录映射到宿主机,因此:
- 容器重建后状态仍会保留
- `855``864` 的状态天然分离
- 不需要再人工维护历史 `wechat_ipad/config.toml`
## 6. Dashboard 安全建议
建议至少设置以下变量后再对外暴露:
- `ABOT_DASHBOARD_PASSWORD`
- `ABOT_DASHBOARD_SECRET_KEY`
- `ABOT_TRENDRADAR_WEBHOOK_TOKEN`
补充说明:
- 仓库默认密码已不再使用 `admin123`
- 若数据库里已存在管理员账号,登录以数据库中的真实密码为准
- 如果你把 Dashboard 暴露到公网建议再增加反向代理、HTTPS 和 IP / VPN 访问控制
## 7. 常用运维命令
停止服务:
```bash
@@ -99,7 +164,20 @@ docker compose down
docker compose down -v
```
## 6. 升级建议
进入应用容器:
```bash
docker compose exec abot bash
```
重建应用镜像:
```bash
docker compose build --no-cache abot
docker compose up -d
```
## 8. 升级建议
拉取新代码后建议执行:
@@ -108,13 +186,21 @@ docker compose down
docker compose up -d --build
```
若数据库结构发生变更,请先备份升级。
若数据库结构发生变更,请先备份数据库与关键挂载目录,再执行升级。
## 7. 公开仓库注意事项
建议重点备份:
在公开仓库或分享部署示例前,请再次确认:
- MariaDB 数据卷
- `./logs`
- `./wechat_ipad/providers`
- 你自己的 `.env`
## 9. 开源仓库注意事项
在公开仓库、打包镜像或分享部署模板前,请再次确认:
1. `.env` 未提交
2. `config.yaml` 未提交真实密钥
3. `wechat_ipad/providers/*/runtime_state.toml` 未被误公开
4. Dashboard 账号密码与 webhook token 已替换为你自己的值
4. Dashboard 密码、Session Secret、Webhook Token 已替换为你自己的值
5. 未确认授权来源的字体、二进制与业务素材没有被一起公开