Skip to content

Deploying BTCPay Server

BTCPay Server is a free, open-source, and self-hosted Bitcoin payment processor that allows merchants to accept Bitcoin without fees, intermediaries, or third-party involvement. As a true non-custodial solution, payments go directly to your wallet—your private keys never leave your server.

Built with .NET Core and PostgreSQL, BTCPay Server provides a complete payment infrastructure including invoicing, point-of-sale, crowdfunding, and support for Lightning Network payments. Over 7,000 merchants worldwide trust BTCPay Server for their Bitcoin payment processing needs.

Zero Fees

No transaction fees beyond Bitcoin network fees

Non-Custodial

Complete control over your private keys

Lightning Network

Instant, low-cost payments via Lightning

Self-Hosted

Your server, your rules, your data

Key Features

BTCPay Server offers comprehensive Bitcoin payment processing:

FeatureDescription
Invoice ManagementCreate and track Bitcoin payment invoices
Point of SaleBuilt-in POS app for retail environments
Payment RequestsShareable payment links
CrowdfundingHost Bitcoin crowdfunding campaigns
Lightning NetworkSupport for LND, Core Lightning, and Eclair
Multi-tenantHost multiple stores on one instance
Hardware WalletIntegration with Ledger, Trezor, and more
API AccessFull Greenfield REST API

Architecture Overview

BTCPay Server is a complex multi-component system:

ComponentPurposeRequired
BTCPay ServerMain web application and APIYes
NBXplorerLightweight blockchain explorerYes
Bitcoin CoreFull Bitcoin nodeYes
PostgreSQLDatabase for BTCPay and NBXplorerYes
Lightning (LND/CLN)Lightning Network paymentsOptional
NginxReverse proxy with SSLRecommended

Deployment Options

Given BTCPay Server’s complexity, there are several deployment approaches:

Option 1: Full Stack (Multiple Klutch.sh Apps)

Deploy each component as a separate Klutch.sh app:

  • PostgreSQL database
  • Bitcoin Core full node (requires 300+ GB storage)
  • NBXplorer
  • BTCPay Server
  • Optional: Lightning daemon

Option 2: BTCPay Server with External Services

Deploy only BTCPay Server on Klutch.sh, connecting to:

  • External Bitcoin node (via RPC)
  • External NBXplorer instance
  • Managed PostgreSQL

Option 3: Use Third-Party BTCPay Hosting

For smaller deployments, consider third-party BTCPay hosting services.

Prerequisites

Before deploying BTCPay Server on Klutch.sh, ensure you have:

  • A Klutch.sh account with an active project
  • A GitHub repository for your deployment
  • Access to a running Bitcoin Core node with RPC enabled
  • A running NBXplorer instance connected to your Bitcoin node
  • A PostgreSQL database (can be deployed on Klutch.sh)

Project Structure

Set up your BTCPay Server deployment repository:

  • Directorybtcpayserver/
    • Dockerfile
    • docker-compose.yml (local development only)
    • .env.example
    • README.md

Deployment Configuration

Dockerfile

Create a Dockerfile for BTCPay Server:

Dockerfile
FROM btcpayserver/btcpayserver:latest
# BTCPay Server runs on port 49392 by default in the container
# The environment variables control the actual binding
ENV BTCPAY_BIND="0.0.0.0"
ENV BTCPAY_PORT="49392"
# Data directory for BTCPay Server
ENV BTCPAY_DATADIR="/datadir"
# Expose the application port
EXPOSE 49392
# Volume for persistent data
VOLUME /datadir

Alternative: Build from Source

For more control, build BTCPay Server from source:

Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS builder
WORKDIR /source
# Clone BTCPay Server
RUN git clone --depth 1 --branch latest https://github.com/btcpayserver/btcpayserver.git .
# Build the application
RUN cd BTCPayServer && dotnet publish -c Release -o /app
# Runtime image
FROM mcr.microsoft.com/dotnet/aspnet:8.0
RUN apt-get update && apt-get install -y --no-install-recommends \
iproute2 openssh-client ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=builder /app .
ENV BTCPAY_DATADIR=/datadir
ENV BTCPAY_BIND=0.0.0.0
ENV BTCPAY_PORT=49392
EXPOSE 49392
VOLUME /datadir
ENTRYPOINT ["dotnet", "BTCPayServer.dll"]

