BTCPay Server 2.4.5 Docker Compose 部署指南
在 Ubuntu 22.04 上使用官方 btcpayserver-docker 的 btcpay-setup.sh 一键脚本以 Docker Compose 部署 BTCPay Server 2.4.5 全栈(主程序、NBXplorer、Bitcoin Core、PostgreSQL),含环境变量规划、部署验证、13 个官方运维脚本实测与六类排障实录。
BTCPay Server 2.4.5 Docker Compose 部署指南
目标:使用官方部署仓库 btcpayserver-docker 的 btcpay-setup.sh 一键脚本,在 Ubuntu 22.04 服务器上以 Docker Compose 方式部署 BTCPay Server 2.4.5 全栈(主程序、NBXplorer、Bitcoin Core、PostgreSQL 四个容器服务),讲清部署前的环境变量规划、生成产物的结构、日常运维脚本与升级方法。全部命令与回显实测;链的验证环节采用 regtest 私有测试链,并给出主网(mainnet)的切换改法。
一、部署方案与环境信息
1.1 两种部署形态
BTCPay Server 官方支持两种部署形态:
| 形态 | 适用场景 | 说明 |
|---|---|---|
| Docker Compose 一键部署(本篇) | 绝大多数生产服务器 | 官方脚本自动生成编排、注册开机自启、内置证书签发与运维脚本 |
| 手动部署(源码构建 + systemd) | 需要完全掌控进程边界的运维 | 见《Ubuntu 22.04 安装 BTCPay Server 2.4.5 指南》 |
1.2 实测环境与组件版本
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS |
| Docker | 29.9.2(官方 apt 源 docker-ce) |
| Docker Compose | v5.6.1(docker-compose-plugin) |
| 验证链网络 | regtest(私有测试链) |
| 部署仓库 | btcpayserver-docker(2026-10-22 克隆) |
生成的栈内组件镜像(官方部署仓库片段锁定组合,与 v2.4.5 配套):
| 服务 | 镜像 | 说明 |
|---|---|---|
| btcpayserver | btcpayserver/btcpayserver:2.4.5 | 主程序(.NET 10) |
| nbxplorer | nicolasdorier/nbxplorer:2.6.19 | 链上索引器 |
| bitcoind | btcpayserver/bitcoin:31.1-1 | Bitcoin Core 31.1 全节点 |
| postgres | btcpayserver/postgres:18.6 | PostgreSQL 18.6 数据库 |
1.3 端口与数据卷布局(regtest 实测拓扑)
外部访问 Docker 网络(compose 项目 generated)
──────── ─────────────────────────────────────
:80 ──────────────────▶ generated_btcpayserver_1(容器内 49392)
│ │ │
▼ ▼ ▼
generated_postgres_1 generated_nbxplorer_1
(5432) (32838) │
▼
btcpayserver_bitcoind
(RPC 43782 / P2P 39388,容器网络内部)
数据卷(compose 项目前缀 generated_):
| 卷名 | 存放内容 |
|---|---|
| generated_btcpay_datadir | BTCPay Server 数据(含 settings.config) |
| generated_btcpay_pluginsdir | 插件目录 |
| generated_nbxplorer_datadir | NBXplorer 索引数据 |
| generated_bitcoin_datadir | Bitcoin Core 区块与链状态 |
| generated_bitcoin_wallet_datadir | Bitcoin Core 钱包 |
| generated_postgres_datadir | PostgreSQL 数据文件 |
二、前置条件:安装 Docker 与 Compose 插件
2.1 配置 Docker 官方 apt 源
Ubuntu 22.04 自带源里的 docker.io 版本较旧,推荐官方源。安装依赖并添加仓库签名:
apt-get install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" > /etc/apt/sources.list.d/docker.list
实测回显(追加写入的源行):
deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu jammy stable
apt-get update
实测回显(末尾节选):
Fetched 5047 kB in 5s (974 kB/s)
Reading package lists...
2.2 安装 Docker CE 与 compose 插件
DEBIAN_FRONTEND=noninteractive apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
实测回显(末尾节选):
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /lib/systemd/system/docker.service.
Created symlink /etc/systemd/system/multi-user.target.wants/docker.socket → /lib/systemd/system/docker.socket.
Processing triggers for libc-bin (2.35-0ubuntu3.15) ...
安装包已自动注册 docker.service 开机自启。启动并确认版本:
systemctl enable --now docker
systemctl is-active docker
docker --version
docker compose version
实测回显:
active
Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1
三、一键部署
3.1 规划环境变量
btcpay-setup.sh 通过环境变量决定生成什么样的栈。常用变量一览(摘自脚本帮助文本,实测 btcpay-setup.sh 无参数执行可查看全文):
| 变量 | 取值与作用 | 本文实测值 |
|---|---|---|
BTCPAY_HOST | 对外域名;HTTPS 由内置 nginx 自动签发证书 | btcpay.local(regtest 验证) |
NBITCOIN_NETWORK | 链网络:mainnet / testnet / signet / regtest | regtest |
BTCPAYGEN_CRYPTO1 | 第一种币(btc, ltc, grs, ftc, doge, mona, dash, xmr, bdx, lbtc, zec, dcr,默认 btc) | btc |
BTCPAYGEN_LIGHTNING | 闪电实现:clightning / lnd / phoenixd / none(默认 none) | none |
BTCPAYGEN_REVERSEPROXY | nginx(自动 HTTPS)/ none(关闭内置代理) | none(验证环境直连端口) |
BTCPAYGEN_ADDITIONAL_FRAGMENTS | 附加片段,分号分隔(如 opt-save-storage 区块裁剪) | 空 |
BTCPAYGEN_EXCLUDE_FRAGMENTS | 强制排除的片段,分号分隔 | 空 |
BTCPAY_PROTOCOL | 对外协议(默认 https) | http(regtest 验证) |
生产主网最小配置示例(域名需提前把 DNS A 记录指向本服务器):
export BTCPAY_HOST="pay.example.com"
export NBITCOIN_NETWORK="mainnet"
export BTCPAYGEN_CRYPTO1="btc"
export BTCPAYGEN_REVERSEPROXY="nginx"
3.2 克隆官方部署仓库并执行安装
git clone https://github.com/btcpayserver/btcpayserver-docker.git /root/btcpayserver-docker
cd /root/btcpayserver-docker
. ./btcpay-setup.sh -i
脚本会自动完成:安装缺失的 Docker/Compose、生成 compose 编译、写环境快照、注册开机自启、安装运维脚本到 /usr/local/bin、启动全部服务。实测回显(重复执行同一命令时的幂等输出,末尾节选;首次执行在同一位置显示的是镜像拉取与容器创建过程):
BTCPAY_DOCKER_COMPOSE=/root/btcpayserver-docker/Generated/docker-compose.generated.yml
Generating /app/Generated/docker-compose.generated.yml
Generated /app/Generated/pull-images.sh
Generated /app/Generated/docker-compose.generated.yml
Container generated_btcpayserver_1 Running
Container generated_postgres_1 Running
Container btcpayserver_bitcoind Running
Container generated_nbxplorer_1 Running
Installed bitcoin-cli.sh to /usr/local/bin: Command line for your Bitcoin instance
Installed btcpay-host to /usr/local/bin: Command line exposing the services of the host (see https://github.com/btcpayserver/btcpayserver/pull/7511)
Installed btcpay-fragments to /usr/local/bin: Command line for managing Docker Compose fragments
Installed btcpay-routes to /usr/local/bin: Command line for managing optional nginx routes
Installed btcpay-clean.sh to /usr/local/bin: Command line for deleting old unused docker images
Installed btcpay-down.sh to /usr/local/bin: Command line for stopping all services related to BTCPay Server
Installed btcpay-restart.sh to /usr/local/bin: Command line for restarting all services related to BTCPay Server
Installed btcpay-setup.sh to /usr/local/bin: Command line for restarting all services related to BTCPay Server
Installed btcpay-switch to /usr/local/bin: Command line for switching node implementations
Installed btcpay-up.sh to /usr/local/bin: Command line for starting all services related to BTCPay Server
Installed btcpay-admin.sh to /usr/local/bin: Command line for some administrative operation in BTCPay Server
Installed btcpay-update.sh to /usr/local/bin: Command line for updating your BTCPay Server to the latest commit of this repository
Installed changedomain.sh to /usr/local/bin: Command line for changing the external domain of your BTCPay Server
⚠️ 排障实录(重跑 setup 报 must be run as root):首次部署成功后,若在普通非登录 shell 里再次执行
. ./btcpay-setup.sh -i,会报This script must be run as root after running "sudo su -",与真实身份无关。真实原因:脚本检测到/etc/profile.d/btcpay-env.sh已存在但当前 shell 里BTCPAYGEN_CRYPTO1等变量为空(这些变量在首次部署后被写进 profile 快照,只有登录 shell 会自动加载)。解决:用bash -l进入登录 shell 后重跑,或重新export BTCPAYGEN_*各变量再执行。
3.3 生成产物结构
安装完成后落盘三类产物:
ls /root/btcpayserver-docker/Generated/
grep -E "^ [a-z0-9]+:" /root/btcpayserver-docker/Generated/docker-compose.generated.yml
实测回显:
btcpay-host-proxy
docker-compose.generated.yml
manifest.json
pihole
pull-images.sh
save-images.sh
torrc-relay.tmpl
torrc.tmpl
zcash.conf
btcpayserver:
postgres:
bitcoind:
nbxplorer:
- Generated/docker-compose.generated.yml:最终生效的编排文件(由所选片段合并生成),不要手改,配置变更一律通过环境变量 + 重跑 setup;
- /root/.env:环境变量快照,实测关键内容:
BTCPAY_PROTOCOL=http
BTCPAY_HOST=btcpay.local
REVERSEPROXY_HTTP_PORT=80
REVERSEPROXY_HTTPS_PORT=443
NBITCOIN_NETWORK=regtest
BTCPAY_CRYPTOS=btc
ACME_CA_URI=production
- /etc/profile.d/btcpay-env.sh:登录 shell 自动加载的环境快照(所有
BTCPAYGEN_*变量在此),这也是 3.3 排障实录里非登录 shell 丢变量的根源。
3.4 开机自启
setup 已把栈注册为 systemd 服务(服务名 btcpayserver)。确认:
systemctl is-enabled btcpayserver
实测回显:
enabled
四、部署验证
4.1 容器状态
docker ps --format "{{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}" | sort
实测回显:
btcpayserver_bitcoind btcpayserver/bitcoin:31.1-1 Up 57 minutes 8332-8333/tcp, 18332-18333/tcp, 18443-18444/tcp, 39388/tcp, 43782/tcp
generated_btcpayserver_1 btcpayserver/btcpayserver:2.4.5 Up 41 minutes 0.0.0.0:80->49392/tcp, [::]:80->49392/tcp
generated_nbxplorer_1 nicolasdorier/nbxplorer:2.6.19 Up 57 minutes 32838/tcp
generated_postgres_1 btcpayserver/postgres:18.6 Up 57 minutes 5432/tcp
BTCPAYGEN_REVERSEPROXY=none 时主程序容器直接把宿主 80 端口映射到容器内 49392;生产使用 nginx 片段时,对外是 nginx 容器的 80/443 并自动签发证书。
4.2 健康检查
curl -s --max-time 10 http://127.0.0.1:80/api/v1/health; echo
实测回显:
{"synchronized":true}
synchronized:true 表示主程序、NBXplorer、Bitcoin Core 整条链路健康且索引同步。
4.3 管理面与主程序日志
登录页可达性验证:
curl -s -o /dev/null -w "login HTTP=%{http_code}\n" --max-time 10 http://127.0.0.1:80/login
实测回显:
login HTTP=200
主程序日志头部(确认版本与配置来源):
docker logs generated_btcpayserver_1 2>&1 | head -7
实测回显:
bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
info: Configuration: Data Directory: /datadir
info: Configuration: Configuration File: /datadir/RegTest/settings.config
info: Configuration: Creating configuration file
info: BTCPayServer.Plugins.PluginManager: Loading plugins from /root/.btcpayserver/Plugins
info: BTCPayServer.Plugins.PluginManager: Running BTCPayServer - 2.4.5
info: Configuration: Supported chains: BTC
浏览器访问 http://<服务器IP>(生产为 https://你的域名)进入注册页,首个注册用户自动成为服务器管理员(示例账号 admin@example.com / q1w2e3r4,生产务必强口令)。
4.4 链状态验证
官方安装的 bitcoin-cli.sh 已自动带上容器内的 RPC 参数:
bitcoin-cli.sh getblockchaininfo | head -5
实测回显:
{
"chain": "regtest",
"blocks": 103,
"headers": 103,
"bestblockhash": "7e2a98736602bda9c104e9cc5366f9567898403573913d9aa897c8e76aec17d5",
"bits": "207fffff",
💡 说明:regtest 链由 NBXplorer 的 warmup 机制在启动后自动出块(默认开启),因此块高自动增长;生产 mainnet 则从 0 开始同步全链,耗时以小时~天计。regtest 验证完成后切主网只需改
NBITCOIN_NETWORK=mainnet重跑 setup,数据卷按网络隔离互不影响。
五、日常运维(官方 helper 脚本)
5.1 脚本清单
setup 安装到 /usr/local/bin 的 13 个运维脚本:
| 脚本 | 用途 |
|---|---|
| btcpay-setup.sh | (重)生成并启动整套栈;配置变更后重跑 |
| btcpay-up.sh | 启动所有服务 |
| btcpay-down.sh | 停止所有服务 |
| btcpay-restart.sh | 重启所有服务 |
| btcpay-update.sh | 更新部署仓库到最新提交并重建栈 |
| btcpay-clean.sh | 清理旧的无用 Docker 镜像 |
| btcpay-admin.sh | 管理操作(多因素/管理员/服务器策略) |
| btcpay-switch | 切换全节点实现 |
| btcpay-fragments | 管理 compose 片段 |
| btcpay-routes | 管理 nginx 可选路由 |
| btcpay-host | 查看宿主上各服务的访问命令行 |
| bitcoin-cli.sh | 执行 Bitcoin Core CLI(自动带容器 RPC 参数) |
| changedomain.sh | 变更对外域名 |
5.2 停止与启动(数据持久化验证)
btcpay-down.sh
实测回显(末尾节选):
Container generated_postgres_1 Stopping
Container generated_postgres_1 Stopped
Container generated_postgres_1 Removing
Container generated_postgres_1 Removed
Network generated_default Removing
Network generated_default Removed
重新启动:
btcpay-up.sh
sleep 6
curl -s --max-time 10 http://127.0.0.1:80/api/v1/health; echo
实测回显(末尾节选):
Container generated_nbxplorer_1 Started
Container generated_btcpayserver_1 Started
{"synchronized":true}
💡 说明:down 会移除容器与网络,但六个数据卷全部保留,up 后数据原样恢复(实测 health 直接回到 synchronized)。重启等价命令
btcpay-restart.sh。
5.3 日志查看
docker logs generated_btcpayserver_1 --tail 20
docker logs btcpayserver_bitcoind --tail 20
docker logs generated_nbxplorer_1 -f
5.4 管理操作:btcpay-admin.sh
btcpay-admin.sh
实测回显:
Usage: /usr/local/bin/btcpay-admin.sh [command]
Commands:
disable-multifactor <email>
set-user-admin <email>
reset-server-policy
set-user-admin <邮箱>:把已有用户提升为服务器管理员;disable-multifactor <邮箱>:清除某用户的 2FA/U2F/FIDO2 凭据(管理员丢失验证器时的恢复手段);reset-server-policy:重置服务器级策略设置。
⚠️ 排障实录(非 mainnet 网络下报库不存在):在
NBITCOIN_NETWORK=regtest的栈上执行btcpay-admin.sh set-user-admin admin@example.com实测报错:psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: database "btcpayservermainnet" does not exist原因:脚本内 SQL 固定连
btcpayservermainnet库,而非 mainnet 网络下数据库后缀跟随网络(regtest 栈实际库名为btcpayserverregtest,实测docker exec generated_postgres_1 psql -U postgres -l可见)。变通做法是在 postgres 容器内手动执行等效 SQL(以 set-user-admin 为例):docker exec -i generated_postgres_1 psql -U postgres -d btcpayserverregtest \ -c "INSERT INTO \"AspNetUserRoles\" Values ( (SELECT \"Id\" FROM \"AspNetUsers\" WHERE upper('admin@example.com') = \"NormalizedEmail\"), (SELECT \"Id\" FROM \"AspNetRoles\" WHERE \"NormalizedName\"='SERVERADMIN'))"执行后复核角色(实测回显;若用户已是管理员会报 duplicate key 唯一约束冲突,同样说明其已是管理员):
Email | Name -------------------+------------- admin@example.com | ServerAdmin (1 row)
六、升级与配置变更
6.1 变更配置的标准流程
任何配置变更(换域名、加币种、开闪电、调整反向代理)都遵循同一流程:导出/修改环境变量 → 重跑 setup → 栈自动按新配置重建。setup 是幂等的,重复执行只会重建发生变化的容器(见 3.2 的 Running 输出)。
示例:把验证栈切到主网:
bash -l
export BTCPAY_HOST="pay.example.com"
export NBITCOIN_NETWORK="mainnet"
export BTCPAYGEN_REVERSEPROXY="nginx"
cd /root/btcpayserver-docker
. ./btcpay-setup.sh -i
6.2 版本锁定与升级
- 锁定版本:环境变量
BTCPAY_IMAGE=btcpayserver/btcpayserver:2.4.5可显式固定主程序版本(默认跟随仓库片段的当前稳定版); - 官方更新:
btcpay-update.sh会拉取部署仓库最新提交并重建栈(主程序版本随官方片段演进);更新后建议立即验证docker ps中的镜像标签与/api/v1/health; - 升级前必读:核对目标版本 Release Notes 的 Breaking changes(如 v2.4.5 默认开启的 SSRF 私网出站阻断会影响内网 webhook/闪电联动,需
ssrfexceptions显式放行),详见《BTCPay Server 2.4.5 介绍与选型指南》第四章。
💡 说明:生产升级前建议先用
btcpay-backup.sh(官方备份脚本)备份数据卷,恢复使用btcpay-restore.sh。
6.3 存储裁剪(可选)
主网全链同步磁盘压力大时,通过附加片段启用区块裁剪:BTCPAYGEN_ADDITIONAL_FRAGMENTS="opt-save-storage"(另有 -s 50 GB / -xs 25 GB / -xxs 5 GB 三档),磁盘估算公式与资源口径见《BTCPay Server 2.4.5 介绍与选型指南》第五章。
七、常见问题(排障实录)
7.1 重跑 btcpay-setup.sh 报 must be run as root
现象:root 身份重跑 setup 仍报 This script must be run as root after running "sudo su -"。
定位:脚本发现 profile 快照已存在但当前 shell 的 BTCPAYGEN_CRYPTO1 为空(非登录 shell 不加载 /etc/profile.d/btcpay-env.sh),报错文案有误导性。
解决:bash -l 进入登录 shell 或重新 export 各 BTCPAYGEN_* 变量后再执行(见 3.2 排障实录)。
7.2 btcpay-admin.sh 报 database "btcpayservermainnet" does not exist
现象:非 mainnet 网络(regtest/testnet)栈上执行 btcpay-admin.sh 子命令报库不存在。
定位:脚本 SQL 硬编码 mainnet 库名,其他网络下库名后缀跟随网络。
解决:在 postgres 容器内对实际库名(如 btcpayserverregtest)手动执行等效 SQL(见 5.4 排障实录)。
7.3 NBXplorer 日志提示 RPC wallet 功能被禁用
现象:docker logs generated_nbxplorer_1 出现:
BTC: RPC wallet features are disabled because neither 'BTC.rpc.defaultwallet' nor 'NBXPLORER_BTC_RPC_DEFAULTWALLET' is configured.
定位与影响:官方片段默认不为 NBXplorer 指定节点钱包上下文;链上收款索引不受影响,但依赖 NBXplorer RPC wallet 的「生成热钱包」路径会受限。需要该能力时,可参照手动部署方式为 NBXplorer 显式指定 --btcrpcdefaultwallet(参数实测见《Ubuntu 22.04 安装 BTCPay Server 2.4.5 指南》5.6)。
7.4 Bitcoin Core 日志出现 Ignoring unknown configuration value
现象:docker logs btcpayserver_bitcoind 头部出现:
[warning] Ignoring unknown configuration value regtest.mempoolfullrbf
定位:部署片段中的旧配置键在 Bitcoin Core 31 中已被移除,Core 忽略并给出 warning,不影响功能;随官方片段更新会消除。
7.5 主程序健康检查返回 synchronized:false
现象:刚 btcpay-up.sh 或重启后短暂返回 {"synchronized":false}。
定位:NBXplorer 重建后需要重新完成索引就绪,属正常瞬态。
判断:等待数十秒后复查;NBXplorer 日志出现 Node state changed: NBXplorerSynching => Ready 即恢复(实测见 5.2)。
八、卸载
# 1. 停止并删除栈(容器与网络;加 -v 连数据卷一并删除)
btcpay-down.sh
cd /root/btcpayserver-docker
docker compose -f Generated/docker-compose.generated.yml down -v
# 2. 删除数据卷(未用 down -v 时手动删)
docker volume ls --format "{{.Name}}" | grep "^generated_" | xargs -r docker volume rm
# 3. 删除部署仓库、环境快照与运维脚本
rm -rf /root/btcpayserver-docker /root/.env /etc/profile.d/btcpay-env.sh
rm -f /usr/local/bin/{btcpay-setup.sh,btcpay-up.sh,btcpay-down.sh,btcpay-restart.sh,btcpay-update.sh,btcpay-clean.sh,btcpay-admin.sh,btcpay-switch,btcpay-fragments,btcpay-routes,btcpay-host,bitcoin-cli.sh,changedomain.sh}
systemctl disable --now btcpayserver 2>/dev/null
rm -f /etc/systemd/system/btcpayserver.service
systemctl daemon-reload
⚠️ 注意:第 2 步会永久删除全部链数据、发票与商店数据,执行前确认已备份。
九、参考链接
- 部署仓库:https://github.com/btcpayserver/btcpayserver-docker (含 configuration.md 环境变量参考)
- 主仓库:https://github.com/btcpayserver/btcpayserver (v2.4.5 标签)
- 官方文档站:https://docs.btcpayserver.org
- Greenfield API 文档:https://docs.btcpayserver.org/API/Greenfield/v1/
- 手动部署形态:《Ubuntu 22.04 安装 BTCPay Server 2.4.5 指南》
- 组件背景与选型:《BTCPay Server 2.4.5 介绍与选型指南》