Files
bitdeals bf2c2d3508 feat: docker image for Bitcoin Core, configured by environment
Replaces lncm/bitcoind, which pins Core 26 — a version that still has legacy
wallets, while the code that talks to it (bt's BitcoindClient) is written for
the descriptor-only behaviour of 29 and later.

The binaries are the official release build, verified by SHA-256 in the same
layer that downloads them; a version bump that forgets the checksum fails the
build instead of shipping something unverified. uid 1000 and /data/.bitcoin are
kept from the image this replaces, so an existing named volume survives the
switch without a recursive chown of a synced chain.

Verified on testnet2: regtest node healthy in ~12 s, descriptor wallet, 101
blocks mined, sendtoaddress accepted — the last one being the check for
BITCOIND_FALLBACKFEE, without which a fresh chain refuses to send.
2026-08-06 11:56:52 +00:00

91 lines
3.2 KiB
Bash
Executable File

#!/bin/sh
set -eu
export BITCOIND_CHAIN="${BITCOIND_CHAIN:-main}"
export BITCOIND_USER="${BITCOIND_USER:-user}"
export BITCOIND_PASSWORD="${BITCOIND_PASSWORD:-pass}"
export BITCOIND_FALLBACKFEE="${BITCOIND_FALLBACKFEE:-0}"
export BITCOIND_RPCBIND="${BITCOIND_RPCBIND:-0.0.0.0}"
export BITCOIND_RPCALLOWIP="${BITCOIND_RPCALLOWIP:-0.0.0.0/0}"
export BITCOIND_TXINDEX="${BITCOIND_TXINDEX:-0}"
export BITCOIND_TXOSPENDERINDEX="${BITCOIND_TXOSPENDERINDEX:-0}"
export BITCOIND_EXTRA_ARGS="${BITCOIND_EXTRA_ARGS:-}"
# The chain name decides the default RPC port, so an unknown value must stop the
# container rather than fall through to a default: "-chain=testnet" (the name
# Core does not use -- it wants "test") would otherwise be a mainnet node
# holding a wallet the caller believes is worthless.
case "$BITCOIND_CHAIN" in
main) default_port=8332 ;;
test) default_port=18332 ;;
signet) default_port=38332 ;;
regtest) default_port=18443 ;;
*)
echo "BITCOIND_CHAIN must be one of main, test, signet, regtest (got '$BITCOIND_CHAIN')" >&2
exit 1
;;
esac
export BITCOIND_PORT="${BITCOIND_PORT:-$default_port}"
case "$BITCOIND_PORT" in
'' | *[!0-9]*)
echo "BITCOIND_PORT must be a positive integer" >&2
exit 1
;;
esac
# A named volume starts out owned by root. Non-recursive on purpose: the only
# case that needs fixing is the empty datadir, and a synced mainnet chain is
# hundreds of gigabytes -- walking it on every start would add minutes to each
# restart. A datadir moved here from an image with another uid must be chowned
# by hand, once (see README, "Notes").
mkdir -p "$BITCOIN_DATA"
if [ "$(stat -c %u "$BITCOIN_DATA")" != "$USER_UID" ]
then
chown "$USER_UID:$USER_GID" "$BITCOIN_DATA"
fi
# Credentials for bitcoin-cli, so the health check does not have to repeat them
# on a command line. Written before the daemon starts and readable only by the
# daemon's user. rpcport is deliberately at the top level: bitcoin-cli is
# invoked without -chain and therefore reads the mainnet section, whatever chain
# the daemon runs -- what matters is that the number matches.
cli_conf="${BITCOIN_DATA}/cli.conf"
umask 077
cat > "$cli_conf" <<EOF
rpcconnect=127.0.0.1
rpcport=${BITCOIND_PORT}
rpcuser=${BITCOIND_USER}
rpcpassword=${BITCOIND_PASSWORD}
EOF
chown "$USER_UID:$USER_GID" "$cli_conf"
umask 022
# Everything goes on the command line rather than into bitcoin.conf. Core treats
# rpcport, port and bind as network-specific options: in a config file they only
# apply inside the matching [main]/[test]/[regtest] section, while on the
# command line they apply to the chain in force. One list that behaves the same
# on every network is worth more here than a config file nobody edits.
set -- \
-chain="$BITCOIND_CHAIN" \
-datadir="$BITCOIN_DATA" \
-server=1 \
-printtoconsole=1 \
-rpcport="$BITCOIND_PORT" \
-rpcuser="$BITCOIND_USER" \
-rpcpassword="$BITCOIND_PASSWORD" \
-rpcbind="$BITCOIND_RPCBIND" \
-rpcallowip="$BITCOIND_RPCALLOWIP" \
-txindex="$BITCOIND_TXINDEX" \
-txospenderindex="$BITCOIND_TXOSPENDERINDEX" \
-fallbackfee="$BITCOIND_FALLBACKFEE" \
"$@"
# Unquoted on purpose: this is the one variable whose whole point is to be split
# into separate arguments.
# shellcheck disable=SC2086
set -- "$@" $BITCOIND_EXTRA_ARGS
exec gosu bitcoin bitcoind "$@"