−25%

on annual Windows plans, until 31 Oct. See plans

EQVPS
Get started

VPS for BTCPay Server: take crypto on your server

Run BTCPay Server with its own pruned Bitcoin node: payments go straight to your wallet, no processor in between. Tested install, disk math for 35 GB, caveats.

Every payment processor in the middle comes with its own terms, its own KYC and its own button that freezes your balance. BTCPay Server removes the middle. Invoices are created on your server, the customer pays to an address derived from your wallet, and your own Bitcoin node confirms the payment. Nobody can switch it off but you.

It's for shops, freelancers and services that already take bitcoin — or want to — and would rather not hand that job to a company.

Which plan

BTCPay runs as about seven containers: the BTCPay app, NBXplorer (which watches the chain), Bitcoin Core, Postgres and an nginx front with automatic Let's Encrypt. On our test server they used around 0.7 GB of RAM at the start, and Bitcoin Core takes more while it syncs; 4 GB is plenty. Disk is the real constraint, not memory.

SetupPlan
On-chain BTC, pruned node keeping ~5 GB of blocksSmall-IP — 4 vCPU, 4 GB, 35 GB ($16/mo)
Same, with more breathing room for logs and updatesMedium-IP — 6 vCPU, 6 GB, 45 GB ($20/mo)
Lightning, a bigger block window, or a second coinPro-32 — 8 vCPU, 32 GB, 400 GB ($40/mo), on request

You need a plan with its own IPv4: customers reach BTCPay over HTTPS, and Let's Encrypt has to reach port 80. Choose Germany or Finland, whichever is available at checkout — for a payment page, latency hardly matters. And since the whole point is taking crypto, it's fitting that the server itself is paid in crypto without KYC.

Install

Point pay.example.com at the server, then, as root on a fresh Ubuntu 24.04 or Debian 12:

mkdir BTCPayServer && cd BTCPayServer
git clone https://github.com/btcpayserver/btcpayserver-docker
cd btcpayserver-docker

export BTCPAY_HOST="pay.example.com"
export LETSENCRYPT_EMAIL="you@yourdomain.com"
export NBITCOIN_NETWORK="mainnet"
export BTCPAYGEN_CRYPTO1="btc"
export BTCPAYGEN_ADDITIONAL_FRAGMENTS="opt-save-storage-xxs"
export BTCPAYGEN_REVERSEPROXY="nginx"
export BTCPAYGEN_LIGHTNING="none"
. ./btcpay-setup.sh -i

opt-save-storage-xxs is what makes it fit: Bitcoin Core prunes down to 5 GB of blocks. The script pulls the images, creates a btcpayserver systemd service and starts everything. It also restarts the Docker daemon on the way — one more reason to give BTCPay a server of its own rather than squeezing it next to other containers.

Check the node:

bitcoin-cli.sh getblockchaininfo

Look at blocks against headers, and at "pruned": true. Twenty minutes into our test it had about 218,000 of roughly 972,000 blocks — the early ones are tiny, so don't extrapolate from that. The real work comes later.

First login: do it now

Open https://pay.example.com the moment it answers. BTCPay sends you to a registration page, and the first account becomes the server admin. If someone else finds the page before you do, they own your payment server. Register, then look under Server Settings → Policies and make sure new sign-ups are the way you want them.

Then create a store and connect your wallet with its extended public key (xpub) — from a hardware wallet or your desktop wallet's export. BTCPay derives a fresh address for every invoice and never sees a private key. Use a fresh wallet or a fresh account for this rather than one with years of history behind it: a pruned node is happiest tracking what happens from now on.

Until the node catches up, BTCPay shows that it's still synchronizing and won't watch for payments. Plan the launch for after the sync, not for the evening you install it.

Things you should know before going live

  • The first sync is long. A pruned node still downloads and verifies the entire chain — more than 700 GB — before it can throw old blocks away. Traffic on our plans is unmetered at 1 Gbit/s, so it costs nothing extra, but on a 4-vCPU server think in days. There's a fast-sync script in the repository; it skips that work by trusting someone else's copy of the UTXO set, which defeats part of the reason you're running a node.
  • Updates. btcpay-update.sh pulls the latest BTCPay and its dependencies. Run it in a quiet hour, not during a sale.
  • What to back up. With an xpub-only wallet your coins aren't on the server. What you'd lose is the store setup and invoice history in Postgres — back up that volume, and keep your wallet's seed somewhere that has nothing to do with this server.
  • Lightning later. Start on-chain. Lightning means a bigger block window, channel management and inbound liquidity — a project of its own, and a Pro plan, which we set up on request.

My take: for a small shop that takes bitcoin once a day, BTCPay on Small-IP is the cleanest setup there is. If you need card payments or fiat payouts, this isn't that tool.

Ready to deploy? Pay with crypto, no KYC — live in about a minute.

Deploy now →

FAQ

How much disk does BTCPay Server need?

With the opt-save-storage-xxs profile the Bitcoin node keeps only about 5 GB of blocks. On top of that come the chainstate (the UTXO set, around a dozen GB and growing), roughly 2.5 GB of Docker images and the OS. That fits the 35 GB of Small-IP. The next profile up, opt-save-storage-xs, keeps 25 GB of blocks on its own and needs a Pro plan, available on request.

How long does the first sync take?

Days, not hours. Even a pruned node downloads and checks the whole Bitcoin blockchain — more than 700 GB of traffic — and only then throws the old blocks away. Traffic is unmetered on our plans, so the download costs nothing extra, but BTCPay won't see payments until the node has caught up.

Does BTCPay hold my coins?

Not if you connect a wallet by its extended public key (xpub). The server can then create addresses and watch for payments, but it has no private keys and can't spend anything. Losing the server means losing the store settings, not the money.

Do I need a dedicated IP?

Yes. Your shop and your customers' browsers have to reach BTCPay on port 443, and Let's Encrypt needs port 80 to issue the certificate. A NAT plan only accepts your SSH port from outside.

Can it take Lightning or Monero too?

Both exist as options, but neither fits the small plans. A Lightning node wants a bigger block window and more care than on-chain payments; a Monero node needs far more disk than a pruned Bitcoin node. Start with on-chain bitcoin on Small-IP; for either of them, ask us about a Pro plan.

Comments

No comments yet. Be the first.

Leave a comment

Comments are moderated before they appear.