Deploy BTCPay Server

Bitcoin payment processor for accepting payments in your own store

Deploy BTCPay Server

/var/lib/postgresql/data

Just deployed

/data

Just deployed

/datadir

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.

Diagram of the BTCPay Server, NBXplorer, Bitcoin Core and Postgres services on Railway

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.

BTCPay store dashboard showing a settled invoice and wallet balance

BTCPay checkout page with a Bitcoin address and payment QR code

BTCPay point of sale app listing priced tea products

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

  • btcpayserverbtcpayserver/btcpayserver:2.4.3, the ASP.NET web application
  • nbxplorernicolasdorier/nbxplorer:2.6.11, the wallet indexer
  • bitcoindbtcpayserver/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

VariableServicePurpose
BTCPAY_ADMIN_EMAILbtcpayserverServer admin created on first boot
BTCPAY_ADMIN_PASSWORDbtcpayserverIts password; needs a symbol and digit
BITCOIN_NETWORKall threeregtest default; mainnet, signet, testnet
BITCOIN_PRUNEbitcoindMB of blocks kept; 0 disables pruning
BITCOIN_RPC_PASSWORDbitcoindShared with NBXplorer; rpcauth derived
NBXPLORER_BTCRPCURLnbxplorerBitcoin Core RPC endpoint
NBXPLORER_BTCNODEENDPOINTnbxplorerBitcoin Core P2P endpoint

Deployment Dependencies

Hardware Requirements for Self-Hosting BTCPay Server

ResourceMinimumRecommended
CPU2 vCPU4 vCPU during the initial sync
RAM2 GB4 GB across all services
Storageunder 1 GB on regtest60 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

More templates in this category

View Template
Rocky Linux
Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀

codestorm
44
View Template
Foundry Virtual Tabletop
A Self-Hosted & Modern Roleplaying Platform

Lucas
71
View Template
Letta Code Remote
Run a Letta Code agent 24/7. No inbound ports, just deploy.

Letta
51