Environment Variables

BTCPay Server is configured primarily through environment variables:

Required Variables

VariableDescriptionExample
BTCPAY_POSTGRESPostgreSQL connection stringHost=postgres;Database=btcpay;...
BTCPAY_BTCEXPLORERURLNBXplorer URL for Bitcoinhttp://nbxplorer:32838/
BTCPAY_NETWORKBitcoin networkmainnet, testnet, regtest
BTCPAY_BINDBind address0.0.0.0
BTCPAY_PORTServer port49392

Database Configuration

VariableDescription
BTCPAY_POSTGRESFull PostgreSQL connection string
BTCPAY_EXPLORERPOSTGRESNBXplorer database connection (optional)

Example PostgreSQL connection string:

User ID=btcpay;Password=yourpassword;Host=your-postgres-host;Port=5432;Database=btcpay;

Network Configuration

VariableDescription
BTCPAY_ROOTPATHRoot path for reverse proxy
BTCPAY_SSHCONNECTIONSSH connection for server management
BTCPAY_SSHTRUSTEDFINGERPRINTSSSH fingerprints

Lightning Network Configuration

VariableDescription
BTCPAY_BTCLIGHTNINGLightning connection string

Example LND connection:

type=lnd-rest;server=https://lnd:8080/;macaroonfilepath=/path/to/admin.macaroon;allowinsecure=true

Example Core Lightning connection:

type=clightning;server=unix://root/.lightning/bitcoin/lightning-rpc

Optional Configuration

VariableDescriptionDefault
BTCPAY_DEBUGLOGEnable debug loggingfalse
BTCPAY_UPDATEURLUpdate check URLBTCPay default
BTCPAY_DOCKERDEPLOYMENTDocker deployment modefalse

Local Development with Docker Compose

Test your BTCPay Server setup locally:

docker-compose.yml
services:
btcpayserver:
image: btcpayserver/btcpayserver:latest
ports:
- "49392:49392"
depends_on:
postgres:
condition: service_healthy
nbxplorer:
condition: service_started
environment:
BTCPAY_POSTGRES: "User ID=btcpay;Password=btcpay;Host=postgres;Port=5432;Database=btcpay;"
BTCPAY_NETWORK: "regtest"
BTCPAY_BIND: "0.0.0.0"
BTCPAY_PORT: "49392"
BTCPAY_BTCEXPLORERURL: "http://nbxplorer:32838/"
BTCPAY_DEBUGLOG: "btcpay.log"
volumes:
- btcpay_data:/datadir
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: btcpay
POSTGRES_USER: btcpay
POSTGRES_PASSWORD: btcpay
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U btcpay -d btcpay"]
interval: 5s
timeout: 5s
retries: 5
bitcoind:
image: btcpayserver/bitcoin:29.1
environment:
BITCOIN_NETWORK: "regtest"
BITCOIN_EXTRA_ARGS: |
server=1
rpcuser=rpc
rpcpassword=rpc
rpcallowip=0.0.0.0/0
rpcbind=0.0.0.0
volumes:
- bitcoin_data:/data
nbxplorer:
image: nicolasdorier/nbxplorer:latest
depends_on:
- bitcoind
environment:
NBXPLORER_NETWORK: "regtest"
NBXPLORER_BTCRPCURL: "http://bitcoind:43782/"
NBXPLORER_BTCRPCUSER: "rpc"
NBXPLORER_BTCRPCPASSWORD: "rpc"
NBXPLORER_BIND: "0.0.0.0"
NBXPLORER_PORT: "32838"
volumes:
- nbxplorer_data:/datadir
volumes:
btcpay_data:
postgres_data:
bitcoin_data:
nbxplorer_data:

Deploying to Klutch.sh

