Install Bitcoin Core on Linux

Debian, Ubuntu and Raspberry Pi OS (64-bit). About twenty minutes of work, then the initial sync runs on its own. Versions change, so every step reads the number from a VERSION variable.

Practice first

The node lab simulates a node in your browser. You can run the status and log commands from this page there before touching a real machine.

1. Check the machine

You need a 64-bit OS, wget, gpg and git.

prepare
$ uname -m
x86_64
$ sudo apt update
$ sudo apt install -y wget gnupg git

Expected: x86_64 (PC, mini PC, most VPS) or aarch64 (Raspberry Pi 4/5, ARM VPS). Anything else, such as armv7l, means a 32-bit OS: reinstall a 64-bit one. Disk size and RAM: see hardware and VPS.

2. Download

Open bitcoincore.org/en/download, read the latest version number, and put it in VERSION in place of X.Y. Digits and dots only, no leading v.

download
$ VERSION=X.Y
$ ARCH=$(uname -m)
$ mkdir -p ~/btc-install && cd ~/btc-install
$ wget https://bitcoincore.org/bin/bitcoin-core-$VERSION/bitcoin-$VERSION-$ARCH-linux-gnu.tar.gz
$ wget https://bitcoincore.org/bin/bitcoin-core-$VERSION/SHA256SUMS
$ wget https://bitcoincore.org/bin/bitcoin-core-$VERSION/SHA256SUMS.asc

Run these in the same terminal session, because the variables disappear when you close it. A 404 Not Found means VERSION still says X.Y or has a typo.

3. Verify

The checksum shows the file is intact. The signatures show that Bitcoin Core builders published that checksum list. Do both, because a modified binary can do anything with your machine.

verify
$ sha256sum --ignore-missing --check SHA256SUMS
bitcoin-X.Y-x86_64-linux-gnu.tar.gz: OK

