SHKeeper v2.5.32 配置参数详解

SHKeeper v2.5.32 全配置面实测详解:核心与适配器环境变量、币种开关、汇率与费率模型、钱包加密三态、回调开关与 Metrics 认证,Compose 与 Helm 载体对照及八则配置排障速查。

SHKeeper加密货币支付系统自托管2026/10/24

SHKeeper v2.5.32 配置参数详解

目标:把 SHKeeper v2.5.32 的全部配置面讲清并给出实测依据——核心环境变量、各币种适配器环境变量、汇率与费率模型、钱包加密与回调开关、Metrics 认证、Compose/Helm 两种载体下的配置写法。全部参数语义以 v2.5.32 源码为准,关键项在本地 BTC regtest 栈(部署过程见《SHKeeper v2.5.32 Docker Compose 部署指南》,https://www.quzuo.net/document/tZXXROlLn3ej)逐一实测验证。产品背景见[《SHKeeper v2.5.32 介绍与选型指南》](https://www.quzuo.net/document/XwLIhTLm3c60)。

一、环境信息与配置来源

  • 取证与实测日期:2026-10-24
  • 核心版本:vsyshost/shkeeper:2.5.32(Python 3.13 / Flask / Gunicorn)
  • 适配器版本:vsyshost/bitcoin-shkeeper:2.0.14(Python 3.11 / Flask / Celery / Redis)
  • 配置载体:v2.5.32 的配置几乎全部通过环境变量注入(源码 shkeeper/__init__.py 的 app.config.from_mapping、各币种模块的 os.environ.get),另有少量持久化设置存于核心 SQLite 的 setting 表(通过管理台或 /api/v1/settings/<key> 读写)
  • 配置分层:核心(shkeeper 容器)与适配器(bitcoin-shkeeper 容器等)各有一套独立环境变量,同名变量的两侧语义不同,这是配置排障的高发点

💡 SHKeeper 无 config.ini/config.yaml 这类静态配置文件;/shkeeper.io/instance/config.py(实例目录内 Python 文件)如果存在会被 app.config.from_pyfile 加载(silent=True),可用于覆盖少量 Flask 层配置,但官方未文档化该用法,常规运维请以环境变量为准。

二、核心环境变量(shkeeper 容器)

2.1 币种启用开关:<币种>_WALLET

命名规则:<币种代码大写>_WALLET,值取 enabled / disabled。核心启动时按开关决定为哪些币种初始化钱包配置并暴露业务接口。v2.5.32 支持的全部开关(与官方 Helm Chart templates/shkeeper/deploy.yaml 渲染清单逐一核对):

环境变量对应币种
BTC_WALLETBitcoin(链上)
LTC_WALLETLitecoin
DOGE_WALLETDogecoin
FIRO_WALLET / FIRO_SPARK_WALLETFiro / Firo-Spark
TRX_WALLET / USDT_WALLET / USDC_WALLETTron 主链与 TRC20 代币
ETH_WALLET / ETH_USDT_WALLET / ETH_USDC_WALLET / ETH_PYUSD_WALLET / ETH_DAI_WALLETEthereum 主链与 ERC20 代币
BNB_WALLET / BNB_USDT_WALLET / BNB_USDC_WALLETBNB Chain 与 BEP20 代币
MONERO_WALLETMonero
XRP_WALLETXRP
MATIC_WALLET / POLYGON_USDT_WALLET / POLYGON_USDC_WALLETPolygon 主链与代币
AVAX_WALLET / AVALANCHE_USDT_WALLET / AVALANCHE_USDC_WALLETAvalanche C 链与代币
SOL_WALLET / SOLANA_USDT_WALLET / SOLANA_USDC_WALLETSolana 与 SPL 代币
ARBETH_WALLETArbitrum
OPETH_WALLETOptimism
TON_WALLETTON
BITCOINLIGHTNING_WALLETBTC 闪电网络

实测验证:本文实测栈只设 BTC_WALLET: enabled,其余全部 disabled,启动后业务侧币种列表即只有 BTC:

curl -s http://127.0.0.1:8128/api/v1/crypto

实测回显:

{"crypto":["BTC"],"crypto_list":[{"display_name":"Bitcoin","name":"BTC"}],"status":"success"}

被 disabled 的币种即使强行调用其接口,也返回网关不可用({"status":"error","message":"<币种> payment gateway is unavailable"},见《SHKeeper v2.5.32 API 使用详解》)。

2.2 核心与适配器的连接参数

只启用 BTC 时核心侧连接参数为:

环境变量默认值说明
BTC_USERNAME / BTC_PASSWORD无核心访问 BTC 适配器 HTTP 接口的 Basic 认证凭据(不是 bitcoind 的 RPC 凭据)
BTC_API_SERVER_HOSTbitcoin-shkeeperBTC 适配器主机名(容器网络内可解析)
BTC_SERVER_PORT6000BTC 适配器监听端口
SHKEEPER_BTC_BACKEND_KEYshkeeper核心侧的 Backend Key。bitcoind 的 walletnotify 脚本经适配器/核心间回调时以此鉴权

命名模式:这一组变量对所有币种同构,把 BTC_ 换成币种代码即可,如 Tron 是 TRON_API_SERVER_HOST / TRON_API_SERVER_PORT(官方 Chart 中明确出现);代币类(如 ETH_USDT)与其主链共用同一适配器连接。

实测验证:本栈核心侧设 BTC_API_SERVER_HOST=bitcoin-shkeeper、BTC_SERVER_PORT=6000、SHKEEPER_BTC_BACKEND_KEY=q1w2e3r4,核心与适配器连通(/api/v1/BTC/status 返回 server: Synced)。Backend Key 不匹配的直接后果见 2.6 节回调开关。

2.3 指标认证:METRICS_USERNAME / METRICS_PASSWORD

Prometheus 指标端点 /metrics 的 HTTP Basic 认证凭据,默认值均为 shkeeper(源码 shkeeper/auth.py:os.environ.get("METRICS_USERNAME", "shkeeper"))。

实测(本栈设为 admin / q1w2e3r4):

curl -s -u admin:q1w2e3r4 http://127.0.0.1:8128/metrics | grep -E '^bitcoin' | head -6

实测回显:

bitcoin_fullnode_status 1.0
bitcoin_fullnode_last_block 109.0
bitcoin_wallet_last_block 108.0
bitcoin_fullnode_last_block_timestamp 1.792831002e+09
bitcoin_wallet_last_block_timestamp 0.0
bitcoin_shkeeper_status 1.0

凭据错误或缺失均拒绝:

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8128/metrics            # 401
curl -s -u admin:wrongpass -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8128/metrics  # 401

实测回显:

401
401

2.4 法币扩展:EXTRA_CURRENCIES

内置法币只有 USD 与 EUR(源码 Fiat.BASE),EXTRA_CURRENCIES 以逗号分隔追加其他法币。源码语义(models.py::Fiat.list):大小写不敏感(自动转大写)、自动去空格与重复。

实测验证:本栈设 EXTRA_CURRENCIES: "CNY",登录管理台访问人民币汇率页:

curl -s -b cookies.txt -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8128/rates/CNY

实测回显:

200

页面正常渲染出 BTC/CNY 汇率设置表单,证明扩展法币已注册。每个新法币自动获得与 USD 相同结构的汇率记录(ExchangeRate.register_currency 为每个法币 × 币种建一行)。

⚠️ 注意:新法币注册后 source 默认为 dynamic(自动汇率源)。离线环境必须在对应 /rates/<法币> 页把每个币种的汇率源切到 manual 并填值,否则首次开票仍会请求外部汇率源而失败。

2.5 行为开关类变量

以下布尔开关均以 bool(os.environ.get(...)) 方式解析——设为任意非空字符串即视为开启(包括 "false"、"0"!源码如此,务必只留空或不设来表示关闭):

环境变量默认说明
FORCE_WALLET_ENCRYPTION关强制启用钱包加密(禁止在解锁页选择「不加密」)。生产启用 BTC/LTC/DOGE 等链上币种时强烈建议开启
UNCONFIRMED_TX_NOTIFICATION关开启后买家交易进入内存池(0 确认)时即向 callback_url 推送未确认交易通知,便于商户提前发货决策;关闭则只推送确认后回调
ENABLE_PAYOUT_CALLBACK关开启后打款(Payout/Multipayout)完成时适配器会回调核心 /api/v1/payoutnotify/<币种> 并向商户 callback_url 推送打款结果通知;官方 Chart 中该值固定渲染为 enabled
DISABLE_CRYPTO_WHEN_LAGS关开启后节点同步滞后(status 非 Synced)的币种自动暂停收款,payment_request 会返回 "...because of lagging" 错误;关闭则滞后时仍可开票
TRON_MULTISERVER_GUI关管理台显示 Tron 多服务器配置界面
TRON_STAKING_GUI关管理台显示 Tron 质押管理界面
DEV_MODE关开发模式:固定 SECRET_KEY=dev 并放宽部分校验,生产严禁开启

2.6 数值/超时类变量

环境变量默认值说明
SECRET_KEY每次启动随机生成Flask 会话签名密钥。不固定则每次重启全站会话失效(源码注释明确「all sessions are invalidated at app restart by design, unless key is overriden from env」);多副本部署必须固定且一致
REQUESTS_TIMEOUT10核心对外(适配器、汇率源)HTTP 请求超时(秒)
MAX_RETRIES(映射为 REQUESTS_NOTIFICATION_RETRIES)7回调通知失败后的最大重试次数
REQUESTS_NOTIFICATION_TIMEOUT30单次回调通知的 HTTP 超时(秒)
NOTIFICATION_TASK_DELAY60回调重发间隔(秒)。实测:回调接收方不返回 202 时,核心每 60 秒重发一次
MIN_CONFIRMATION_BLOCK_FOR_PAYOUT1打款相关交易所需的最小确认块数
DEV_MODE_ENC_PW无配合 DEV_MODE 的加密密码占位

2.7 数据存储路径(Flask 层)

以下由源码内部固定,列出供备份与排障参考:

配置项值说明
SQLALCHEMY_DATABASE_URIsqlite:///<实例目录>/shkeeper.sqlite核心数据库(发票、钱包 API Key、汇率设置、打款记录)
SESSION_TYPE / SESSION_FILE_DIRfilesystem / <实例目录>/flask_session管理台会话文件
SESSION_COOKIE_HTTPONLY / SESSION_COOKIE_SAMESITETrue / Strictv2.5.x 安全加固项;SESSION_COOKIE_SECURE 默认 False,套 HTTPS 后建议在实例配置中改 True

容器内实例目录为 /shkeeper.io/instance,官方镜像 WORKDIR /shkeeper.io。Compose 部署时把它挂出到宿主机(本文 ./data/shkeeper:/shkeeper.io/instance),核心全部状态都在这个目录。

三、适配器环境变量(bitcoin-shkeeper 等容器)

BTC 族(BTC/LTC/DOGE 共用 vsyshost/bitcoin-shkeeper 镜像,靠 WALLET 变量区分币种):

环境变量实测取值说明
WALLETBTC适配器身份:本容器服务哪个币种
BTC_NETWORKregtest网络选择:mainnet / testnet / regtest(LTC/DOGE 同构为 LTC_NETWORK 等)
BTC_USERNAME / BTC_PASSWORDshkeeper / shkeeper适配器连 bitcoind RPC 的凭据(注意与核心侧同名变量语义不同:核心侧是「连适配器」的凭据)
FULLNODE_URLhttp://shkeeper:shkeeper@bitcoind:18443bitcoind RPC 地址(含凭据)。官方 Chart 中等价物是 btc_fullnode.url,指向外部全节点时无需本地部署节点
SHKEEPER_HOSTshkeeper:5000核心地址,适配器回调核心时使用
SHKEEPER_BACKEND_KEYq1w2e3r4适配器侧 Backend Key,必须与核心侧 SHKEEPER_BTC_BACKEND_KEY 一致
REDIS_HOSTredisCelery broker 地址
C_FORCE_ROOT1允许 Celery 以 root 运行(容器内默认用户即 root,官方镜像用法)

一致性核对清单(两侧不一致是「节点状态/回调」类故障的第一嫌疑):

  1. 核心侧 BTC_USERNAME/BTC_PASSWORD = 适配器 HTTP Basic 凭据(适配器侧由其自身配置约定,官方镜像默认即 shkeeper/shkeeper);
  2. 适配器侧 BTC_USERNAME/BTC_PASSWORD = bitcoind -rpcuser/-rpcpassword;
  3. 核心侧 SHKEEPER_BTC_BACKEND_KEY = 适配器与 walletnotify.sh 的 SHKEEPER_BACKEND_KEY。

实测佐证:bitcoind 镜像自带的 /shkeeper/walletnotify.sh 内容为:

#!/bin/bash
TXID="$1"
CRYPTO="BTC"
curl -X POST -H "X-Shkeeper-Backend-Key: ${SHKEEPER_BACKEND_KEY}" \
  "http://shkeeper:5000/api/v1/walletnotify/${CRYPTO}/${TXID}"
exit 0

若凭据缺失,手工执行该脚本会收到 {"message":"No backend key provided","status":"error"}(实测回显);Key 传对后同一请求返回 {"status":"success"}。

3.1 其他币种适配器的差异项

  • Monero(vsyshost/monero 镜像内同时跑 monerod 与 monero-wallet-rpc):MONERO_WALLET_NAME、MONERO_WALLET_PASS(钱包文件名与密码,默认均 shkeeper)、MONERO_DAEMON_HOST/PORT/USER/PASS(monerod RPC,默认 monerod:1111)、MONERO_WALLET_RPC_HOST/USER/PASS(源码 modules/cryptos/monero.py);
  • Tron 族:tron_fullnode.url(HTTP API,默认 8090)与 solidity_url(Solidity 节点,8091);Tron 适配器镜像 vsyshost/tron-shkeeper:2.0.0;
  • EVM 族(ETH/BNB/Polygon/AVAX/ARB/OP 及其代币,统一镜像 vsyshost/evm-shkeeper:1.1.3):连接参数即各 <链>_fullnode.url(JSON-RPC 地址),如 http://ethereum:8545;
  • XRP(vsyshost/xrp-shkeeper:1.0.16):xrp_fullnode.url(JSON-RPC,默认 51234);
  • BTC Lightning:由 LND(lndinit 镜像,BITCOIND_RPCHOST、BITCOIND_ZMQPUBRAWBLOCK/ZMQPUBRAWTX、BITCOIND_RPCUSER/PASS)+ LNBits 组成,通过 btc_lightning.network 选主网/测试网。

四、汇率与费率模型(管理台配置,非环境变量)

汇率不是环境变量,而是核心库 exchange_rate 表中的持久化配置,管理台 /rates/<法币> 页(或等效表单 POST)维护。每条记录五个字段:

字段取值说明
sourcedynamic / 具体源名(binance、coinbase、kraken、kucoin) / manual汇率来源;manual 时使用 rate 字段静态值
rate十进制数手动汇率(法币/币种),仅 source=manual 时生效;源码逻辑明确「do not save rate from dynamic rate providers」——表单里 source 不是 manual 时 rate 字段被忽略
fee百分数(默认 2)商户加价率(%)
fixed_fee法币绝对值固定手续费金额
fee_policyNO_FEE / PERCENT_FEE / FIXED_FEE / PERCENT_OR_MINIMAL_FIXED_FEE计费策略

开票金额计算公式(源码 ExchangeRate.convert,实测验证):加密币数量 = (fiat金额 + 手续费) ÷ 汇率,按币种精度取整。

实测数据闭环:本栈 BTC 手动汇率 100000、PERCENT_FEE 2%,开票 18.25 USD:

18.25 × 1.02 = 18.615 USD → ÷ 100000 = 0.00018615 BTC

发票与回调中的金额字段完全吻合(实测回显):amount: "0.00018615"、回调 balance_fiat: "18.615"、amount_fiat_without_fee: "18.25"、fee_fiat: "0.365"。

4.1 管理台表单的 API 等价写法(实测可用)

curl -s -b cookies.txt -o /dev/null -w 'POST /rates/USD -> %{http_code}\n' \
  --data-urlencode 'rates__BTC__source=manual' \
  --data-urlencode 'rates__BTC__rate=100000' \
  --data-urlencode 'rates__BTC__fee_policy=PERCENT_FEE' \
  --data-urlencode 'rates__BTC__fee=2' \
  --data-urlencode 'rates__BTC__fixed_fee=0' \
  http://127.0.0.1:8128/rates/USD

实测回显:

POST /rates/USD -> 302

字段命名规则:rates__<币种>__<字段>,POST 到 /rates/<法币>。另有按币种设定「汇率重算周期」的 recalc(发票锁价时长,单位小时),在钱包管理页 /wallet/BTC 设置,开票响应中的 recalculate_after 即来源于此(本文实测栈为默认值 0,即不锁价重算)。

五、钱包加密机制(部署后必配项)

v2.5.x 的钱包加密不是环境变量,而是三态持久化设置 + 两段式运行时解锁:

  1. 持久化状态(存 setting 表 WalletEncryptionPersistentStatus):pending(初始,未选择)→ enabled(加密,存密码哈希 WalletEncryptionPasswordHash)/ disabled(不加密,使用内置默认密钥 shkeeper);
  2. 运行时状态:pending → success / fail,由管理台 /unlock 页输入正确密码后置位;
  3. 解锁动作:核心用密码派生 Fernet 密钥(PBKDF2-HMAC-SHA256,盐 Shkeeper4TheWin!,50 万次迭代),适配器经核心 /api/v1/<币种>/decrypt 接口取得密码以加载加密的 HD 私钥字段。

实测排障:适配器在未解锁时循环告警(逐行实测日志):

WARNING: Get password from shkeeper
WARNING: Encryption enabled, but password is not entered yet
WARNING: Encryption password not available yet, waiting 20 seconds...

此时任何生成地址类操作都失败(适配器报 Encryption password not loaded — cannot save encrypted field)。解锁成功后适配器立即恢复正常(日志出现 Retrieved blockchain info: {'chain': 'regtest', ...} 并开始扫块)。完整两段式操作步骤见部署篇第六节;FORCE_WALLET_ENCRYPTION=1 可禁止部署者选择「不加密」。

六、回调相关配置汇总

项配置位置实测结论
收款回调地址开票请求体 callback_url(每张发票可不同)见部署篇第八节完整回调体
回调重试间隔与次数环境 NOTIFICATION_TASK_DELAY=60、MAX_RETRIES=7接收方必须返回 202,否则按 60 秒间隔重试
未确认交易通知环境 UNCONFIRMED_TX_NOTIFICATION(默认关)开启后 0 确认即推送
打款结果回调环境 ENABLE_PAYOUT_CALLBACK(默认关,Chart 默认开)打款完成推 payoutnotify
回调签名验证无需配置,新版自带 X-Shkeeper-Signature(HMAC-SHA256,密钥=钱包 API Key)与 X-Shkeeper-Timestamp 头商户侧验签实现即可,旧 X-Shkeeper-Api-Key 头仅兼容保留
交易入块通知(节点→核心)bitcoind -walletnotify 脚本 + 两侧 *BACKEND_KEY凭据不一致时核心日志报 Wrong backend key 或 No backend key provided(均实测复现)

七、/api/v1/settings/<key> 运行时设置接口

核心提供一个白名单制的运行时设置读写接口(登录态):

  • GET /api/v1/settings/<key>:key 在白名单内返回 {"key":...,"status":"success","value":...},否则 {"message":"forbidden","status":"error"};
  • POST /api/v1/settings/<key>:同白名单限制。

v2.5.32 源码中白名单 PUBLIC_SETTINGS 只含 start_banner_shown(管理台首页横幅已读标记)一个键。

实测(白名单内/外各一次):

curl -s -b cookies.txt http://127.0.0.1:8128/api/v1/settings/start_banner_shown
curl -s -b cookies.txt http://127.0.0.1:8128/api/v1/settings/rate_update_period

实测回显:

{"key":"start_banner_shown","status":"success","value":null}
{"message":"forbidden","status":"error"}

💡 该接口是给前端与插件用的「少量运行时标记」通道,不是通用配置中心;改变行为类配置仍以环境变量 + 管理台(汇率、钱包参数、打款策略)为准。

八、Compose 与 Helm 载体对照

同一套配置在两种官方载体下的写法对照(节选):

配置项Docker Compose(环境变量)Helm Chart(values.yaml)
启用 BTCBTC_WALLET: enabledbtc.enabled: true
regtest 模式bitcoind 容器 command 追加 -regtest + 适配器 BTC_NETWORK: regtestbtc.regtest: true(btc.mainnet: false)
外接全节点(不部署本地节点)适配器 FULLNODE_URL: http://user:pass@host:8332btc_fullnode.enabled: false + btc_fullnode.url: http://...
打款回调ENABLE_PAYOUT_CALLBACK: "1"shkeeper.enable_payout_callback: true(渲染为 env enabled)
追加法币EXTRA_CURRENCIES: "TRY,CAD"通过 shkeeper.extraEnv 任意 env 注入
指标凭据METRICS_USERNAME / METRICS_PASSWORD同名 env 注入
MariaDB root 密码MARIADB_ROOT_PASSWORD: shkeepermariadb.rootPassword: shkeeper

Chart 的 shkeeper.extraEnv 支持任意键值注入核心容器,是 Chart 模式下透传本文全部环境变量的通用出口。

九、配置排障速查(实测沉淀)

症状根因处置
开票报 api.binance.com ... Network is unreachable汇率源 dynamic 且外网不可达/rates/<法币> 把币种 source 切 manual 并填 rate(见第四节)
适配器循环 Encryption password not available yet核心未完成两段式解锁按 /unlock 两段操作(见第五节)
核心日志 Wrong backend key / No backend key providedSHKEEPER_BTC_BACKEND_KEY 与适配器侧 SHKEEPER_BACKEND_KEY(及 walletnotify.sh 的 env)不一致两侧统一取值并重启相关容器
重启后管理台全部要求重新登录SECRET_KEY 未固定(随机生成)设固定 SECRET_KEY 环境变量
EXTRA_CURRENCIES 设了新法币但开票仍报错新法币的汇率记录 source 仍是 dynamic到 /rates/<新法币> 逐币种设 manual 或配通外网汇率源
布尔开关设 "false" 却被开启源码按 bool(非空字符串) 解析关闭 = 不设或留空,绝不能设 "false"
/metrics 一直 401Basic 凭据不是 METRICS_USERNAME/METRICS_PASSWORD 所设值核对凭据(默认 shkeeper/shkeeper)
适配器起不来、报 MariaDB 错误库名连字符未转义(自编排时高发)建库语句用反引号包裹 bitcoin-shkeeper

十、参考与关联