Step 1: Deploy PostgreSQL Database

  1. Create a PostgreSQL app on Klutch.sh

    1. Navigate to your Klutch.sh dashboard at klutch.sh/app
    2. Select your project or create a new one
    3. Click Create App and connect a repository with a PostgreSQL Dockerfile

    See our PostgreSQL deployment guide for detailed instructions.

  2. Create the BTCPay database

    1. Connect to your PostgreSQL instance
    2. Create the database and user
    CREATE DATABASE btcpay TEMPLATE 'template0' LC_CTYPE 'C' LC_COLLATE 'C' ENCODING 'UTF8';
    CREATE USER btcpay WITH ENCRYPTED PASSWORD 'your-secure-password';
    GRANT ALL PRIVILEGES ON DATABASE btcpay TO btcpay;
  3. Note your connection details

    1. Record the internal hostname
    2. Note the database name, username, and password

Step 2: Set Up Bitcoin Infrastructure

  1. Option A: Deploy Bitcoin Core on Klutch.sh

    1. Create a new app with a Bitcoin Core Dockerfile
    2. Attach a persistent volume of at least 500 GB at /data
    3. Configure for RPC access
    Dockerfile
    FROM btcpayserver/bitcoin:29.1
    ENV BITCOIN_NETWORK=mainnet
    ENV BITCOIN_EXTRA_ARGS="server=1\nrpcuser=btcpay\nrpcpassword=your-password\nrpcallowip=10.0.0.0/8\nprune=50000"
    VOLUME /data
    EXPOSE 8332 8333
  2. Option B: Use an external Bitcoin node

    1. Ensure your Bitcoin node has RPC enabled
    2. Allow RPC connections from Klutch.sh IP ranges
    3. Note your RPC URL, username, and password

Step 3: Deploy NBXplorer

NBXplorer is required as the blockchain indexer:

  1. Create a Dockerfile for NBXplorer

    Dockerfile
    FROM nicolasdorier/nbxplorer:latest
    ENV NBXPLORER_NETWORK=mainnet
    ENV NBXPLORER_BIND=0.0.0.0
    ENV NBXPLORER_PORT=32838
    VOLUME /datadir
    EXPOSE 32838
  2. Deploy on Klutch.sh

    1. Create a new app with the NBXplorer Dockerfile
    2. Configure environment variables for Bitcoin RPC connection
    3. Attach a persistent volume at /datadir (10-20 GB)
    VariableValue
    NBXPLORER_NETWORKmainnet
    NBXPLORER_BTCRPCURLYour Bitcoin RPC URL
    NBXPLORER_BTCRPCUSERYour RPC username
    NBXPLORER_BTCRPCPASSWORDYour RPC password
    NBXPLORER_BIND0.0.0.0
    NBXPLORER_PORT32838

Step 4: Deploy BTCPay Server

  1. Push your repository to GitHub

    1. Create a new repository with the BTCPay Server Dockerfile
    Terminal window
    git init
    git add .
    git commit -m "Initial BTCPay Server configuration"
    git remote add origin https://github.com/yourusername/btcpayserver.git
    git push -u origin main
  2. Create a new app on Klutch.sh

    1. Navigate to your Klutch.sh dashboard at klutch.sh/app
    2. Select your project
    3. Click Create App and connect your GitHub repository
    4. Klutch.sh will automatically detect your Dockerfile
  3. Configure environment variables

    1. In your app settings, add the required environment variables
    VariableValue
    BTCPAY_POSTGRESUser ID=btcpay;Password=yourpassword;Host=postgres-hostname;Port=5432;Database=btcpay;
    BTCPAY_BTCEXPLORERURLhttp://nbxplorer-hostname:32838/
    BTCPAY_NETWORKmainnet
    BTCPAY_BIND0.0.0.0
    BTCPAY_PORT49392
  4. Configure the internal port

    1. Set the internal port to 49392
    2. Select HTTP as the traffic type
  5. Set up persistent storage

    1. Add a persistent volume for BTCPay Server data
    Mount PathSize
    /datadir10 GB
  6. Deploy your application

    1. Click Deploy to build and launch BTCPay Server
    2. Monitor the build logs for any issues
    3. Once deployed, your app will be available at https://your-app.klutch.sh

Initial Setup

