# Raspberry Pi 3 Deployment

This document guides you step by step on how to run BTCPay Server on a Raspberry Pi 3. See here the Raspberry Pi 4 instructions

The overall process is as follows:

  1. Purchase and assemble hardware
  2. Install Raspbian Lite operating system, configure networking
  3. Install BTCPayServer-Docker

BTCPayServer can be successfully installed on the following hardware:

  1. Raspberry Pi 3 Model B+
Raspberry Pi 3 Model B+
  1. 64GB SanDisk Ultra Fit USB Flash Drive
    64 GB SanDisk Ultra Fit USB Flash Drive

  2. 16 GB SanDisk Ultra MicroSDXC Card
    16 GB SanDisk Ultra MicroSDXC Card

Other requirements are as follows:

  1. Internet connection
  2. Static IP
  3. Domain Name
  4. Ability to open ports 80, 443, 9735 on your router

Once you have the hardware and other requirements, you're ready to begin!

# Here are the setup instructions:

Step 1 - Configure your domain name.

Login to your domain registrar and create an A record pointing your domain to the external IP address of your Pi's internet connection:

  • IP Address: Visit ipchicken.com (opens new window) or search the web for "what's my ip" from any device on the network
  • Domain / Hostname: btcpay.YourDomain.com. Name the subdomain where BTCPayServer will run (e.g. btcpay).
  • TTL: Shortest, or Default

It can take several hours for DNS changes to propagate worldwide, so you should do this step first.

Step 2 - Assemble your Pi.

Step 3 - Get on a computer with a microSD card slot, or a USB port if you have a USB-microSD adapter (opens new window). Download and extract Raspbian Buster Lite (opens new window) to this machine.

Step 4 - On this same computer, download and install Etcher (opens new window). Etcher is used to 'flash' Operating System disk images to SD cards and USB drives. ⚠️ 'Flashing' a drive wipes it completely; be careful.

In this case, we will be using Etcher to flash your microSD card with the downloaded Raspbian Lite OS. Plug in the microSD card, and run Etcher. Select the unzipped Raspbian OS, select your microSD card, and confirm to flash it.

Step 5 - On this same computer, ⚠️ before you plug the SD card into your Pi, create an empty file named ssh in the boot partition of the SD card.

  • On Mac and Linux, use touch ssh in the card's root directory via Terminal
  • On Windows, use type nul > ssh in the card's root directory via cmd

Step 6 - Insert your microSD card and flash drive into the Pi; connect the network cable and power supply.

Step 7 - From another computer, use an SSH client (ssh on Mac and Linux, PuTTY (opens new window) on Windows) to connect to your Raspberry Pi:

  • hostname: raspberrypi.local
  • username: pi
  • password: raspberry

So: ssh pi@raspberrypi.local.

If raspberrypi.local doesn't work, you will have to either look up the Pi's IP address on your router, or run ifconfig on the Pi directly for the eth0 inet address.

Step 8 - ⚠️ IMPORTANT! - Change your password:


Step 9 - Give your Pi a static IP address and a DHCP reservation on your local network, via your router. Optionally, setup WiFi. There are a few different ways to do this and you will find a ton of articles online.

To get your router's IP:

  • On Linux: ip route | grep default
  • On Mac: netstat -nr | grep default
  • On Windows: ipconfig | findstr /i "Gateway"

Step 10 - Log into your router and forward ports 80, 443, and 9735 to your Pi's local IP address. Every router is different and you should be able to find instructions for your router by searching the web for "Port Forwarding + {your router make and model}".

Step 11 - Install fail2ban and git.

fail2ban bans IPs that attempt to connect to your server and show malicious signs. git allows you to clone and manage repositories on github.com.

So, open a new terminal window and type the following command:

sudo apt update && sudo apt install -y fail2ban git

⚠️ Note for beginners: Run all commands in these instructions one line at a time!

Step 12 - Install ufw (Uncomplicated Firewall) and allow only specific ports. UFW is a user-friendly frontend for managing iptables firewall rules and its main goal is to make managing iptables easier, or as the name says: uncomplicated.

Install UFW:

sudo apt install ufw

This command allows SSH connections from internal networks only:

sudo ufw allow from to any port 22 proto tcp
sudo ufw allow from to any port 22 proto tcp
sudo ufw allow from to any port 22 proto tcp
sudo ufw allow from to any port 22 proto tcp
sudo ufw allow from fc00::/7 to any port 22 proto tcp
sudo ufw allow from fe80::/10 to any port 22 proto tcp
sudo ufw allow from ff00::/8 to any port 22 proto tcp

