PyCryptoBot / 运维安全
PyCryptoBot 上线后怎么安全运行:权限、隔离与应急停止
绝大多数教程讲到「启动成功」就结束了。但真正决定你会不会出事的是启动之后的那几件事:进程会不会自己起来、密钥权限给得是不是太宽、同一市场会不会被两个实例同时交易、以及最关键的——你以为停掉了,它到底还会不会下单。
这一页不重复安装步骤,只做两件事:把项目里已经写好的安全设计(容器非 root 运行、密钥走 secret、官方在 README 里针对冒充管理员的骗子写的 5 条提醒)挑出来讲清楚;再把项目不会帮你想的部分(IP 白名单、多实例隔离、停止后的下单核对)整理成可以直接照着核对的清单。
需要先说明边界:本站没有连接任何真实交易所账户,也没有下过任何委托。以下内容都来自仓库源码、配置样本与官方文档,不是实盘经验分享;真实交易的风险请自行评估。
- PyCryptoBot v8.2.4(main=1fa9aaef,2024-03-04)
- Python 3.11(官方 Dockerfile 基线)
- 交易所范围:Binance / Coinbase / KuCoin
- 验证日期 2026-09-21
- 本站未实机运行机器人
Dockerfile 的 USER pycryptobot、chart/templates/secret.yaml 与 docs/UbuntuSystemdService.md 整理,非官方运维手册)。四格分别对应当页的四张表。怎么让机器人自己起来,并且挂了能起回来
「前台跑一个 python3 pycryptobot.py」适合试跑,不适合长期运行——关掉终端、SSH 断线、服务器重启,它都会停。下面四条是仓库里已经给出的路径。
| 方式 | 依据文件 | 怎么做 | 适用场景与注意点 |
|---|---|---|---|
| docker-compose | docker-compose.yaml | 仓库自带编排文件,已声明 deploy.restart_policy.condition: on-failure,并把 config.json、pycryptobot.log、graphs 与宿主机目录挂载绑定,另把 /etc/localtime 只读挂入 | 单机长期运行最省事;注意 on-failure 只在进程以非零退出时重启,「正常退出」不会拉起 |
| docker run | docker-compose.yaml 注释块 / 官方镜像 | 用镜像 ghcr.io/whittlem/pycryptobot/pycryptobot:latest 直接运行,需要自己把配置、日志、密钥目录挂进去,并显式加 --restart 策略 | 没有 compose 的环境;别漏挂密钥文件,否则容器里读不到交易所凭证 |
| systemd | docs/UbuntuSystemdService.md | 仓库提供了对应的服务化说明文档,按它把脚本注册成系统服务,实现开机自启与崩溃重启 | 裸机(不用容器)场景;要确认服务工作目录与该机器人的配置目录一致 |
| Helm / Kubernetes | chart/ 目录(Chart.yaml、values.yaml、templates/ 下含 deployment.yaml、secret.yaml、configmap.yaml、serviceaccount.yaml、NOTES.txt、_helpers.tpl) | 用官方 chart 部署,配置走 ConfigMap、密钥走 Secret | 已经有 K8s 的场景;多副本要特别小心「同一市场被多个 Pod 同时交易」 |
| 前台直接运行 | 无 | python3 pycryptobot.py 跑在终端里 | 仅用于试跑。终端关闭、SSH 断开、机器重启都会停;停在你不知道的时候,比不停更危险 |
| 多机器人编排 | docker-compose.yaml 注释块 | 文件里给出了按市场复制服务块(如 BTCEUR / ETHEUR)的写法,每个服务挂载各自目录 | 多市场并行时用它,比在一个容器里跑多个进程更好排查 |
telegram_bot.py 与 websvc.py 两块是注释状态,默认不会被拉起。也就是说「我配了 compose」不等于「通知和控制界面已经跑起来了」——需要手动取消注释或另外启动。具体分工见通知与控制面。密钥该给多大权限?
这一节是本页最重要的部分。机器人持有的是能在交易所真实下单的凭证,所以「给多少权限」本质上是在设定你的风险上限。
| 项 | 项目里的现状或依据 | 你应该做什么 | 不做会怎样 |
|---|---|---|---|
| 容器运行身份 | Dockerfile 里 groupadd -g 1000 pycryptobot、useradd -r -u 1000 -g pycryptobot,并显式 USER pycryptobot | 沿用官方镜像的这一设计;如果用 compose 覆盖用户,不要改回 root | 容器内进程被攻破时直接拿到容器 root,挂载目录的写权限一起丢 |
| 密钥文件权限 | 各交易所密钥通过 api_key_file 指向独立文件(样本里是 binance.key、coinbase.key、coinbasepro.key、kucoin.key) | 文件权限收到仅属主可读;不要放在 Web 根目录下 | 同机其它账户或误配的静态服务可以直接读走密钥 |
| 提现权限 | 项目只需要下单与查询账户能力;仓库未见任何提现相关调用 | 明确关闭提现权限,只保留交易与读取 | 密钥一旦泄露,损失不限于仓位 |
| 权限范围 | 各交易所 api.py 用到的能力集中在行情、账户、下单、费率查询(如 get_account、get_orders、market_buy、market_sell、get_fees) | 按「现货交易 + 读取」的最小集合勾选,多余的(提现、划转、杠杆/合约)一律不勾 | 密钥泄露时的可操作面被放大,且难以复盘 |
| IP 白名单 | 仓库未强制;属于交易所侧的额外保护 | 强烈建议开启,只放行运行机器人的那台机器/VPS 的出网 IP | 密钥泄露后可以在任意地点被使用,你的日志里看不出异常来源 |
| 密钥入版本库 | CHANGELOG 记载过把自定义策略文件加入 .gitignore 以防覆盖,说明官方在意「本地文件别被提交」这件事 | 把 *.key、keys.json、config.json 等含凭证文件写进 .gitignore;提交前再 grep 一次 | 密钥进入 Git 历史后极难彻底清除,等于长期暴露 |
| 把密钥发给别人或 AI | README 顶部专门写了一组防骗提醒,第 1 条就是「永远不要把 API Key 分享给任何人」 | 无论是调试、求助还是截图,都不要粘贴真实密钥;需要时可临时新建一把只读密钥 | 官方明确提醒有人在冒充管理员行骗,密钥一旦外流不归你控制 |
| 控制权限归属 | telegram 配置段有 user_id 字段,官方文档说明它的作用就是限定只有你能控制机器人 | 务必填自己的 user_id,不要留默认值 | 任何知道机器人的人都可能通过 Telegram 下指令 |
| K8s 场景密钥管理 | chart/templates/secret.yaml 存在,说明官方把密钥按 Secret 资源处理 | 不要把密钥明文写进 values.yaml 提交进仓库;用 Secret 或外部密钥管理 | 集群配置仓库泄露等于密钥泄露 |
DISCLAIMER.md,明确「as-is、不提供任何担保」,并且不对使用该软件产生的任何直接或间接损失负责。换句话说,跑在哪个账户、给多大权限、亏多少钱,都由你自己承担。重复下单:这个项目历史上真的处理过这类问题
「机器人重复下单」不是假想风险。项目的更新日志里有多条针对它的修复记录,可以直接用来判断自己该防什么。
| 风险 | 表现 | 自查方法 | 处置 |
|---|---|---|---|
| 同一市场被多个实例交易 | 同一时间出现方向相近的多笔委托,仓位翻倍 | 列出所有正在运行的进程与容器,确认每个市场只有一个实例 | 用不同配置目录/服务块隔离,一个市场只留一个实例 |
| API 异常后重复买入 | 更新日志记载过某交易所「API 出错时对同一交易对重复买入」并已修复 | 检查日志里是否有连续的同向买入记录;核对交易所侧的委托列表 | 升级到含该修复的版本;异常后先人工核对持仓再让它继续 |
| 同一轮内重复处理同一笔交易 | 更新日志记载过「同一轮买卖流程中交易可能被处理多次」的修复 | 看成交记录里是否存在时间戳几乎相同的重复条目 | 确认当前版本晚于该修复;必要时降低轮询频率 |
| 启用 WebSocket 时的重复买入 | 更新日志记载过「使用 WebSocket 时出现双重买入」的修复 | 对比开启/关闭 WebSocket 时的成交条数 | 先以非 WebSocket 模式稳定运行,再评估是否开启 |
| Web 界面/机器人重复启动 | 更新日志记载过「启动脚本只启动尚未运行的机器人」与「界面与 Telegram 各自的扫描计划是两个进程」 | 分别确认机器人进程数量与界面进程数量 | 多实例场景用不同的 datafolder 分开存放状态 |
| 重启后本地状态与交易所不一致 | 进程停了但交易所仍有挂单;或本地记录了持仓而交易所已成交 | 重启前后各查一次交易所侧持仓与挂单 | 以交易所为准:先核对再让机器人继续;不要假设本地文件是对的 |
| 余额校验缺失导致「以为成交了」 | 更新日志记载过「增加余额检查以验证买卖是否真的发生」 | 成交后比对账户余额变化,而不是只看日志打印 | 以交易所回执为准;日志只作参考 |
怎么确认它真的停了:停止进程 ≠ 已经撤单
这是本节最需要记住的一句话。杀掉进程只让「程序不再决策」,并不会自动撤销已经挂在交易所的委托,也不会改变你的持仓。
| 项 | 依据 | 怎么做 | 注意点 |
|---|---|---|---|
| 运行日志 | docker-compose.yaml 把 pycryptobot.log 挂载到宿主机 | 把日志落到容器外,避免容器重建时日志一起丢;定期归档 | 日志是排查的第一现场,--disablelog 关闭后就没得查了 |
| 日志服务入口 | logsvc.py(与 websvc.py 同为 57 行的小型服务入口) | 需要集中看日志时按官方说明启动它;不需要就不必开 | 它是独立进程,不会随机器人自动起来 |
| 日志级别 | telegram 配置段有 logger_level(样本默认 DEBUG) | 长期运行时按需下调输出级别,避免日志无限膨胀 | 级别调太粗会把关键告警也过滤掉 |
| 交易通知 | telegramtradesonly 配置项:只推送交易、不推中间状态变化 | 至少让「成交/失败」这两类消息可达;把它当作你的外部告警通道 | 通知依赖 Telegram 可达性,不能作为唯一告警手段 |
| 时间基准 | 各交易所 api.py 有 get_time/get_timestamp 类方法,binance 侧还使用 recvWindow | 确认宿主机时间与 NTP 同步;容器已把 /etc/localtime 挂入,注意同时确认时区 | 系统时钟偏差会直接导致请求被拒,表现像「接口坏了」 |
| 应急停止(第一步) | 进程层面 | 停掉机器人进程/容器 | 只停止「继续决策」,不撤销已有挂单 |
| 应急停止(第二步) | 交易所侧 | 登录交易所核对挂单与持仓,必要时手动撤单 | 这一步不能省;只做第一步就以为安全,是危险误判 |
| 应急停止(第三步) | 凭证层面 | 怀疑密钥外流时,立即在交易所侧吊销并轮换 API Key | 轮换后记得同步更新密钥文件,并确认旧密钥已失效 |
上线前要检查哪十二项?
下面这份清单按「先保证不失控,再谈能不能赚钱」的顺序排列。每一条都写清了通过标准与依据来源,方便你逐项打勾。
| # | 检查项 | 通过标准 | 依据 |
|---|---|---|---|
| 1 | 先用非实盘模式跑通 | 配置里的 live 保持关闭,机器人能完整跑完一轮并输出日志 | 样本配置中 live 默认即为关闭状态 |
| 2 | 确认自己拿的是哪一版代码 | 知道自己的 main/beta 提交时间,并确认要用的修复是否已在其中 | 见版本与分支现状 |
| 3 | 密钥权限最小化 | 只开现货交易与读取;提现权限关闭 | 各交易所 api.py 的能力集合 |
| 4 | 独立密钥,不与其它工具共用 | 该机器人使用一把专用 API Key | 便于单独吊销与归因 |
| 5 | IP 白名单已开启 | 只有运行机器人的机器 IP 在白名单内 | 交易所侧安全设置(非项目功能) |
| 6 | 密钥未进入版本库 | git status 与历史中都不含 *.key/keys.json | CHANGELOG 对本地文件保护的记录 |
| 7 | 日志可读且可留存 | 日志落在持久化目录,能按时间检索 | docker-compose.yaml 的日志挂载 |
| 8 | 告警可达 | 能收到交易与异常通知,且通知里能看出是哪一笔 | telegram 配置段与 telegramtradesonly |
| 9 | 多实例已隔离 | 每个市场只有一个实例;多实例使用不同 datafolder | 状态目录与更新日志中的重复下单修复记录 |
| 10 | 应急流程演练过 | 「停进程 → 交易所侧核对/撤单 → 轮换密钥」三步都实际走过一遍 | 本页应急三步 |
| 11 | 账户与计价币种正确 | 配置的 base_currency/quote_currency 与实际资金账户一致 | 两份配置样本 |
| 12 | 最小下单量已知 | 已在交易所侧确认该交易对的最小下单量与精度要求 | 见交易所支持矩阵 |
关于长期运行与安全的高频问题
回答依据仓库源码、配置样本与官方文档;本站未连接真实账户、未下过任何委托,涉及实盘表现的判断请自行验证。
重启机器人会不会重复下单?
项目历史上确实出现过这类问题:更新日志里有多条修复记录,包括「API 出错时对同一交易对重复买入」「使用 WebSocket 时双重买入」「同一轮内交易被处理多次」等,也都对应了修复提交。但「已修复」不等于「任何场景都不会再发生」。真正稳妥的做法是:重启前后各查一次交易所侧的持仓与挂单,并确保同一市场只有一个实例在跑。如果你不确定自己的版本是否包含某个修复,可以先用版本与分支现状确认提交时间。
我把进程停掉了,是不是就安全了?
不是。停进程只意味着程序不再做新的决策,它不会自动撤销已经挂在交易所的委托,也不会改变你当前的持仓。正确的应急顺序是三步:① 停掉进程/容器;② 登录交易所核对挂单与持仓,必要时手动撤单;③ 如果怀疑密钥外流,立即在交易所吊销并轮换 API Key。这三步对应三种不同的失控,只做第一步只是切断了其中一种。
API Key 到底该给什么权限?
按源码用到的能力给最小集合:读取行情、读取账户与委托、下单与撤单、查询费率就足够了。对照各交易所 api.py 的方法清单可以看到,项目用到的能力集中在 get_account、get_orders、market_buy、market_sell、get_fees 这一组,没有任何提现相关调用。所以「提现权限必须关闭」不是可选项,是底线。另外强烈建议同时开启交易所侧的 IP 白名单——它不在项目里,但能显著缩小密钥泄露后的影响面。
能不能直接用我的主账户跑?
技术上可以,但风险集中:主账户通常同时持有长期仓位,一旦机器人出现重复下单或方向错误,影响的是你全部资产;而且密钥与主账户绑定后,权限收窄的余地更小。更稳妥的做法是给机器人单独准备一个子账户或独立账户,只放愿意交给策略运作的那部分资金。这不是技术限制,而是损失上限的控制问题。
同时跑多个币对要注意什么?
三件事:① 每个市场只保留一个实例,避免同一交易对被两处下单;② 多实例之间用不同的 datafolder 隔离状态目录,否则状态文件可能互相覆盖;③ 编排层面优先用 compose 的「一个市场一个服务块」写法或 K8s 里明确副本数为 1,而不是在一个容器里塞多个进程。另外别忘了 scanner 段里有数量上限(maxbotcount 与 exchange_bot_count),如果你手动起的实例和扫描器启动的实例同时存在,就会突破你预期的数量。
本站有实盘运行经验吗?
没有。本站做的是代码级与文档级核对:读源码确认安全相关设计(容器非 root 运行、密钥走 secret、配置字段语义)、读更新日志找出历史上出过的状态类问题、读官方文档整理部署路径。我们没有连接任何交易所账户、没有创建 API Key、没有下过任何委托。因此这一页是「操作顺序与核对清单」,不是实盘经验分享;真实资金的风险请自行评估。