After deployment, configure your BTCPay Server:

  1. Create your admin account

    1. Visit https://your-app.klutch.sh
    2. Click Register to create your administrator account
    3. The first registered user becomes the server administrator
  2. Create a store

    1. After registration, click Create your first store
    2. Enter your store name and select your default currency
    3. Choose your preferred price source
  3. Set up your wallet

    1. Go to your store → WalletsBitcoin
    2. Choose your wallet setup method

    Options include:

    • Hot wallet: Keys stored on server (easiest, less secure)
    • Hardware wallet: Connect Ledger, Trezor, etc. via BTCPay Vault
    • Watch-only: Import xpub for cold storage

Wallet Configuration

Hot Wallet Setup

  1. Generate a new wallet

    1. Store → Wallets → Bitcoin → Setup → Create new wallet
    2. Select Hot wallet
    3. Backup your seed phrase immediately
  1. Generate xpub from your hardware wallet

    1. Use BTCPay Vault or your wallet software
    2. Export the xpub/zpub for the account
  2. Import to BTCPay Server

    1. Store → Wallets → Bitcoin → Setup → Connect hardware wallet
    2. Follow the BTCPay Vault instructions

Lightning Network (Optional)

To accept Lightning payments, connect a Lightning node:

LND Connection

type=lnd-rest;server=https://your-lnd-host:8080/;macaroonfilepath=/path/to/admin.macaroon;allowinsecure=true

Core Lightning Connection

type=clightning;server=unix://path/to/lightning-rpc

Creating Invoices

Use BTCPay Server to accept payments:

  1. Create a payment request

    1. Go to your store → InvoicesCreate Invoice
    2. Enter the amount and currency
    3. Add optional buyer email and order ID
  2. Share the payment page

    1. Send the invoice URL to your customer
    2. They’ll see the Bitcoin address and amount
    3. Payment is confirmed automatically

Point of Sale App

BTCPay Server includes a built-in POS:

  1. Create a POS app

    1. Store → Plugins → Point of Sale → Create
    2. Configure your products and prices
    3. Customize the appearance
  2. Access the POS

    1. Navigate to the POS URL
    2. Use on a tablet or phone for in-person payments

API Integration

BTCPay Server provides a comprehensive API:

Generate API Key

  1. Create an API key

    1. Account → Manage Account → API Keys
    2. Generate a new key with required permissions

Create Invoice via API

Terminal window
curl -X POST "https://your-btcpay.klutch.sh/api/v1/stores/{storeId}/invoices" \
-H "Authorization: token YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": "10.00",
"currency": "USD",
"metadata": {
"orderId": "ORDER-123"
}
}'

See the Greenfield API Documentation for complete reference.

Security Best Practices

Use Watch-Only Wallets

Keep private keys on hardware wallets, not on the server

Enable 2FA

Protect admin accounts with two-factor authentication

Regular Backups

Back up your database and wallet configuration

Keep Updated

Update BTCPay Server for security patches

Two-Factor Authentication

Enable 2FA for all accounts:

  1. Account → Manage Account → Two-Factor Authentication
  2. Set up using an authenticator app (TOTP)

Troubleshooting

Common issues and solutions:

IssueCauseSolution
Can’t connect to databaseWrong connection stringVerify PostgreSQL credentials and hostname
NBXplorer not syncingBitcoin node not accessibleCheck Bitcoin RPC connection
Invoice stuck pendingBlockchain not syncedWait for NBXplorer to sync
Lightning not availableNo Lightning node connectedConfigure BTCPAY_BTCLIGHTNING
502 errorsPort misconfigurationVerify internal port is set to 49392

Checking Sync Status

Monitor NBXplorer sync status through BTCPay Server:

  1. Server Settings → Maintenance
  2. Check “Sync Status” for each chain

Viewing Logs

Monitor logs through the Klutch.sh dashboard:

  1. Navigate to your app
  2. View deployment and runtime logs

Backup and Recovery

What to Back Up

ComponentLocationPriority
PostgreSQL databaseYour database serverCritical
BTCPay data directory/datadirCritical
Wallet configurationIn databaseCritical
NBXplorer data/datadirImportant

Database Backup

Terminal window
pg_dump -Fc btcpay > btcpay_backup.dump

Restore

Terminal window
pg_restore -d btcpay btcpay_backup.dump

Additional Resources