feat: docker image for ElectrumX, configured by environment
Replaces lukechilds/electrumx, unmaintained for years. ElectrumX 2.0.0 from the
upstream tag, rocksdb, built in a venv so only the runtime library follows into
the final image.
Every variable is ElectrumX's own — the entrypoint only fills defaults and
rejects the one mistake that is expensive to diagnose: NET spelled the way
bitcoind spells it ("test" for "testnet"), which otherwise fails deep inside a
coin-class lookup. DB_ENGINE defaults to rocksdb because 2.0 made the variable
required, and peer discovery is off because this image is for private indexers.
Verified on testnet2 against the sibling bitcoind image: coin BitcoinRegtest,
db height matching daemon height at 101, Electrum protocol answering on 50001.
That run also found what the README now states — 2.x refuses to serve unless
the daemon runs with both txindex=1 and txospenderindex=1.
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
# Intro
|
||||
|
||||
> Русская версия: [README.ru-RU.md](README.ru-RU.md)
|
||||
|
||||
[ElectrumX](https://github.com/spesmilo/electrumx) is a server for the Electrum protocol. It indexes the chain from a full node and answers the queries a light client cannot answer for itself: the history and the UTXOs of an arbitrary address, and transaction broadcast.
|
||||
|
||||
ElectrumX running in a docker container, configured by environment variables.
|
||||
|
||||
This repository covers the docker deployment only. ElectrumX itself is installed from a pinned upstream git tag.
|
||||
|
||||
# Usage
|
||||
|
||||
ElectrumX needs a `bitcoind` it can reach over RPC, on the same network, not
|
||||
pruned. `DAEMON_URL` is the only required variable; `NET` must name the same
|
||||
chain the daemon runs.
|
||||
|
||||
The container serves the Electrum protocol on **50001** (plaintext TCP) and, if
|
||||
`SERVICES` asks for it, on **50002** (TLS). There is no authentication of any
|
||||
kind, so keep both inside the docker network or on loopback. The **RPC** service
|
||||
on `localhost:8000` is administrative and never leaves the container — the
|
||||
health check is what uses it.
|
||||
|
||||
## docker-compose
|
||||
|
||||
```yaml
|
||||
services:
|
||||
electrumx:
|
||||
build:
|
||||
context: https://git.bitdeals.org/private/electrumx.git
|
||||
dockerfile: ./docker/Dockerfile
|
||||
image: registry.bitdeals.org/electrumx
|
||||
environment:
|
||||
- COIN=Bitcoin
|
||||
- NET=regtest
|
||||
- DAEMON_URL=http://CHANGE_ME:CHANGE_ME@bitcoind:18443
|
||||
- CACHE_MB=400
|
||||
ports:
|
||||
- 127.0.0.1:50001:50001 # no auth — loopback only
|
||||
volumes:
|
||||
- electrumxdata:/data
|
||||
|
||||
volumes:
|
||||
electrumxdata:
|
||||
```
|
||||
|
||||
## docker cli
|
||||
|
||||
```sh
|
||||
docker run -d \
|
||||
-e COIN=Bitcoin \
|
||||
-e NET=regtest \
|
||||
-e DAEMON_URL=http://CHANGE_ME:CHANGE_ME@bitcoind:18443 \
|
||||
-e CACHE_MB=400 \
|
||||
-p 127.0.0.1:50001:50001 \
|
||||
-v electrumxdata:/data \
|
||||
registry.bitdeals.org/electrumx
|
||||
```
|
||||
|
||||
Anything after the image name is passed on to `electrumx_server`.
|
||||
|
||||
## build and publish
|
||||
|
||||
```sh
|
||||
docker build . --file docker/Dockerfile --tag registry.bitdeals.org/electrumx
|
||||
docker push registry.bitdeals.org/electrumx
|
||||
```
|
||||
|
||||
A different ElectrumX release is a build argument — use a tag from
|
||||
[the upstream repository](https://github.com/spesmilo/electrumx/tags):
|
||||
|
||||
```sh
|
||||
docker build . --file docker/Dockerfile \
|
||||
--build-arg ELECTRUMX_VERSION=2.0.0 \
|
||||
--tag registry.bitdeals.org/electrumx:2.0.0
|
||||
```
|
||||
|
||||
# Parameters
|
||||
|
||||
Container images are configured using parameters passed at runtime. Every
|
||||
variable is ElectrumX's own, so
|
||||
[the upstream environment reference](https://electrumx-spesmilo.readthedocs.io/en/latest/environment.html)
|
||||
applies unchanged; the table lists the ones this image gives a default to.
|
||||
|
||||
|Parameter|Function|
|
||||
|:--------|:-------|
|
||||
|-p 127.0.0.1:50001|Electrum protocol over plaintext TCP. No authentication — see "Notes"|
|
||||
|-p 127.0.0.1:50002|Electrum protocol over TLS. Served only when `SERVICES` includes `ssl://`|
|
||||
|-v /data|Data directory: the index, and the self-signed certificate if one was generated. Losing it means indexing the chain again|
|
||||
|-e DAEMON_URL|**Required.** The daemon's RPC, e.g. `http://user:password@bitcoind:8332`. Several may be given, comma-separated|
|
||||
|-e COIN|Coin class. Default: `Bitcoin`|
|
||||
|-e NET|Network: `mainnet`, `testnet`, `testnet4`, `signet`, `regtest` or `mutinynet`. Must match the daemon's chain. Default: `mainnet`|
|
||||
|-e DB_ENGINE|Index storage. Default: `rocksdb`, the only engine whose libraries this image carries|
|
||||
|-e DB_DIRECTORY|Where the index lives. Default: `/data`|
|
||||
|-e SERVICES|What to serve, comma-separated. Default: `tcp://:50001,rpc://localhost:8000`. Keep an `rpc://` entry — the health check needs it|
|
||||
|-e SSL_CERTFILE, -e SSL_KEYFILE|TLS certificate and key. Default: generated as a self-signed pair in the data directory when `SERVICES` includes `ssl://`|
|
||||
|-e PEER_DISCOVERY|Whether to learn other public servers. Default: `off` — this image is meant for a private indexer|
|
||||
|-e PEER_ANNOUNCE|Whether to announce this server to the peer network. Default: `false`|
|
||||
|-e CACHE_MB|Indexing cache. Default: `1200` (ElectrumX's own). Lower it for a small chain, raise it to speed up an initial mainnet index|
|
||||
|
||||
# Notes
|
||||
|
||||
- **There is no authentication.** Anyone who reaches 50001 or 50002 can query
|
||||
any address and broadcast transactions. Publish to loopback, or not at all
|
||||
when the clients are containers on the same network.
|
||||
- **An index from another image is not readable.** This one runs rocksdb;
|
||||
`lukechilds/electrumx`, which it replaces in BitDeals, wrote leveldb. Point
|
||||
the container at an empty volume and let it index — for regtest and testnet
|
||||
this is quick, for mainnet it is a matter of days.
|
||||
- **The daemon needs `txindex=1` and `txospenderindex=1`.** ElectrumX 2.x checks
|
||||
`getindexinfo` before it serves anything and exits with a `RuntimeError`
|
||||
naming the missing index — one at a time, so fixing `txindex` earns you the
|
||||
same message about `txospenderindex`. With the sibling
|
||||
[bitcoind image](https://git.bitdeals.org/private/bitcoind) that is
|
||||
`BITCOIND_TXINDEX=1` and `BITCOIND_TXOSPENDERINDEX=1`; on an existing datadir
|
||||
turning them on means a reindex of the daemon.
|
||||
- **The daemon must not be pruned.** Indexing reads every block; a pruned node
|
||||
fails partway through with an error about a missing block rather than about
|
||||
the configuration.
|
||||
- **`NET` is ElectrumX's spelling, not bitcoind's.** The daemon calls the
|
||||
networks `main`, `test` and `regtest`; ElectrumX calls them `mainnet`,
|
||||
`testnet` and `regtest`. The entrypoint rejects an unknown value, because the
|
||||
pair is usually configured from one `.env` and `NET=test` would otherwise
|
||||
fail deep inside a coin lookup.
|
||||
- **The container turns healthy only once it is serving**, which is after it has
|
||||
caught up with the daemon. An initial mainnet index takes days and the
|
||||
container will be unhealthy for all of it — watch the logs instead; on regtest
|
||||
it is a matter of seconds.
|
||||
- **A self-signed certificate is generated only if `SERVICES` asks for TLS and
|
||||
no files are supplied.** Clients then have to trust it explicitly. That is the
|
||||
price of ElectrumX refusing to start when `ssl://` is requested without a
|
||||
certificate, which is a surprising way to learn you added a port.
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
# Общие сведения
|
||||
|
||||
> English version: [README.md](README.md)
|
||||
|
||||
[ElectrumX](https://github.com/spesmilo/electrumx) — сервер протокола Electrum. Он индексирует цепочку по данным полного узла и отвечает на запросы, которые лёгкий клиент не может обработать сам: история и UTXO произвольного адреса, а также публикация транзакций.
|
||||
|
||||
ElectrumX, работающий в docker-контейнере, настраивается переменными окружения.
|
||||
|
||||
Репозиторий описывает только развёртывание в docker. Сам ElectrumX устанавливается из зафиксированного тега upstream-репозитория.
|
||||
|
||||
# Использование
|
||||
|
||||
ElectrumX нужен `bitcoind`, доступный по RPC, в той же сети и без обрезки
|
||||
цепочки. `DAEMON_URL` — единственная обязательная переменная; `NET` должен
|
||||
называть ту же сеть, в которой работает демон.
|
||||
|
||||
Контейнер отдаёт протокол Electrum на порту **50001** (открытый TCP) и, если
|
||||
этого требует `SERVICES`, на порту **50002** (TLS). Никакой аутентификации нет,
|
||||
поэтому держите оба порта во внутренней сети docker или на loopback.
|
||||
Служебный **RPC** на `localhost:8000` наружу не выходит — им пользуется проверка
|
||||
состояния контейнера.
|
||||
|
||||
## docker-compose
|
||||
|
||||
```yaml
|
||||
services:
|
||||
electrumx:
|
||||
build:
|
||||
context: https://git.bitdeals.org/private/electrumx.git
|
||||
dockerfile: ./docker/Dockerfile
|
||||
image: registry.bitdeals.org/electrumx
|
||||
environment:
|
||||
- COIN=Bitcoin
|
||||
- NET=regtest
|
||||
- DAEMON_URL=http://CHANGE_ME:CHANGE_ME@bitcoind:18443
|
||||
- CACHE_MB=400
|
||||
ports:
|
||||
- 127.0.0.1:50001:50001 # без аутентификации — только loopback
|
||||
volumes:
|
||||
- electrumxdata:/data
|
||||
|
||||
volumes:
|
||||
electrumxdata:
|
||||
```
|
||||
|
||||
## docker cli
|
||||
|
||||
```sh
|
||||
docker run -d \
|
||||
-e COIN=Bitcoin \
|
||||
-e NET=regtest \
|
||||
-e DAEMON_URL=http://CHANGE_ME:CHANGE_ME@bitcoind:18443 \
|
||||
-e CACHE_MB=400 \
|
||||
-p 127.0.0.1:50001:50001 \
|
||||
-v electrumxdata:/data \
|
||||
registry.bitdeals.org/electrumx
|
||||
```
|
||||
|
||||
Всё, что указано после имени образа, передаётся `electrumx_server`.
|
||||
|
||||
## сборка и публикация
|
||||
|
||||
```sh
|
||||
docker build . --file docker/Dockerfile --tag registry.bitdeals.org/electrumx
|
||||
docker push registry.bitdeals.org/electrumx
|
||||
```
|
||||
|
||||
Другая версия ElectrumX задаётся аргументом сборки — берите тег из
|
||||
[upstream-репозитория](https://github.com/spesmilo/electrumx/tags):
|
||||
|
||||
```sh
|
||||
docker build . --file docker/Dockerfile \
|
||||
--build-arg ELECTRUMX_VERSION=2.0.0 \
|
||||
--tag registry.bitdeals.org/electrumx:2.0.0
|
||||
```
|
||||
|
||||
# Параметры
|
||||
|
||||
Образы контейнера настраиваются параметрами, передаваемыми при запуске. Все
|
||||
переменные — собственные переменные ElectrumX, поэтому
|
||||
[справочник upstream](https://electrumx-spesmilo.readthedocs.io/en/latest/environment.html)
|
||||
применим без изменений; в таблице перечислены те, которым этот образ задаёт
|
||||
значения по умолчанию.
|
||||
|
||||
|Параметр|Назначение|
|
||||
|:--------|:-------|
|
||||
|-p 127.0.0.1:50001|Протокол Electrum поверх открытого TCP. Аутентификации нет — см. «Замечания»|
|
||||
|-p 127.0.0.1:50002|Протокол Electrum поверх TLS. Отдаётся, только если `SERVICES` содержит `ssl://`|
|
||||
|-v /data|Каталог данных: индекс и самоподписанный сертификат, если он был создан. Его потеря означает повторную индексацию цепочки|
|
||||
|-e DAEMON_URL|**Обязательный.** RPC демона, например `http://user:password@bitcoind:8332`. Можно указать несколько через запятую|
|
||||
|-e COIN|Класс монеты. По умолчанию: `Bitcoin`|
|
||||
|-e NET|Сеть: `mainnet`, `testnet`, `testnet4`, `signet`, `regtest` или `mutinynet`. Должна совпадать с сетью демона. По умолчанию: `mainnet`|
|
||||
|-e DB_ENGINE|Хранилище индекса. По умолчанию: `rocksdb` — единственный движок, библиотеки которого есть в образе|
|
||||
|-e DB_DIRECTORY|Где лежит индекс. По умолчанию: `/data`|
|
||||
|-e SERVICES|Что обслуживать, через запятую. По умолчанию: `tcp://:50001,rpc://localhost:8000`. Оставьте запись `rpc://` — она нужна проверке состояния|
|
||||
|-e SSL_CERTFILE, -e SSL_KEYFILE|Сертификат и ключ TLS. По умолчанию: самоподписанная пара создаётся в каталоге данных, если `SERVICES` содержит `ssl://`|
|
||||
|-e PEER_DISCOVERY|Искать ли другие публичные серверы. По умолчанию: `off` — образ рассчитан на приватный индексатор|
|
||||
|-e PEER_ANNOUNCE|Объявлять ли себя в сети серверов. По умолчанию: `false`|
|
||||
|-e CACHE_MB|Кэш индексации. По умолчанию: `1200` (значение ElectrumX). Снижайте для небольшой цепочки, повышайте для ускорения первой индексации mainnet|
|
||||
|
||||
# Замечания
|
||||
|
||||
- **Аутентификации нет никакой.** Любой, кто дотянулся до 50001 или 50002, может
|
||||
запросить произвольный адрес и опубликовать транзакцию. Публикуйте на
|
||||
loopback, а если клиенты — контейнеры той же сети, не публикуйте вовсе.
|
||||
- **Индекс от другого образа не читается.** Здесь rocksdb, а
|
||||
`lukechilds/electrumx`, который этот образ заменяет в BitDeals, писал leveldb.
|
||||
Подключите пустой том и дайте проиндексировать заново: для regtest и testnet
|
||||
это быстро, для mainnet — несколько суток.
|
||||
- **Демону нужны `txindex=1` и `txospenderindex=1`.** ElectrumX 2.x перед
|
||||
началом работы запрашивает `getindexinfo` и завершается с `RuntimeError`,
|
||||
называя недостающий индекс — по одному за раз, так что после включения
|
||||
`txindex` вы получите то же сообщение про `txospenderindex`. В соседнем
|
||||
[образе bitcoind](https://git.bitdeals.org/private/bitcoind) это
|
||||
`BITCOIND_TXINDEX=1` и `BITCOIND_TXOSPENDERINDEX=1`; на существующем каталоге
|
||||
данных их включение означает переиндексацию демона.
|
||||
- **Демон не должен быть обрезанным.** Индексация читает каждый блок; узел с
|
||||
`-prune` приводит к отказу на середине с сообщением об отсутствующем блоке, а
|
||||
не о неверной настройке.
|
||||
- **`NET` пишется по-электрумовски, а не по-биткойновски.** Демон называет сети
|
||||
`main`, `test` и `regtest`, ElectrumX — `mainnet`, `testnet` и `regtest`.
|
||||
Точка входа отвергает неизвестное значение, потому что пара обычно
|
||||
настраивается из одного `.env`, и `NET=test` иначе упал бы глубоко внутри
|
||||
поиска класса монеты.
|
||||
- **Контейнер становится healthy только когда начинает обслуживать клиентов** —
|
||||
то есть после того, как догнал демона. Первая индексация mainnet занимает
|
||||
несколько суток, и всё это время контейнер будет unhealthy; смотрите логи. На
|
||||
regtest это секунды.
|
||||
- **Самоподписанный сертификат создаётся, только если `SERVICES` требует TLS, а
|
||||
файлы не заданы.** Клиентам придётся доверять ему явно. Это плата за то, что
|
||||
ElectrumX отказывается стартовать при запросе `ssl://` без сертификата — не
|
||||
лучший способ узнать, что вы добавили порт.
|
||||
@@ -0,0 +1,26 @@
|
||||
services:
|
||||
electrumx:
|
||||
build:
|
||||
# Repository root, not ./docker: the Dockerfile copies ./docker/run.sh
|
||||
# and ./docker/healthy_check.sh, and those paths are resolved against the
|
||||
# build context.
|
||||
context: .
|
||||
dockerfile: ./docker/Dockerfile
|
||||
image: registry.bitdeals.org/electrumx
|
||||
environment:
|
||||
- COIN=Bitcoin
|
||||
# ElectrumX spelling, not bitcoind's: the daemon calls this chain
|
||||
# "regtest" too, but "main"/"test" there are "mainnet"/"testnet" here.
|
||||
- NET=regtest
|
||||
# The daemon must run with txindex=1 and txospenderindex=1.
|
||||
- DAEMON_URL=http://CHANGE_ME:CHANGE_ME@bitcoind:18443
|
||||
- CACHE_MB=400
|
||||
ports:
|
||||
# No authentication of any kind — loopback only, or nothing at all when
|
||||
# the clients are containers on the same network.
|
||||
- 127.0.0.1:50001:50001
|
||||
volumes:
|
||||
- electrumxdata:/data
|
||||
|
||||
volumes:
|
||||
electrumxdata:
|
||||
@@ -0,0 +1,74 @@
|
||||
# A container for the ElectrumX server
|
||||
#
|
||||
# ElectrumX indexes a bitcoind and answers the Electrum protocol: address
|
||||
# history, UTXOs, transaction broadcast. BitDeals uses it for payment detection
|
||||
# (ДС) and for UTXO lookup and broadcast (ГС).
|
||||
#
|
||||
# Installed from the upstream git tag, pinned below. The venv is built in the
|
||||
# first stage with the rocksdb headers, and only the runtime library follows it
|
||||
# into the final image.
|
||||
|
||||
FROM python:3.14-trixie AS builder
|
||||
|
||||
ARG ELECTRUMX_VERSION=2.0.0
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -yq --no-install-suggests --no-install-recommends \
|
||||
build-essential git librocksdb-dev pkg-config \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN python -m venv venv \
|
||||
&& venv/bin/pip install --no-cache-dir \
|
||||
"e_x[rocksdb] @ git+https://github.com/spesmilo/electrumx.git@${ELECTRUMX_VERSION}"
|
||||
|
||||
|
||||
FROM python:3.14-slim-trixie
|
||||
|
||||
# Electrum protocol, plaintext TCP. SSL is served on 50002 when SERVICES asks
|
||||
# for it; the RPC (8000) stays on localhost and is what the health check uses.
|
||||
EXPOSE 50001/tcp
|
||||
EXPOSE 50002/tcp
|
||||
|
||||
ENV USER_UID=2000
|
||||
ENV USER_GID=2000
|
||||
ENV HOME=/home/electrumx
|
||||
# /data, not the home directory: this is the path the image this one replaces
|
||||
# (lukechilds/electrumx) used, so a compose file keeps its volume line. The
|
||||
# index itself has to be rebuilt anyway — see README, "Notes".
|
||||
ENV DB_DIRECTORY=/data
|
||||
|
||||
# librocksdb9.10 is the runtime half of librocksdb-dev above; openssl is only
|
||||
# for the self-signed certificate the entrypoint generates on demand.
|
||||
RUN apt-get update \
|
||||
&& apt-get install -yq --no-install-suggests --no-install-recommends \
|
||||
librocksdb9.10 openssl gosu \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY --from=builder /usr/src/app/venv /usr/src/app/venv
|
||||
COPY ./docker/run.sh /usr/local/bin/
|
||||
COPY ./docker/healthy_check.sh /usr/local/bin/
|
||||
|
||||
# Exec-form ENTRYPOINT/HEALTHCHECK targets: a clone on a filesystem that does
|
||||
# not carry the executable bit would otherwise build an unstartable image.
|
||||
RUN chmod +x /usr/local/bin/run.sh /usr/local/bin/healthy_check.sh
|
||||
|
||||
# electrumx_server and electrumx_rpc live in the venv; putting it on PATH keeps
|
||||
# both this file and the scripts free of the full path.
|
||||
ENV PATH=/usr/src/app/venv/bin:$PATH
|
||||
|
||||
# groupadd, not addgroup: the slim images dropped the adduser package.
|
||||
RUN groupadd --gid $USER_GID electrumx \
|
||||
&& useradd --uid $USER_UID --gid $USER_GID --skel /dev/null --create-home --home-dir $HOME electrumx
|
||||
|
||||
VOLUME ${DB_DIRECTORY}
|
||||
WORKDIR ${HOME}
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/run.sh"]
|
||||
|
||||
# The server starts serving only after it has caught up with the daemon, and on
|
||||
# mainnet the first index takes days. The start period covers a restart on an
|
||||
# existing index, not a first run — for that, watch the logs.
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=300s --retries=3 \
|
||||
CMD ["/usr/local/bin/healthy_check.sh"]
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Healthy = the server answers its own RPC. That happens once it has caught up
|
||||
# with the daemon and started serving, which is what callers care about: an
|
||||
# ElectrumX still building its index accepts no Electrum sessions at all.
|
||||
#
|
||||
# The RPC lives on localhost:8000 by default (SERVICES). Overriding SERVICES
|
||||
# without an rpc:// entry leaves nothing to ask — see README, "Notes".
|
||||
|
||||
set -eu
|
||||
|
||||
exec gosu electrumx electrumx_rpc getinfo > /dev/null
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
# ElectrumX reads its own configuration from the environment, so this script
|
||||
# only fills in defaults and checks the two mistakes that are expensive to
|
||||
# diagnose later. Every variable below is ElectrumX's own name, not ours —
|
||||
# anything documented upstream works here unchanged.
|
||||
|
||||
export COIN="${COIN:-Bitcoin}"
|
||||
export NET="${NET:-mainnet}"
|
||||
export DB_DIRECTORY="${DB_DIRECTORY:-/data}"
|
||||
# Required by ElectrumX 2.0 (it refuses to start without it). rocksdb is what
|
||||
# the image ships the libraries for.
|
||||
export DB_ENGINE="${DB_ENGINE:-rocksdb}"
|
||||
# Plaintext Electrum protocol plus the local RPC the health check talks to.
|
||||
# Add ssl://:50002 to serve TLS (see the certificate section below).
|
||||
export SERVICES="${SERVICES:-tcp://:50001,rpc://localhost:8000}"
|
||||
# Off by default: this image is meant for private indexers behind a known
|
||||
# daemon. A node that announces itself to the public server network is a
|
||||
# deliberate act — set PEER_DISCOVERY=on and PEER_ANNOUNCE=true for it.
|
||||
export PEER_DISCOVERY="${PEER_DISCOVERY:-off}"
|
||||
export PEER_ANNOUNCE="${PEER_ANNOUNCE:-false}"
|
||||
|
||||
if [ -z "${DAEMON_URL:-}" ]
|
||||
then
|
||||
echo "DAEMON_URL is required, e.g. http://user:password@bitcoind:8332" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# NET names the coin class ElectrumX looks up, and a wrong one is not a
|
||||
# harmless mismatch: the class carries the genesis hash, so a testnet index
|
||||
# pointed at a regtest daemon fails at the first block with a message about
|
||||
# hashes rather than about configuration. The check exists mostly for one
|
||||
# specific typo — bitcoind calls these networks `main` and `test`, ElectrumX
|
||||
# calls them `mainnet` and `testnet`, and the pair is usually configured from
|
||||
# the same .env.
|
||||
case "$NET" in
|
||||
mainnet | testnet | testnet4 | signet | regtest | mutinynet) ;;
|
||||
*)
|
||||
echo "NET must be one of mainnet, testnet, testnet4, signet, regtest, mutinynet (got '$NET')" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# A named volume starts out owned by root. Non-recursive: only the empty case
|
||||
# needs fixing, and a mainnet index is hundreds of gigabytes.
|
||||
mkdir -p "$DB_DIRECTORY"
|
||||
if [ "$(stat -c %u "$DB_DIRECTORY")" != "$USER_UID" ]
|
||||
then
|
||||
chown "$USER_UID:$USER_GID" "$DB_DIRECTORY"
|
||||
fi
|
||||
|
||||
# TLS on demand. ElectrumX requires both files as soon as SERVICES mentions
|
||||
# ssl://, and refuses to start when they are missing — generating a self-signed
|
||||
# pair is the difference between "works out of the box" and a startup error
|
||||
# nobody expects from adding a port. Clients must trust it explicitly; a real
|
||||
# certificate is supplied by pointing SSL_CERTFILE/SSL_KEYFILE elsewhere.
|
||||
case "$SERVICES" in
|
||||
*ssl://*)
|
||||
export SSL_CERTFILE="${SSL_CERTFILE:-${DB_DIRECTORY}/electrumx.crt}"
|
||||
export SSL_KEYFILE="${SSL_KEYFILE:-${DB_DIRECTORY}/electrumx.key}"
|
||||
if [ ! -f "$SSL_CERTFILE" ] || [ ! -f "$SSL_KEYFILE" ]
|
||||
then
|
||||
echo "generating a self-signed certificate for $SSL_CERTFILE"
|
||||
openssl req -x509 -newkey rsa:2048 -nodes -days 3650 \
|
||||
-subj "/CN=electrumx" \
|
||||
-keyout "$SSL_KEYFILE" -out "$SSL_CERTFILE" 2>/dev/null
|
||||
chown "$USER_UID:$USER_GID" "$SSL_CERTFILE" "$SSL_KEYFILE"
|
||||
chmod 600 "$SSL_KEYFILE"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
exec gosu electrumx electrumx_server "$@"
|
||||
Reference in New Issue
Block a user