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 ServerBTCPay ServerDocker加密货币支付系统2026/10/23

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
Docker29.9.2(官方 apt 源 docker-ce)
Docker Composev5.6.1(docker-compose-plugin)
验证链网络regtest(私有测试链)
部署仓库btcpayserver-docker(2026-10-22 克隆)

生成的栈内组件镜像(官方部署仓库片段锁定组合,与 v2.4.5 配套):

服务镜像说明
btcpayserverbtcpayserver/btcpayserver:2.4.5主程序(.NET 10)
nbxplorernicolasdorier/nbxplorer:2.6.19链上索引器
bitcoindbtcpayserver/bitcoin:31.1-1Bitcoin Core 31.1 全节点
postgresbtcpayserver/postgres:18.6PostgreSQL 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_datadirBTCPay Server 数据(含 settings.config)
generated_btcpay_pluginsdir插件目录
generated_nbxplorer_datadirNBXplorer 索引数据
generated_bitcoin_datadirBitcoin Core 区块与链状态
generated_bitcoin_wallet_datadirBitcoin Core 钱包
generated_postgres_datadirPostgreSQL 数据文件

二、前置条件:安装 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 / regtestregtest
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_REVERSEPROXYnginx(自动 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 步会永久删除全部链数据、发票与商店数据,执行前确认已备份。

九、参考链接