Deploy BTCPay Server
Bitcoin payment processor for accepting payments in your own store
Just deployed
/var/lib/postgresql/data
bitcoind
Just deployed
/data
nbxplorer
Just deployed
/datadir
btcpayserver
Just deployed
/data
Deploy and Host BTCPay Server on Railway
BTCPay Server is a free, open-source Bitcoin payment processor a merchant runs themselves. Where BitPay or Coinbase Commerce sits between a shop and its customers — holding funds, demanding identity documents, taking a percentage — BTCPay Server generates invoices against a wallet the merchant controls, so payments settle on-chain or over Lightning with no intermediary and no fee. It ships a checkout page, a point of sale, payment buttons, crowdfunding pages, refunds, payouts and a REST API, plus plugins for WooCommerce and Shopify.
Self-host BTCPay Server on Railway and four services come up wired together.
btcpayserver is the web application and the only one with a public URL. nbxplorer
is the UTXO indexer it depends on: it watches the chain for the addresses your wallets
derive and tells BTCPay when an invoice is paid. bitcoind is Bitcoin Core, pruned to
fit a Railway volume, and the only source of truth about the chain. Postgres holds
BTCPay's stores, invoices and users alongside NBXplorer's index. Traffic reaches only
btcpayserver, which talks to nbxplorer privately, which talks to bitcoind over
JSON-RPC and the Bitcoin peer-to-peer protocol.

Getting Started with BTCPay Server on Railway
Set BTCPAY_ADMIN_EMAIL and BTCPAY_ADMIN_PASSWORD before you deploy: the first
container creates that server-admin account and closes public registration in the same
step, so nobody can claim your server while it boots. The password needs an upper-case
letter, a lower-case letter, a digit and a symbol. Open the deployed URL, sign in, and
BTCPay lands you on Create your first store — give it a name and a display currency.
Then choose Set up a wallet → Create a new wallet: hot if you want BTCPay to be
able to spend, watch-only to keep keys off the server. Write the recovery phrase down;
it is shown once. Now hit Create Invoice, enter an amount, and you get a checkout
page with an address, a QR code and a countdown. The default chain is regtest with
BTCPAY_CHEATMODE on, so that page also carries Pay and Mine controls: click
Pay, then Mine, and the invoice goes Processing then Settled — the end-to-end proof
that all four services are talking.