These ports need to be accessible from anywhere (The default subnet is 'any' unless you specify one):

sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 9735

Verify your configuration:

sudo ufw status

Enable your firewall:

sudo ufw enable

Step 13 - Reformat flash drive, to be configured as swap space.

⚠️ Warning: Using any SD card for swap space kills it quickly!. Instead, use a flash drive, as the instructions discuss.

The command sudo fdisk -l shows a list of the connected storage devices. Assuming you only have one flash drive connected, it will be called /dev/sda. Double-check that /dev/sda exists, and that its storage capacity matches your flash memory.

Delete existing flash drive partition:

sudo fdisk /dev/sda
# Press 'd'
# Press 'w'

Create new primary flash drive partition:

sudo fdisk /dev/sda
# Press 'n'
# Press 'p'
# Press '1'
# Press 'enter'
# Press 'enter'
# Press 'w'

Format partition as ext4:

sudo mkfs.ext4 /dev/sda1
# Create folder for mount.
sudo mkdir /mnt/usb
# Look up UUID of flash drive.
UUID="$(sudo blkid -s UUID -o value /dev/sda1)"
# Add mount to fstab.
echo "UUID=$UUID /mnt/usb ext4 defaults,nofail 0" | sudo tee -a /etc/fstab

Test changes to fstab file:

sudo mount -a

Verify that drive is mounted:

df -h

/dev/sda1 should appear as mounted on /mnt/usb.

Create symlink to flash drive for Docker:

sudo mkdir /mnt/usb/docker
sudo ln -s /mnt/usb/docker /var/lib/docker

Step 14 - Finally, move Swapfile to USB and increase its size.

Edit its configuration file:

sudo nano /etc/dphys-swapfile

Change the CONF_SWAPFILE line to: CONF_SWAPFILE=/mnt/usb/swapfile

Change the CONF_SWAPSIZE line to: CONF_SWAPSIZE=2048

Stop and restart the swapfile service:

sudo /etc/init.d/dphys-swapfile stop
sudo /etc/init.d/dphys-swapfile start

Step 15 - Install BTCPayServer!

Login as root:

sudo su -

Create a folder for BTCPayServer:

mkdir btcpayserver
cd btcpayserver

Clone the BTCPayServer-Docker repository into the folder:

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

Set your environment variables. Make sure the BTCPAY_HOST value uses your own domain & subdomain. As usual, run each command separately:

export BTCPAY_HOST="btcpay.YourDomain.com"
export NBITCOIN_NETWORK="mainnet"
export BTCPAYGEN_CRYPTO1="btc"
export BTCPAYGEN_ADDITIONAL_FRAGMENTS="opt-save-storage-xs;opt-save-memory"

Adding the opt-save-storage-xs fragment will tell Bitcoin Core to keep around 3 months of blocks, or 25 GB of disk space. See other pruning levels here. Pruning is necessary for FastSync to work.

If you want to use multiple hostnames, add them via the optional BTCPAY_ADDITIONAL_HOSTS variable:

export BTCPAY_ADDITIONAL_HOSTS="raspberrypi.local,btcpay.local"

In case you want to restrict access to your local network only, please note that you need to use a .local domain.

Finally, run the BTCPayServer setup script:

. ./btcpay-setup.sh -i

Step 16 - Go to https://btcpay.YourDomain.com and confirm that your site is up and your nodes are syncing.

Syncing is very slow on a Pi, since each block and transaction needs to go through validation. You can skip this, at your own risk, by using FastSync. Otherwise, simply leave the node running to sync to 100%; this may take weeks.

Setup Complete!

# Fast Sync

BTCPayServer's complete FastSync documentation is available here (opens new window).

Please read very carefully to understand what FastSync is and why it's important to verify the UTXO set yourself.

Step 17 - OPTIONAL - FastSync:

cd /root/btcpayserver/btcpayserver-docker

cd contrib
cd FastSync

FastSync currently takes about 30 minutes on a high-speed internet connection. After FastSync finishes, run the following command to restart BTCPayServer:

cd ../..

# Total Verification

By using FastSync, you are exposing yourself to attacks if a malicious UTXO Set snapshot (opens new window) is sent to you.

If you have another trusted node somewhere else, you can check the validity of the UTXO Set gathered by FastSync by following these instructions (opens new window).

# That's it! Enjoy your BTCPi! 🎉

If you don't have the time or patience to build your own BTCPi, there are a few merchants who can build one for you: