Electrs - tulliolo/mobybolt GitHub Wiki
Electrs is an efficient re-implementation of Electrum Server in Rust, inspired by ElectrumX, Electrum Personal Server and bitcoincore-indexd.
â To follow this section, log in to your node as admin user via Secure Shell (SSH) and access the project's home:
$ cd apps/mobybolt
- Bitcoin Knots or Bitcoin Core
- ~ 130GB of free storage for the database
â Electrs is a replacement for Fulcrum, these two services cannot be run at the same time (due to the same standard ports used). If you already have Fulcrum installed, please uninstall it before proceeding.
Bitcoin with hardware wallets
The best way to safely keep your bitcoin (meaning the best combination of security and usability) is to use a hardware wallet (like BitBox, Coldcard, Ledger, or Trezor) in combination with your own Bitcoin node. This gives you security, privacy and eliminates the need to trust a third party to verify transactions.
Bitcoin Knots/Core on the MobyBolt itself is not meant to hold funds.
One possibility to use Bitcoin Core with your Bitcoin wallets is to use an Electrum server as middleware. It imports data from Bitcoin Knots/Core and provides it to software wallets supporting the Electrum protocol. Desktop wallets like Sparrow, the BitBoxApp, Electrum, or Specter Desktop that support hardware wallets can then be used with your own sovereign Bitcoin node.
Create the electrs directory:
$ mkdir electrs
Edit the .env file and append the following content to the end:
$ nano .env
# electrs
ELECTRS_VERSION=0.10.6
ELECTRS_ADDRESS=172.16.21.5
ELECTRS_GID=1101
ELECTRS_UID=1101
đĄ In this file:
- we define the
ELECTRS_VERSION(check the latest available version here); - we define a static address for the container;
- we define the
uid(user id) andgid(group id) of the electrs user.
Create the Dockerfile and populate it with the following content:
$ nano electrs/Dockerfile
# base image
FROM debian:stable-slim AS base
# install dependencies
RUN set -eux && \
apt update && \
apt install -y \
cargo \
clang \
cmake \
curl \
git \
gpg && \
rm -rf /var/lib/apt/lists/*
# builder image
FROM base AS builder
ARG ELECTRS_VERSION
ENV ELECTRS_URL="https://github.com/romanz/electrs.git" \
ELECTRS_SIG_URL="https://romanzey.de/pgp.txt"
# clone repository
RUN set -eux && \
git clone --branch "v$ELECTRS_VERSION" $ELECTRS_URL
WORKDIR electrs
# build electrs
RUN set -eux && \
# import signatures
curl $ELECTRS_SIG_URL | gpg --import && \
# verify signatures
git verify-tag "v$ELECTRS_VERSION" && \
# build
cargo build --locked --release && \
# install
install -m 0755 -o root -g root -t /usr/local/bin ./target/release/electrs
# result image
FROM debian:stable-slim
COPY --from=builder /usr/local/ /usr/local/
# default guid for electrs user
ARG ELECTRS_GID=1101
ARG ELECTRS_UID=1101
ARG BITCOIN_GID=1100
RUN set -xe && \
# create electrs user
addgroup --gid $ELECTRS_GID electrs && \
adduser --disabled-password --comment "" --gid $ELECTRS_GID --uid $ELECTRS_UID electrs && \
# create bitcoin group and add electrs user to bitcoin group
addgroup --gid $BITCOIN_GID bitcoin && \
adduser electrs bitcoin && \
# setup dirs and permissions
mkdir -p /home/electrs/db/ && \
chmod 0700 /home/electrs/db/ && \
chown -R electrs:electrs /home/electrs/db/
# setup entrypoint
COPY --chmod=0755 docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
# switch user
USER electrs
đĄ In this file:
- we define a builder image (
builder) to buid electrs from github sources, verifying version tag signatures; - we define a result image:
- copying binaries from builder image;
- configuring the
electrsuser and the directories to which he will have access; - adding the
electrsuser to thebitcoingroup for RPC cookie authentication; - setting the
entrypoint(the script to run when the container starts).
Create the entrypoint file and populate it with the following content:
$ nano electrs/docker-entrypoint.sh
#!/bin/bash
set -eo pipefail
function die_func() {
echo "INFO: got SIGTERM... exiting"
exit 1
}
trap die_func TERM
CMD=$@
CONF_FILE=/home/electrs/electrs.conf
if [[ $# -eq 0 ]]; then
# missing parameters, run electrs
CMD="/usr/local/bin/electrs --conf $CONF_FILE --skip-default-conf-files"
fi
exec $CMD
đĄ In this file:
- we define the configuration file;
- we run electrs.
Create the electrs configuration file and populate it with the following content:
$ nano electrs/electrs.conf
# MobyBolt: electrs configuration
# /home/electrs/electrs.conf
# Bitcoin Core settings
network = "bitcoin"
daemon_dir = "/data/bitcoin"
daemon_rpc_addr = "bitcoin:8332"
daemon_p2p_addr = "bitcoin:8333"
# Electrs settings
electrum_rpc_addr = "0.0.0.0:50001"
db_dir = "/home/electrs/db"
server_banner = "Welcome to electrs (Electrum Rust Server) running on a MobyBolt node!"
skip_block_download_wait = true
# Logging
log_filters = "INFO"
Create the Docker Compose file and populate it with the following content:
$ nano electrs/docker-compose.yml
services:
electrumserver:
build:
context: .
args:
ELECTRS_VERSION: ${ELECTRS_VERSION}
ELECTRS_GID: ${ELECTRS_GID}
ELECTRS_UID: ${ELECTRS_UID}
container_name: ${COMPOSE_PROJECT_NAME}_electrs
depends_on:
bitcoin:
condition: service_healthy
expose:
- "50001:50001"
image: ${COMPOSE_PROJECT_NAME}/electrs:${ELECTRS_VERSION}
networks:
default:
ipv4_address: ${ELECTRS_ADDRESS}
restart: unless-stopped
stop_grace_period: 3m
volumes:
- electrs-data:/home/electrs/db/
- bitcoin-data:/data/bitcoin/:ro
- ./electrs.conf:/home/electrs/electrs.conf:ro
volumes:
electrs-data:
đĄ In this file:
- we
buildthe Dockerfile and create an image namedmobybolt/electrs:<version>; - we define the
restartpolicy of the container in case of failures; - we declare the bitcoin service as a dependency (Electrs will not run if bitcoin is not active);
- we provide the container:
- with the previously defined configuration (bind mount);
- with the bitcoin volume data, from which it will reach the RPC authentication cookie;
- with a volume named
mobybolt_electrs-datato store persistent data; - with the
ELECTRS_ADDRESSstatic address.
Edit the main Docker Compose file and link the electrs docker compose file in the include section:
$ nano docker-compose.yml
The file should look like this:
include:
- ...
- electrs/docker-compose.ymlRun the following command and check the output:
$ docker compose config --quiet && printf "OK\n" || printf "ERROR\n"
> OK
đĄ If the output is not OK, check the error reported... Maybe some wrong indentation in the yaml files?
Let's build the electrs image by typing:
$ docker compose build electrumserver
Check for a new image called mobybolt/electrs:<version>:
$ docker images | grep electrs
> mobybolt/electrs 0.10.6 5389bd930062 37 seconds ago 102MB
Run the following command and check the output:
$ docker run --rm --network mobybolt_default -v mobybolt_bitcoin-data:/data/bitcoin/:ro -v ./electrs/electrs.conf:/home/electrs/electrs.conf:ro mobybolt/electrs:0.10.6
> Starting electrs 0.10.6 on x86_64 linux with Config { network: Bitcoin, db_path: "/home/electrs/db/bitcoin", db_log_dir: None, daemon_dir: "/data/bitcoin", daemon_auth: CookieFile("/data/bitcoin/.cookie"), daemon_rpc_addr: 172.16.21.4:8332, daemon_p2p_addr: 172.16.21.4:8333, electrum_rpc_addr: 0.0.0.0:50001, monitoring_addr: 127.0.0.1:4224, wait_duration: 10s, jsonrpc_timeout: 15s, index_batch_size: 10, index_lookup_limit: None, reindex_last_blocks: 0, auto_reindex: true, ignore_mempool: false, sync_once: false, skip_block_download_wait: true, disable_electrum_rpc: false, server_banner: "Welcome to electrs (Electrum Rust Server) running on a MobyBolt node!", signet_magic: f9beb4d9 }
> [2024-10-04T08:55:46.391Z INFO electrs::metrics::metrics_impl] serving Prometheus metrics on 127.0.0.1:4224
> [2024-10-04T08:55:46.391Z INFO electrs::server] serving Electrum RPC on 0.0.0.0:50001
> [2024-10-04T08:55:46.543Z INFO electrs::db] "/home/electrs/db/bitcoin": 0 SST files, 0 GB, 0 Grows
> [2024-10-04T08:55:46.596Z INFO electrs::index] indexing 2000 blocks: [1..2000]
> [2024-10-04T08:55:46.800Z INFO electrs::chain] chain updated: tip=00000000dfd5d65c9d8561b4b8f60a63018fe3933ecb131fb37f905f87da951a, height=2000
> ...
Press CTRL-C to exit.
Run the following command and check the output:
$ docker compose up -d electrumserver
> [+] Running 2/2
> â Volume "mobybolt_electrs-data" Created
> â Container mobybolt_electrs Started
Check the container logs:
$ docker logs mobybolt_electrs
> mobybolt/electrs:0.10.6
> Starting electrs 0.10.6 on x86_64 linux with Config { network: Bitcoin, db_path: "/home/electrs/db/bitcoin", db_log_dir: None, daemon_dir: "/data/bitcoin", daemon_auth: CookieFile("/data/bitcoin/.cookie"), daemon_rpc_addr: 172.16.21.4:8332, daemon_p2p_addr: 172.16.21.4:8333, electrum_rpc_addr: 0.0.0.0:50001, monitoring_addr: 127.0.0.1:4224, wait_duration: 10s, jsonrpc_timeout: 15s, index_batch_size: 10, index_lookup_limit: None, reindex_last_blocks: 0, auto_reindex: true, ignore_mempool: false, sync_once: false, skip_block_download_wait: true, disable_electrum_rpc: false, server_banner: "Welcome to electrs (Electrum Rust Server) running on a MobyBolt node!", signet_magic: f9beb4d9, args: [] }
> [2024-09-27T09:01:14.688Z INFO electrs::metrics::metrics_impl] serving Prometheus metrics on 127.0.0.1:4224
> [2024-09-27T09:01:14.688Z INFO electrs::server] serving Electrum RPC on 0.0.0.0:50001
> [2024-09-27T09:01:14.808Z INFO electrs::db] "/home/electrs/db/bitcoin": 0 SST files, 0 GB, 0 Grows
> [2024-09-27T09:01:14.916Z INFO electrs::index] indexing 2000 blocks: [1..2000]
> [2024-09-27T09:01:15.282Z INFO electrs::chain] chain updated: tip=00000000dfd5d65c9d8561b4b8f60a63018fe3933ecb131fb37f905f87da951a, height=2000
> ...
Check the container status:
$ docker ps | grep electrs
> fbbd387b08d7 mobybolt/electrs:0.10.6 "docker-entrypoint.sh" 48 minutes ago Up 48 minutes 0/tcp mobybolt_electrs
âšī¸ If not already present, docker will also create the mobybolt_electrs-data volume. You can check for it with the command:
$ docker volume ls | grep electrs
> local mobybolt_electrs-data
Electrs must first fully index the blockchain and compact its database before you can connect to it with your wallets. This can take up to ~1.5 - 4 days or more, depending on the hardware. Only proceed with the Blockchain explorer: BTC RPC Explorer and Desktop Wallet Section once Electrs is ready.
Electrs will now index the whole Bitcoin blockchain so that it can provide all necessary information to wallets. With this, the wallets you use no longer need to connect to any third-party server to communicate with the Bitcoin peer-to-peer network.
â DO NOT REBOOT OR STOP THE SERVICE DURING THE DB CREATION PROCESS. YOU MAY CORRUPT THE FILES - in case that happens, start the sync from scratch by deleting the mobybolt_electrs-data volume, follow the next steps:
- Remove Electrs container:
$ docker compose down electrumserver > [+] Running 2/1 > â Container mobybolt_electrs Removed - Remove Electrs volume:
$ docker volume rm mobybolt_electrs-data > mobybolt_electrs-data - Follow the run section again.
To enable nginx reverse proxy to add SSL/TLS encryption to the Electrs communication, follow the next steps:
-
create the electrumserver-reverse-proxy configuration file with the following contents:
$ nano nginx/config/streams-enabled/electrumserver-reverse-proxy.confupstream electrumserver { server 172.16.21.5:50001; } server { listen 50002 ssl; proxy_pass electrumserver; }
-
test nginx configuration:
$ docker exec mobybolt_nginx nginx -t > nginx: the configuration file /etc/nginx/nginx.conf syntax is ok > nginx: configuration file /etc/nginx/nginx.conf test is successful -
edit the nginx docker-compose file adding a
portssection betweenimageandrestart; the file should look like below:$ nano nginx/docker-compose.ymlimage: ${COMPOSE_PROJECT_NAME}/nginx:${NGINX_VERSION} ports: - "50002:50002" # electrs restart: unless-stopped
đĄ This configuration will allow the Electrs ssl/tls port in the docker-managed firewall.
â ī¸ Be very careful to respect the indentation. Yaml is very sensitive to this!â ī¸ -
test the docker compose file:
$ docker compose config --quiet && printf "OK\n" || printf "ERROR\n" > OK -
recreate the nginx container:
$ docker compose down nginx && docker compose up -d nginx > [+] Running 2/1 > â Container mobybolt_nginx Removed 0.8s > ! Network mobybolt_default Resource is still in use 0.0s > [+] Running 1/1 > â Container mobybolt_nginx Started -
check the nginx container status (it should be
healthy, if not repeat the command):$ docker ps | grep nginx > bc38795edbb3 mobybolt/nginx:mainline "/docker-entrypoint.âĻ" 2 hours ago Up 5 minutes (healthy) 0.0.0.0:4000->4000/tcp, :::4000->4000/tcp, 80/tcp, 0.0.0.0:50002->50002/tcp, :::50002->50002/tcp mobybolt_nginx
-
Edit the tor configuration file, adding the following content at the end:
$ nano tor/torrc## Hidden Service Electum Server HiddenServiceDir /var/lib/tor/hidden_service_electrumserver/ HiddenServiceVersion 3 HiddenServicePoWDefensesEnabled 1 HiddenServicePort 50001 172.16.21.5:50001 -
Check the tor configuration file:
$ docker exec mobybolt_tor tor -f /etc/tor/torrc --verify-config > ... > Configuration was valid -
Restart tor:
$ docker compose restart tor > [+] Restarting 1/1 > â Container mobybolt_tor Started -
check the tor container status (it should be
healthy, if not repeat the command):$ docker ps | grep tor > bfc225986e0d mobybolt/tor:0.4.8.12 "docker-entrypoint.sh" 3 hours ago Up About a minute (healthy) 9050-9051/tcp -
get your onion address:
$ docker exec mobybolt_tor cat /var/lib/tor/hidden_service_electrumserver/hostname > abcdefg..............xyz.onion
Check the Electrs release page for a new version and change the ELECTRS_VERSION value in the .env file.
Then, redo the steps described in:
If everything is ok, you can clear the old image and build cache, like in the following example:
$ docker images | grep electrs
> mobybolt/electrs 0.10.6 03c38d632c76 3 minutes ago 345MB
> mobybolt/electrs 0.10.5 3613ae3d3613 14 minutes ago 322MB
$ docker image rm mobybolt/electrs:0.10.5
> Untagged: mobybolt/electrs:0.10.5
> Deleted: sha256:3613ae3d36137e9e4dd38e93d40edd21b8e4aa17df5527e934aed2013087537a
$ docker buildx prune
> WARNING! This will remove all dangling build cache. Are you sure you want to continue? [y/N] y
> ID RECLAIMABLE SIZE LAST ACCESSED
> pbzeixdrvu87hv3rajkrfprr8 true 398B 24 minutes ago
> xdufppotcvx2kegu5gc3zscg6* true 621.8MB 17 minutes ago
> ...
> Total: 1.853GB
Follow the next steps to uninstall electrs.
-
Remove the electrumserver-reverse-proxy configuration file:
$ rm nginx/config/streams-enabled/electrumserver-reverse-proxy.conf -
Edit the nginx docker-compose file and remove the line
- "50002:50002" # electrsin theportssection -
Test the docker-compose file:
$ docker compose config --quiet && printf "OK\n" || printf "ERROR\n" > OK -
Recreate the nginx container:
$ docker compose down nginx && docker compose up -d nginx > [+] Running 2/1 > â Container mobybolt_nginx Removed 0.8s > ! Network mobybolt_default Resource is still in use 0.0s > [+] Running 1/1 > â Container mobybolt_nginx Started -
Check the nginx container status (it should be
healthy, if not repeat the command):$ docker ps | grep nginx > bc38795edbb3 mobybolt/nginx:mainline "/docker-entrypoint.âĻ" 2 hours ago Up 5 minutes (healthy) 0.0.0.0:4000->4000/tcp, :::4000->4000/tcp, 80/tcp, 0.0.0.0:50002->50002/tcp, :::50002->50002/tcp mobybolt_nginx
-
Edit the tor configuration file (
nano tor/torrc) and remove all the Electrs lines added above -
Check the tor configuration file:
$ docker exec mobybolt_tor tor -f /etc/tor/torrc --verify-config > ... > Configuration was valid -
Restart tor:
$ docker compose restart tor > [+] Restarting 1/1 > â Container mobybolt_tor Started -
Check the tor container status (it should be
healthy, if not repeat the command):$ docker ps | grep tor > bfc225986e0d mobybolt/tor:0.4.8.12 "docker-entrypoint.sh" 3 hours ago Up About a minute (healthy) 9050-9051/tcp
$ docker compose down electrumserver
> [+] Running 2/1
> â Container mobybolt_electrs Removed
> ...
-
Edit the main docker-compose file (
nano docker-compose.yaml) and remove the Electrs line added above -
Test the docker-compose file:
$ docker compose config --quiet && printf "OK\n" || printf "ERROR\n" > OK
$ docker image rm $(docker images | grep electrs | awk '{print $3}')
> Untagged: mobybolt/electrs:0.10.6
> Deleted: sha256:13afebf08e29c6b9a526a6e54ab1f93e745b25080add4e37af8f08bdf6cfbcc6
$ docker buildx prune
> WARNING! This will remove all dangling build cache. Are you sure you want to continue? [y/N] y
> ID RECLAIMABLE SIZE LAST ACCESSED
> 7r8ccrpq0g0e03deu2dh53ob6* true 9.69MB 19 minutes ago
> ndrhcdo756vejnx17qm775t08* true 1.212kB 24 minutes ago
> ...
$ docker volume rm mobybolt_electrs-data
> mobybolt_electrs-data
$ rm -rf electrs