About Hosting BTCPay Server
Accepting Bitcoin through a processor reintroduces the custodian a merchant was trying to avoid: funds land in the processor's wallet, accounts get frozen, and a percentage of every sale leaves the business. Self-hosting moves invoice generation and payment detection onto infrastructure you control, and the money goes straight to your own extended public key.
- Invoices and checkout — payment pages with configurable expiry, exchange rates and partial-payment handling
- Wallets — hot or watch-only, hardware wallets, PSBT, coin selection
- Apps — point of sale, crowdfunding, payment buttons, pull payments, payouts
- Lightning — connect an external LND, Core Lightning or phoenixd node
The split matters. BTCPay never talks to Bitcoin Core directly: NBXplorer indexes the transactions that concern your wallets, so BTCPay can ask "was invoice X paid?" without scanning the chain. Bitcoin Core validates every block itself, which is what makes the deployment trustless.
Why Deploy BTCPay Server on Railway
Railway removes the server administration BTCPay usually comes with.
- Four services, one volume each, connected in a single deploy
- TLS and a public hostname on the web app, nothing else exposed
- Private networking between BTCPay, NBXplorer and Bitcoin Core
- Managed PostgreSQL instead of a hand-rolled container
- Real health checks on every application service
Common Use Cases
- An online shop taking Bitcoin directly — the WooCommerce or Shopify plugin in front of a store, settling to your own wallet with no processor fee
- Donations and fundraising — a crowdfunding page or an embedded payment button
- A physical point of sale — the POS app on a tablet, for a market stall or café
- Programmatic billing — the REST API and webhooks, driving invoices from your app
Dependencies for BTCPay Server
- btcpayserver —
btcpayserver/btcpayserver:2.4.3, the ASP.NET web application - nbxplorer —
nicolasdorier/nbxplorer:2.6.11, the wallet indexer - bitcoind —
btcpayserver/bitcoin:31.1, Bitcoin Core - Postgres — managed PostgreSQL, two databases on one server
NBXplorer is not optional: BTCPay stores no chain data and asks it for balances, unspent outputs and payment notifications. The three application services build from gridalpha/btcpay-server-railway.
Environment Variables Reference
| Variable | Service | Purpose |
|---|---|---|
BTCPAY_ADMIN_EMAIL | btcpayserver | Server admin created on first boot |
BTCPAY_ADMIN_PASSWORD | btcpayserver | Its password; needs a symbol and digit |
BITCOIN_NETWORK | all three | regtest default; mainnet, signet, testnet |
BITCOIN_PRUNE | bitcoind | MB of blocks kept; 0 disables pruning |
BITCOIN_RPC_PASSWORD | bitcoind | Shared with NBXplorer; rpcauth derived |
NBXPLORER_BTCRPCURL | nbxplorer | Bitcoin Core RPC endpoint |
NBXPLORER_BTCNODEENDPOINT | nbxplorer | Bitcoin Core P2P endpoint |
Deployment Dependencies
- BTCPay Server and its docs
- NBXplorer, Bitcoin Core
Hardware Requirements for Self-Hosting BTCPay Server
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 2 vCPU | 4 vCPU during the initial sync |
| RAM | 2 GB | 4 GB across all services |
| Storage | under 1 GB on regtest | 60 GB+ for pruned mainnet |
| Runtime | .NET 10, Bitcoin Core 31, PostgreSQL 16+ | — |
Storage is the binding constraint: a pruned mainnet node still holds the whole
unspent-output set, roughly 15 GB and growing, on top of the blocks it keeps, and
signet's has grown past 4 GB too. The default chain is therefore regtest, a private
network with nothing to download. For real payments, either give Bitcoin Core a volume
that fits the chain and set BITCOIN_NETWORK=mainnet on all three, or point
NBXPLORER_BTCRPCURL and NBXPLORER_BTCNODEENDPOINT at a mainnet node you already
run and delete bitcoind.
Self-Hosting BTCPay Server
Upstream's install path is a shell script that generates a Docker Compose file:
git clone https://github.com/btcpayserver/btcpayserver-docker
cd btcpayserver-docker
export BTCPAY_HOST="btcpay.example.com" NBITCOIN_NETWORK="mainnet"
export BTCPAYGEN_CRYPTO1="btc"
. ./btcpay-setup.sh -i
That wants a dedicated machine with a DNS name and root access. To reproduce the Railway shape by hand, run the three images directly:
docker run -d --name bitcoind -e BITCOIN_NETWORK=regtest btcpayserver/bitcoin:31.1
docker run -d --name nbxplorer -e NBXPLORER_NETWORK=regtest \
-e NBXPLORER_BTCNODEENDPOINT=bitcoind:39388 nicolasdorier/nbxplorer:2.6.11
docker run -d -p 8080:8080 -e BTCPAY_NETWORK=regtest \
-e BTCPAY_BTCEXPLORERURL=http://nbxplorer:32838/ btcpayserver/btcpayserver:2.4.3
How Much Does BTCPay Server Cost to Self-Host?
BTCPay Server, NBXplorer and Bitcoin Core are MIT-licensed and free. There is no paid tier, no per-transaction fee and no revenue share — the project runs on donations and grants. What you pay is infrastructure: on Railway, the compute and storage the four services use, dominated by Bitcoin Core's disk and the CPU it burns during the initial sync. Against a processor charging around 1% per transaction, that pays for itself quickly.
FAQ
What is BTCPay Server? A self-hosted, open-source Bitcoin payment processor. It creates invoices, shows a checkout page, watches the chain for payment and notifies your shop — against a wallet you control, with no company in the middle.
What does this Railway template deploy? Four services: BTCPay Server, NBXplorer, a pruned Bitcoin Core node and PostgreSQL. Only BTCPay Server gets a public URL; the rest stay private.
Why does it need NBXplorer and Bitcoin Core? BTCPay does not index the chain. NBXplorer keeps the wallet index and answers "has this address been paid?"; Bitcoin Core validates blocks, so no third-party API decides whether you were paid.
How do I switch BTCPay Server from regtest to Bitcoin mainnet?
Set BITCOIN_NETWORK=mainnet on all three services and give Bitcoin Core a volume big
enough for a pruned mainnet node, or point NBXplorer at a node you run and delete
bitcoind. Each network gets its own database, so nothing carries across.
Can I accept Lightning payments on a self-hosted BTCPay Server? Yes — this template deploys the on-chain stack. Add an LND, Core Lightning or phoenixd node and connect it from Store → Lightning.
Is my Bitcoin held by BTCPay Server? Only with a hot wallet, where the private key sits on the server. A watch-only wallet keeps keys off it entirely: BTCPay watches for payments, you sign spends elsewhere.
Template Content
bitcoind
gridalpha/btcpay-server-railwaynbxplorer
gridalpha/btcpay-server-railwaybtcpayserver
gridalpha/btcpay-server-railway