$ git clone https://github.com/bitcoin-core/guix.sigs
$ gpg --import guix.sigs/builder-keys/*.gpg
$ gpg --verify SHA256SUMS.asc SHA256SUMS
gpg: Good signature from "..."
gpg: Good signature from "..."
...

Expected: OK for your file, and one Good signature line for each signer whose key you imported. Importing a key does not make you trust it. Pick a few builders you are willing to trust, check their key fingerprints (printed as Primary key fingerprint) against a source other than that repository, such as the builder's own website or GitHub profile, and accept the download only if several of them signed it. The warning This key is not certified with a trusted signature is normal. bitcoincore.org/en/download describes the same procedure. If you see FAILED or BAD signature, delete the files, download again, and ask on the contact page if it repeats. Do not install.

Optional: contrib/verify-binaries/verify.py in the Bitcoin Core source repository runs these checks for you and can require a minimum number of trusted signatures.

4. Install and create a user

Only bitcoind and bitcoin-cli are needed. The node runs as its own unprivileged user, so a bug in it cannot touch your files.

install
$ tar xzf bitcoin-$VERSION-$ARCH-linux-gnu.tar.gz
$ sudo install -m 0755 -o root -g root -t /usr/local/bin bitcoin-$VERSION/bin/bitcoind bitcoin-$VERSION/bin/bitcoin-cli
$ sudo useradd --system --user-group --shell /usr/sbin/nologin bitcoin
$ bitcoind --version
Bitcoin Core daemon version vX.Y.Z

5. Write bitcoin.conf

Create the config folder with the right owner, then the file. The service below keeps config in /etc/bitcoin and chain data in /var/lib/bitcoind, the layout used by the official unit file.

config folder
$ sudo install -d -m 0710 -o root -g bitcoin /etc/bitcoin
$ sudo install -m 0640 -o root -g bitcoin /dev/null /etc/bitcoin/bitcoin.conf
$ sudo nano /etc/bitcoin/bitcoin.conf
/etc/bitcoin/bitcoin.conf
rpccookieperms=group

# Optional: keep only the most recent blocks (MiB, minimum 550).
# Uses much less disk. You cannot undo it without re-downloading the chain.
#prune=5000

# Optional: RAM for the UTXO cache in MiB. More makes the first sync faster.
# Leave it unset unless you have RAM to spare.
#dbcache=2048

That is all you need. Listening for peers is on by default, and RPC only answers on localhost by default. rpccookieperms=group lets you, once in the bitcoin group, run bitcoin-cli without sudo. Every option is explained in the bitcoin.conf reference; whether to prune is covered in pruned vs full.

If the chain will live on a separate drive, mount it at /var/lib/bitcoind before the first start.

6. Add the systemd service

This is the official contrib/init/bitcoind.service with the binary path set to /usr/local/bin. It starts the node at boot, restarts it after a crash, and gives it up to ten minutes to flush data on shutdown.

/etc/systemd/system/bitcoind.service
[Unit]
Description=Bitcoin daemon
Documentation=https://github.com/bitcoin/bitcoin/blob/master/doc/init.md
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'
ExecStartPre=!/bin/chgrp bitcoin /etc/bitcoin

Type=notify
NotifyAccess=all
PIDFile=/run/bitcoind/bitcoind.pid
Restart=on-failure
TimeoutStartSec=infinity
TimeoutStopSec=600

User=bitcoin
RuntimeDirectory=bitcoind
RuntimeDirectoryMode=0710
ConfigurationDirectory=bitcoin
ConfigurationDirectoryMode=0710
StateDirectory=bitcoind
StateDirectoryMode=0710

PrivateTmp=true
ProtectSystem=full
ProtectHome=true
NoNewPrivileges=true
PrivateDevices=true
MemoryDenyWriteExecute=true
SystemCallArchitectures=native

[Install]
WantedBy=multi-user.target

Save it with sudo nano /etc/systemd/system/bitcoind.service. Compare it with the current official file if your release ships a different one.

7. Start it

The alias makes plain bitcoin-cli commands, as written on this site, find the data folder. Log out and back in afterwards so the group change applies.

start
$ sudo usermod -aG bitcoin $USER
$ echo "alias bitcoin-cli='bitcoin-cli -datadir=/var/lib/bitcoind'" >> ~/.bashrc
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now bitcoind
$ systemctl status bitcoind --no-pager
Active: active (running) since ...

Expected: active (running). On a first start it can sit in activating for a minute while it loads. If it says failed, run journalctl -u bitcoind -n 50 --no-pager. The usual causes are a typo in bitcoin.conf, a wrong file mode on /etc/bitcoin, or a full disk.

8. Check that it is syncing

Log out and back in, then:

first-run checks
$ bitcoin-cli getblockchaininfo
{
  "chain": "main",
  "blocks": ...,
  "headers": ...,
  "verificationprogress": 0.0...,
  "initialblockdownload": true,
  ...
}
$ bitcoin-cli getconnectioncount
10
$ journalctl -u bitcoind -n 20 --no-pager
$ df -h /var/lib/bitcoind
  • chain is main, initialblockdownload is true and blocks rises over time. If blocks stays at 0 and headers too, you have no peers.
  • Connections: about 10 outbound once it settles. 0 after several minutes means no outbound internet or DNS. Test with ping -c 3 bitcoin.org.
  • Log lines like UpdateTip: new best=... mean blocks are being validated. Under systemd bitcoind logs to the journal and also to /var/lib/bitcoind/debug.log, which only root and the bitcoin user can read.
  • Disk: free space must not shrink toward zero. Stop the node if it does and read disk space & pruned.

The sync is done when initialblockdownload is false and verificationprogress is close to 1. More checks and what they mean: commands. If progress seems stuck: sync stuck.

Upgrade

Read the release notes on bitcoincore.org first. Then repeat steps 2 to 4 with the new VERSION (verification included) and swap the binaries while the node is stopped. Your config and chain data stay where they are.

upgrade
$ sudo systemctl stop bitcoind
$ sudo install -m 0755 -o root -g root -t /usr/local/bin bitcoin-$VERSION/bin/bitcoind bitcoin-$VERSION/bin/bitcoin-cli
$ sudo systemctl start bitcoind
$ bitcoin-cli getnetworkinfo | grep subversion
  "subversion": "/Satoshi:X.Y.Z/",

Going back to an older release can fail on data the newer one has already converted, so keep the previous tarball and treat an upgrade as one-way.

Do not expose RPC

Port 8332 must stay on localhost. Do not forward it, and do not set rpcbind or rpcallowip to open it. Background: security basics.

Common problems

Which version should I install?

The latest release listed on bitcoincore.org/en/download. Put its number in the VERSION variable. Always verify the download before you run it.

Can I run Bitcoin Core on a Raspberry Pi?

Yes, on a 64-bit OS. uname -m must print aarch64, and the commands on this page pick the right tarball for you. Keep the chain on an SSD or NVMe drive, not an SD card.

How long does the first sync take?

From several hours to a few days, mostly decided by disk speed, then CPU and RAM. Slow USB drives and SD cards take much longer. The sync resumes if you stop the node.

bitcoin-cli says Could not connect to the server

bitcoind is not running or is still starting. Run systemctl status bitcoind. If it is active, check that you are talking to the right datadir (see the alias in step 7).

bitcoin-cli says Could not locate RPC credentials

bitcoin-cli cannot read the RPC cookie. Check that bitcoin.conf has rpccookieperms=group, that you are in the bitcoin group (run id after logging in again), and that the alias in step 7 points at /var/lib/bitcoind.

Do I need to open a port?

No. The node syncs with outbound connections only. Forward TCP 8333 only if you also want to accept inbound peers.

Node running?

These read-only commands tell you whether it is healthy.

Open commands