3 horizontal lines, burger
3 horizontal lines, burger
3 horizontal lines, burger
3 horizontal lines, burger

3 horizontal lines, burger
Remove all
LOADING ...

Content



    How to deploy a BTCPay Server on a VPS by hand

    Clock
    05.03.2026
    /
    Clock
    12.04.2026
    /
    Clock
    17 minutes
    An eye
    933
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0

    Why do you even need it? - casual introduction

    Let's imagine for a moment that you have a website. Although, perhaps some people don't even need to imagine it. And you want to sell your services or products, and to do so, you need to somehow enable payments on the site. After a little googling and some research on generative networks, you'll likely encounter the following situation: it's complicated.
    It's complicated, especially for my region and my "comrades" from Belarus and Russia. Well, as always :)
    You're probably familiar with payment aggregators like PayPal, Stripe, and Square. I think they are excellent services for small website owners, as well as for young and inexperienced webmasters like me. They can be described as "set it up and forget it." Unfortunately, they're out of the question right away, as they simply don't work in our region. Let's move on.
    There are also similar services that are capable of accepting payments and are simply tailored to local webmasters. For example, in Belarus, there's a monopoly called bePaid. In Russia, these are YooMoney, QIWI, SBP, SberPay, and, of course, WebMoney. But there are a couple of nuances worth considering:
    1. Not all of them are capable of accepting payments from all over the world. For example, I'm only confident in bePaid, as they've clearly stated this on their website.
    2. Integration is only possible if you're a businessmen, not an individual.
    There are many more nuances, and I'd like to describe them in more detail, but that's not what this article is about. As you might have guessed from the title, it's about crypto payments and how to implement them by deploying a BTCPay server first.
    The advantages of this payment acceptance method are as follows:
    1. Independence from both the political situation and the banking system.
    2. No commissions. So, depending on how you implement crypto payments on your website, whether you pay a commission will depend on whether you'll need to pay one.
    However, this method also has its fair share of disadvantages:
    1. Complexity of implementation. You can make it simpler and use various aggregators and gateways, but then the first advantage disappears, and the second, too.
    2. Complexity of use. Yes, not everyone can pay with crypto, and that shouldn't come as a surprise.
    3. In some countries, it's illegal. Well, if we're talking about Belarus, then it's a no-brainer.
    4. Withdrawals are a problem. There aren't many services that allow you to withdraw cryptocurrency into fiat currency, see the previous point.
    5. A bad reputation due to all sorts of dumpers, speculators, investors, crypto bros, crypto prophets, and, of course, ordinary scammers.
    Honestly, there are too many downsides to consider adding crypto payments to my website. But in my situation, this is probably the only option, as it really only requires technical skills and the desire to implement it. And independence from banks and politics sounds tempting. Therefore, this article will focus on implementing such payments on the website.
    So, how exactly do I implement this? Specifically, how do I plan to implement this on the website? Well, firstly, not on this website, but on a separate VPS. Secondly, I'll do it using BTCPay Server, which I'll deploy on a separate VPS. They will communicate using a REST API.
    BTCPay Server is an open-source, self-hosted cryptocurrency payment processor that works with Bitcoin and altcoins.
    VPS (Virtual Private Server) is a virtual machine rental service that simulates the operation of a physical server and, thanks to virtualization, shares resources with other users while providing full control (root access), its own operating system, and independent resources.
    REST API (Representational State Transfer API) is an architectural style for client-server interaction based on the HTTP protocol using standard methods: GET, POST, PUT, DELETE

    What is the general process for deploying such a server and what are the requirements for it?

    First, you need to buy or rent a server. This can be either a cheap VPS or a dedicated server. The main requirement for a server is the amount of dedicated memory, as even a lightweight Bitcoin node requires at least 10-15 gigabytes.
    There are such concepts as a lightweight node and a full blockchain node. The idea is that a full node stores the entire history of user transactions and requires approximately 700-800 gigabytes of memory. A fairly large disk space is required to store this amount, and therefore very expensive. Therefore, there are so-called lightweight nodes, which don't store the entire blockchain, but only the headers of individual blocks. Depending on the BTCPay Server settings, their size can vary from 10-15 gigabytes.
    I would also recommend using at least 2 cores and 4 gigabytes of RAM. This is to prevent the server from crashing every 5 minutes due to overload. Even with these requirements, it's quite expensive for a home-made gadget, and even then, synchronizing a lightweight kernel can take a week :(
    Afterward, you'll need to install and configure the appropriate software for block verification. Specifically, you'll need to install the following packages on the server:
    1. Bitcoin Core. Essentially, this is your wallet for storing, depositing, and transferring funds.
    2. .Net SDK. A necessary dependency for compiling and running packages such as NBXplorer and BTCPay Server.
    3. NBXplorer. A minimalistic UTXO tracker for HD wallets, for tracking current balances and creating new payment addresses.
    4. BTCPay Server. For accepting payments.
    5. PostgreSQL database. For both NBXplorer and BTCPay Server.
    6. Nginx web server. For communication between the website owner and the server hosting BTCPay Server.
    UTXO (Unspent Transaction Output) is a fundamental unit in cryptocurrency, representing the remainder of the cryptocurrency after a transaction. This is change, which is also recorded in the blockchain.
    PostgreSQL is a powerful, reliable, and free open-source object-relational database management system (RDBMS).
    Nginx is a high-performance open-source web server and reverse proxy.
    In theory, it's all quite simple: you just need to install the necessary packages and configure them to suit your needs. Then, create two separate databases for NBXplorer and BTCPay. The next step is to deploy the Nginx web server for external access, that is, from my website. And that's it.
    Of course, I still need to learn how to work with this server through its API and connect it to the website. Specifically, I need to create the appropriate widgets on the website and host them. But this is much easier than the previous steps. But enough of the ramblings and unnecessary talk, let's get down to setting up and preparing the server.

    Setting up and preparing the server

    It all starts with renting a server. As mentioned above, the only requirement for such a server is disk space. For our needs, we need at least 20 GB. It doesn't matter which provider you purchase the server from; this guide is provider-agnostic.
    I'll be using Debian 12 as the operating system for my server. The official BTCPay Server documentation uses Ubuntu 20.04, but the differences between Debian and Ubuntu aren't that significant. In theory, such a server could be run on Windows, but we're not going into that here.
    Beforehand, it's best to simplify your access to the server and switch to SSH key authentication. I'll skip this process in this article, but you can learn more about it in detail later.
    The next step is to create a privileged user on the remote server. Under no circumstances should we do anything as the root user. Again, you can read more about this process in the article on creating a privileged user on Linux machines.
    After creating the privileged user, install the following basic packages:
    gitFor cloning repos
    wgetFor downloading files/archives from internet via terminal
    vimText editor in the terminal
    tarUniversal archives manager
    postgresql и postgresql-contribData base
    nginxWeb server for to enable access from an outside
    certbot и python3-certbot-nginxSpecific script to generate TTL/SSL certificates
    Имя пакетаОписание пакета
    !!! Some packages may already be installed on the system, I can't know which ones the provider installed by default, so I'll list everything that is necessary.
    This is done through one command:
    sudo apt-get update & sudo apt-get upgrade sudo apt-get install git wget vim tar
    Once the system/server has been configured (i.e., the necessary packages have been installed, the required user has been created, and access to the server via SSH has been simplified and secured), you can begin installing and configuring the components required for BTCPay Server.
    I perform all subsequent actions on the server under the unprivileged user btcpay-user.

    Installation of the Bitcoin Core 28.1

    Let's start by installing what's called Bitcoin Core. This is what will calculate all transactions worldwide and what our place in it is. You can install the core archive here. There you can also see all available versions and choose the one that suits you. I'll choose the latest version, which at the time of writing is 28.1.
    We'll do it this way: download the corresponding archive, unzip it, and install some of the binaries in the applications and executables directory. You can download it as a script or simply copy it. Here's the contents of the script:
    BITCOIN_VERSION="28.1" BITCOIN_URL="https://bitcoin.org/bin/bitcoin-core-28.1/bitcoin-28.1-x86_64-linux-gnu.tar.gz" BITCOIN_SHA256="07f77afd326639145b9ba9562912b2ad2ccec47b8a305bd075b4f4cb127b7ed7" # install bitcoin binaries cd /tmp wget -O bitcoin.tar.gz "$BITCOIN_URL" echo "$BITCOIN_SHA256 bitcoin.tar.gz" | sha256sum -c - && \ mkdir bin && \ sudo tar -xzvf bitcoin.tar.gz -C /usr/local/bin --strip-components=2 "bitcoin-$BITCOIN_VERSION/bin/bitcoin-cli" "bitcoin-$BITCOIN_VERSION/bin/bitcoind" rm bitcoin.tar.gz
    We'll install bitcoind and bitcoin-cli. Bitcoin will need to be run as a background service and accessed periodically using bitcoin-cli. We'll also need to configure our kernel first. To do this, create a bitcoin.conf file and place it in /etc/bitcoin. Create a directory if necessary.
    In bitcoin.conf, add the following settings:
    server=1 # need RPC for btcpay. rpcbind=127.0.0.1 # loopback is default for 0.18.0 but no harm making sure. whitelist=127.0.0.1 # for nbxplorer. rpcallowip=127.0.0.1/32 # loopback is default but again no harm. zmqpubrawblock=tcp://127.0.0.1:28332 # needed for lightning. zmqpubrawtx=tcp://127.0.0.1:28333 # needed for lightning. prune=5000 # Recommended if not enough disk space for full 600+GB blockchain.
    You also need to change the access rights to this file:
    sudo chmod 644 /etc/bitcoin/bitcoin.conf
    The Bitcoin core configuration is almost complete; all that's left is to create the corresponding service and enable it so it always restarts when the server reboots. I'll call the service file bitcoind.service, and the contents of this service are as follows:
    # It is not recommended to modify this file in-place, because it will # be overwritten during package upgrades. If you want to add further # options or overwrite existing ones then use # $ systemctl edit bitcoind.service # See "man systemd.service" for details. # Note that almost all daemon options could be specified in # /etc/bitcoin/bitcoin.conf, but keep in mind those explicitly # specified as arguments in ExecStart= will override those in the # config file. [Unit] Description=Bitcoin daemon Documentation=https://github.com/bitcoin/bitcoin/blob/master/doc/init.md # https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ After=network-online.target Wants=network-online.target [Service] ExecStart=/usr/local/bin/bitcoind -pid=/run/bitcoind/bitcoind.pid \ -conf=/etc/bitcoin/bitcoin.conf \ -datadir=/var/lib/bitcoind \ -startupnotify='systemd-notify --ready' \ -shutdownnotify='systemd-notify --stopping' # Make sure the config directory is readable by the service user ExecStartPre=!/bin/chgrp btcpay-user /etc/bitcoin # Process management #################### Type=notify NotifyAccess=all PIDFile=/run/bitcoind/bitcoind.pid Restart=on-failure TimeoutStartSec=infinity TimeoutStopSec=600 # Directory creation and permissions #################################### # Run as bitcoin:bitcoin User=btcpay-user Group=btcpay-user # /run/bitcoind RuntimeDirectory=bitcoind RuntimeDirectoryMode=0710 # /etc/bitcoin ConfigurationDirectory=bitcoin ConfigurationDirectoryMode=0710 # /var/lib/bitcoind StateDirectory=bitcoind StateDirectoryMode=0710 # Hardening measures #################### # Provide a private /tmp and /var/tmp. PrivateTmp=true # Mount /usr, /boot/ and /etc read-only for the process. ProtectSystem=full # Deny access to /home, /root and /run/user ProtectHome=true # Disallow the process and all of its children to gain # new privileges through execve(). NoNewPrivileges=true # Use a new /dev namespace only populated with API pseudo devices # such as /dev/null, /dev/zero and /dev/random. PrivateDevices=true # Deny the creation of writable and executable memory mappings. MemoryDenyWriteExecute=true # Restrict ABIs to help ensure MemoryDenyWriteExecute is enforced SystemCallArchitectures=native [Install] WantedBy=multi-user.target
    The original service code can be found here. The only changes I made were the user name, group, and service path. Once the service file has been successfully created, move it to the services directory and activate it:
    sudo cp bitcoind.service /etc/systemd/system/ sudo systemctl enable bitcoind.service sudo systemctl start bitcoind.service sudo systemctl status bitcoind.service
    Everything should work, but if not, check the logs. Terminal output should help.
    I can only tell you about the most common error code 203. This code means that the service was found and started, but the path to the executable (in this case, bitcoind) was not found. Be sure to double-check all paths.
    After starting the daemon with the configuration we specified in bitcoin.conf, it will download the entire current blockchain. More precisely, in our case, with prune=5000 , it will only download the block headers to save space on the server—this is called node initialization.
    To check the synchronization status, you can use the bitcoin-cli command.
    bitcoin-cli -rpccookiefile=/var/lib/bitcoind/.cookie getblockchaininfo
    This will take some time. If the node reaches 0.99 or 1.00, it's synchronized. Since this is a background service, we can continue working on the server. For example, we can download the required version of the developer tools (or SDK) to the server.

    Installing the .Net SDK 8

    We need to install the latest available version, which is 8. Both NBXplorer and BTCPay Server depend on these SDKs, and they currently require version 8, so we'll install that.
    SDK (Software Development Kit) is a set of pre-built, platform-specific tools, libraries, documentation, and source code examples created specifically to help developers develop applications for specific platforms, operating systems, and programming languages.
    The only problem is that Debian's official package repositories don't contain this package. Therefore, we first need to add the Microsoft repository.
    wget https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb sudo dpkg -i packages-microsoft-prod.deb rm packages-microsoft-prod.deb
    First, we download the deb package from Microsoft servers, then add a new package mirror. Then we delete it; there's no need to save it. Now we should have the dotnet-sdk-8.0 package available.
    But before using packages from other package repositories, you should always update your package manager, like this:
    sudo apt-get update sudo apt-get install dotnet-sdk-8.0
    After installation, let's check the installed SDK version. The command should return the currently installed SDK version number:
    dotnet --version
    Now that we have the necessary components, we can begin compiling and running NBXplorer.

    Installing NBXplorer

    This application allows you to track all transactions sent to this server. This means that payments from your website are sent to BTCPay Server, which we'll deploy later. But first, let's install and compile this application.
    cd ~ git clone https://github.com/dgarage/NBXplorer cd NBXplorer ./build.sh
    Once the application has been installed, you need to add a new database for NBXplorer.
    Let's enter the PostgreSQL database environment:
    sudo -u postgres psql
    And let's create a new database, this is done as follows:
    CREATE DATABASE nbxplorer TEMPLATE 'template0' LC_CTYPE 'C' LC_COLLATE 'C' ENCODING 'UTF8'; CREATE USER nbxplorer WITH ENCRYPTED PASSWORD 'urpassword'; GRANT ALL PRIVILEGES ON DATABASE nbxplorer TO nbxplorer; GRANT ALL ON SCHEMA public TO nbxplorer; ALTER SCHEMA public OWNER TO nbxplorer;
    The database has been created, so you can create the nbxplorer.conf configuration file and copy it to the /etc/nbxplorer/ directory. The contents of nbxplorer.conf:
    ### Database ### postgres=User ID=nbxplorer;Password=urpassword;Application Name=nbxplorer;MaxPoolSize=20;Host=localhost;Port=5432;Database=nbxplorer;
    And to copy the file into /etc/nbxplorer/:
    sudo mkdir /etc/nbxplorer sudo cp nbxplorer.config /etc/nbxplorer sudo chmod 644 /etc/nbxplorer/nbxplorer.config
    We've now linked the database we created and the NBXplorer application. This link must run in the background to continuously monitor for new transactions and add them to the database. To do this, we'll create a service. The contents of the service file, nbxplorer.service, are:
    [Unit] Description=NBXplorer daemon Requires=bitcoind.service After=bitcoind.service [Service] WorkingDirectory=/home/btcpay-user/NBXplorer ExecStart=/home/btcpay-user/NBXplorer/run.sh --conf=/etc/nbxplorer/nbxplorer.conf User=btcpay-user Group=btcpay-user Type=simple PIDFile=/run/nbxplorer/nbxplorer.pid Restart=on-failure [Install] WantedBy=multi-user.target
    Simply replace btcpay-user with your username everywhere, and this service will be ready to use on your server.
    Let's finally create this service:
    sudo cp nbxplorer.service /etc/systemd/system sudo systemctl enable --now nbxplorer
    You may have received error code 134. In that case, check if the bitcoind daemon is running. It's a direct dependency, and NBXplorer can't run without it.
    This is how NBXplorer is launched on the server. Not too difficult, right? The last daemon to launch is BTCPay Server.

    Installing BTCPay Server

    We'll start by downloading the source code from GitHub and compiling the application itself.
    cd ~ git clone https://github.com/btcpayserver/btcpayserver cd btcpayserver ./build.sh
    Next, everything is as in NBXplorer: create a separate PostgreSQL database, add the configuration file to the system, create and run the daemon/service in the background.
    Enter the PostgreSQL interactive shell:
    sudo -u postgres psql
    Let's create a database:
    CREATE DATABASE btcpay TEMPLATE 'template0' LC_CTYPE 'C' LC_COLLATE 'C' ENCODING 'UTF8'; CREATE USER btcpay WITH ENCRYPTED PASSWORD 'urpassword'; GRANT ALL PRIVILEGES ON DATABASE btcpay TO btcpay; GRANT ALL ON SCHEMA public TO btcpay; ALTER SCHEMA public OWNER TO btcpay;
    Create a configuration file, btcpay.conf, and paste the following into it, replacing it with your own data:
    network=mainnet chains=btc port=23000 bind=127.0.0.1 ### Database ### postgres=User ID=btcpay;Password=yourpassword;Application Name=btcpayserver;Host=localhost;Port=5432;Database=btcpay; ### NBXplorer ### # Указываем путь к куки-файлу явно, если он не находится автоматически btc.explorer.url=http://127.0.0.1:24444/ btc.explorer.cookiefile=/home/btcpay-user/.nbxplorer/Main/.cookie # Твоя строка для базы данных эксплорера explorer.postgres=User ID=nbxplorer;Password=yourpassword;Application Name=nbxplorer;MaxPoolSize=20;Host=localhost;Port=5432;Database=nbxplorer;
    Place the created configuration file btcpay.conf in /etc/btcpay:
    sudo mkdir /etc/btcpay sudo cp btcpay.config /etc/btcpay sudo chmod 644 /etc/btcpay/btcpay.conf
    Now you need to run BTCPay in the background as a service. Create a file called btcpay.service and add the following to it, after changing the paths to the executable files and scripts, as well as the username and group from btcpay-user to your username:
    [Unit] Description=BTCPay Server Requires=nbxplorer.service After=nbxplorer.service [Service] WorkingDirectory=/home/btcpay-user/btcpayserver Environment=BTCPAY_BTCEXTERNALRTL="server=https://mainnet.demo.btcpayserver.org/rtl;cookiefile=/var/lib/rtl/.cookie" ExecStart=/home/btcpay-user/btcpayserver/run.sh --conf=/etc/btcpay/btcpay.conf User=btcpay-user Group=btcpay-user Type=simple PIDFile=/run/btcpayserver/btcpayserver.pid Restart=on-failure [Install] WantedBy=multi-user.target
    Copy this file to the directory of all services - /etc/systemd/system. Activate it:
    sudo cp btcpay.service /etc/systemd/system/ sudo systemctl enable btcpay sudo systemctl start btcpay
    To check if the service has started and activated correctly, you can run this command:
    sudo systemctl status btcpay
    To check the log of this command, you can run the following command:
    sudo journalctl -xe --unit btcpay --follow
    At this point, we've completed the bare minimum. We have everything we need to run a small node in a peer-to-peer blockchain system for accepting cryptocurrency payments. But now, this server needs to be exposed to the world, and this is done via the Nginx web server.

    Installing and Configuring the Nginx Web Server

    An important requirement for this server is that it operates exclusively via the HTTPS protocol, otherwise it may simply not start.

    Creating a TTL/SSL Certificate

    To do this, you need to issue an SSL certificate, not just once, but repeatedly. This is done using the excellent CLI tool certbot. Full instructions on how to use this command are available here, but we'll simply do this:
    HTTPS (Hyper Text Transfer Protocol Secured) is a secure version of the HTTP protocol that encrypts data between the user's browser and the website using TLS/SSL.
    SSL (Secure Sockets Layer) is a security protocol that provides an encrypted connection between the user's web browser and the website's server
    sudo certbot --nginx -d your.domain.name
    Don't forget to enter your domain name. In my case, I'll use btc-node.of.by.
    I purchased it with the understanding that if this payment method becomes popular and the node itself becomes a great intermediary for other sites, I'll support it and, secondly, turn it into a full 600GB node.
    You might have difficulties with this step, because when you purchase a new domain, you'll also need to link it to your machine, i.e., your VPS. This is done using DNS A and AAAA records. The first record should contain the domain and IPv4 of your VPS, and the second record should also contain the domain and IPv6 of the same VPS.
    It will take time for the DNS records to take effect, anywhere from an hour to 24 hours. So, you'll have to wait.
    To verify that they've taken effect, use any WhoIs tool where you can see the IP address of your VPS server. If you see this, you've successfully connected your domain to your VPS, and now when you type your domain name in your browser's address bar, you're actually accessing your server on port 80—the HTTP protocol.
    Why buy a domain when you can use an IP address directly? The problem is that the BTCPay server only operates over HTTPS, not HTTP. To switch to this protocol, you need to issue a certificate, which can only be issued for domain names, not addresses.

    Launch the Nginx web server.

    To do this, create the btcpay-server.conf file in /etc/nginx/sites-available and add the following configuration, replacing btc-node.of.by with your server name:
    # If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the # scheme used to connect to this server map $http_x_forwarded_proto $proxy_x_forwarded_proto { default $http_x_forwarded_proto; '' $scheme; } # If we receive X-Forwarded-Port, pass it through; otherwise, pass along the # server port the client connected to map $http_x_forwarded_port $proxy_x_forwarded_port { default $http_x_forwarded_port; '' $server_port; } # If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any # Connection header that may have been passed to this server map $http_upgrade $proxy_connection { default upgrade; '' close; } # Apply fix for very long server names server_names_hash_bucket_size 128; # Prevent Nginx Information Disclosure server_tokens off; # Default dhparam # Set appropriate X-Forwarded-Ssl header map $scheme $proxy_x_forwarded_ssl { default off; https on; } gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; log_format vhost '$host $remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; access_log off; # HTTP 1.1 support proxy_http_version 1.1; proxy_buffering off; proxy_set_header Host $http_host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $proxy_connection; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl; proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; client_header_buffer_size 500k; large_client_header_buffers 4 500k; # Mitigate httpoxy attack (see README for details) proxy_set_header Proxy ""; server { server_name btc-node.of.by; listen 80; access_log /var/log/nginx/access.log vhost; return 301 https://$host$request_uri; } server { client_max_body_size 100M; server_name btc-node.of.by; listen 443 ssl http2 ; access_log /var/log/nginx/access.log vhost; ssl_protocols TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; ssl_prefer_server_ciphers on; ssl_session_timeout 5m; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_certificate /etc/letsencrypt/live/btc-node.of.by/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/btc-node.of.by/privkey.pem; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/btc-node.of.by/fullchain.pem; add_header Strict-Transport-Security "max-age=31536000" always; #include /etc/nginx/vhost.d/default; # Here is the main BTCPay Server application location / { proxy_pass http://127.0.0.1:23000; } }
    In this configuration, we redirect all HTTP requests to HTTPS. We also connect our web server to BTCPay Server via the previously opened port 23000, which we explicitly specified in the btcpay.conf settings.
    Now let's create a link to this configuration in /etc/nginx/sites-enabled, delete the default configuration, and restart the web server:
    sudo cd /etc/nginx/sites-enabled sudo ln -s ../sites-available/btcpay-server.conf btcpay-server.conf sudo rm -f ./default sudo systemctl restart nginx
    You only need to delete the default configuration in the sites-enabled section. Leaving this configuration enabled will cause the server to start it first, which will interfere with our BTCPay server.
    If everything is done correctly, you should see the server login page.

    Additional Enhancements to Your BTCPay Server

    This is the minimum setup required for the BTCPay server to function. However, it can be enhanced with additional features, such as Tor and the Lightning Network (this will be discussed in a separate article).
    The former enhances the security of transmitted messages when making purchases in the open and unreliable internet environment.
    The latter accelerates cryptocurrency transactions and increases throughput, i.e., the number of simultaneous transactions processed to billions per second, compared to 10 billion for the original Bitcoin.

    Security using Tor

    Let's start with security. Tor not only enhances the security of transmitted messages, but also helps with NAT traversal.
    NAT traversal is a set of methods that allows devices on private networks behind a NAT router to establish direct connections over the internet, overcoming the limitations of address translation.
    To do this, let's install Tor itself:
    sudo apt-get install tor
    Let's edit the /etc/tor/torrc file. We'll need to uncomment the following lines for everything to work:
    1. ControlPort 9051
    2. CookieAuthentication 1
    3. CookieAuthFileGroupReadable 1 (Sometimes it might not be there, just add it next to it)
    Everything's ready, now let's just add our user to the debian-tor group and restart the corresponding processes:
    sudo usermod -a -G debian-tor btcpay-user sudo systemctl restart tor sudo systemctl restart bitcoind
    To check if our bitcoind is working on an onion address, you can use the command:
    bitcoin-cli getnetworkinfo
    As a result, you will receive a response like this, where the current onion address is marked in red:

    Summing Up

    I've finished describing the process of deploying a BTCPay server on a separate VPS. It was a long process, I think you'll agree. In this article, we were able to assemble all the necessary components ourselves and combine them into a single, working structure. Starting with the essential bitcoincore, we continued building on top of it with nbxplorer and the btcpay server.
    Finally, we opened access to our server using the Nginx web server. And we completed the picture by installing Tor.
    I wanted to describe the Lightning Network installation process in this article, but it's already become too long. That will be covered in a separate article. In a separate article, I'll also cover the practical use of such a server for your own website. I'll show you how to add your own wallet and how to add payment buttons to your website.

    Do not forget to share, like and leave a comment :)

    Comments

    (0)

    captcha
    Send
    LOADING ...
    It's empty now. Be the first (o゚v゚)ノ

    Other

    Similar articles


    How to deploy a Django project on Beget (Either via hosting or VPS)

    Clock
    12.05.2024
    /
    Clock
    11.03.2026
    An eye
    6197
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0
    This is an article on how to deploy django site on beget. I show two methods (deployment either on hosting or VPS). Plus, how to set up and connect a …

    How to deploy a Django website on reg.ru

    Clock
    16.03.2025
    /
    Clock
    15.04.2026
    An eye
    2343
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    1
    How to deploy a django website on a reg.ru with database configuration, plus setup for a HTTPS redirects and configuration of a nginx, gunicorn and dns

    How to deploy a Django website on the timeweb

    Clock
    24.07.2025
    /
    Clock
    15.04.2026
    An eye
    4521
    Hearts
    2
    Connected dots
    1
    Connected dots
    0
    Connected dots
    2
    How to deploy a django website on a timeweb with database configuration, plus setup for a HTTPS redirects and configuration of a nginx, gunicorn and dns