Build docker image and push to registry.bitdeals.org / main-build-job (push) Successful in 2m12s
The daemon has always listened on 8444 and nothing published it, so every node built from this image was outbound-only. Publishing it is now a documented choice rather than an omission -- including the two things that are not obvious from the config: peers are told the port from `port` in keys.dat rather than the one you mapped it to (so only 8444:8444 works), and the node's own address is never configured at all, because every peer replaces the hardcoded 127.0.0.1 in the version message with the IP it sees on the socket. An open port needs a brake, hence BITMESSAGE_MAXTOTALCONNECTIONS. It defaults to the PyBitmessage stock 200, so nothing changes for existing users of the image. The key is inserted when the stock config lacks it instead of trusting the substitution: the PyBitmessage clone is unpinned, and a silent no-op would ship a node that looks capped and is not. The API port in the example compose moves to loopback, which is what the README already prescribed.
91 lines
3.9 KiB
Bash
91 lines
3.9 KiB
Bash
#!/bin/sh
|
|
|
|
set -eu
|
|
|
|
export BITMESSAGE_API_USER="${BITMESSAGE_API_USER:-bitmessage_api_user}"
|
|
export BITMESSAGE_API_PASSWORD="${BITMESSAGE_API_PASSWORD:-bitmessage_api_password}"
|
|
export BITMESSAGE_SEED_ADDRESSES="${BITMESSAGE_SEED_ADDRESSES:-0}"
|
|
export BITMESSAGE_API_PORT="${BITMESSAGE_API_PORT:-8442}"
|
|
export BITMESSAGE_TTL="${BITMESSAGE_TTL:-172800}"
|
|
export BITMESSAGE_STOPRESENDINGAFTERXDAYS="${BITMESSAGE_STOPRESENDINGAFTERXDAYS:-30}"
|
|
export BITMESSAGE_APIVARIANT="${BITMESSAGE_APIVARIANT:-legacy}"
|
|
export BITMESSAGE_MAXTOTALCONNECTIONS="${BITMESSAGE_MAXTOTALCONNECTIONS:-200}"
|
|
|
|
# Reject anything but a plain number: this value is written into keys.dat, and
|
|
# unlike the credentials below it has no business containing characters that
|
|
# esc() would have to neutralise. A typo here would otherwise land in the config
|
|
# as a key the daemon silently ignores.
|
|
case "$BITMESSAGE_MAXTOTALCONNECTIONS" in
|
|
'' | *[!0-9]*)
|
|
echo "BITMESSAGE_MAXTOTALCONNECTIONS must be a positive integer" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if [ -z "${BITMESSAGE_SEED_PHRASE:-}" ]
|
|
then
|
|
BITMESSAGE_SEED_PHRASE="$(cat /dev/random | tr -dc "a-z" | head -c32)"
|
|
export BITMESSAGE_SEED_PHRASE
|
|
fi
|
|
|
|
# Escape a value for use on the right-hand side of the sed expressions below.
|
|
# There, a backslash starts an escape, "&" stands for the whole match, and "|"
|
|
# ends the replacement because it is the delimiter. Unescaped, a password
|
|
# containing "&" was silently rewritten into something else and one containing
|
|
# "|" made sed fail outright.
|
|
esc() {
|
|
printf '%s' "$1" | sed -e 's/[\\&|]/\\&/g'
|
|
}
|
|
|
|
# this command must be run as root (for bind mounts to container)
|
|
if [ -f keys.dat ]
|
|
then
|
|
chown bitmessage:bitmessage keys.dat
|
|
chmod 600 keys.dat
|
|
fi
|
|
|
|
# maxtotalconnections is the only brake on a node whose P2P port (8444) is
|
|
# published: it caps inbound sockets at the total minus maxoutboundconnections.
|
|
# The substitution below is a no-op when the key is missing, which would ship a
|
|
# node that looks capped and is not -- and the PyBitmessage clone in the
|
|
# Dockerfile is unpinned, so the stock config is whatever upstream generates
|
|
# today. Add the key rather than trust the substitution alone; line 1 is the
|
|
# [bitmessagesettings] header the daemon reads it from.
|
|
if ! grep -q "^maxtotalconnections = " keys.dat
|
|
then
|
|
gosu bitmessage sed -i "1a maxtotalconnections = $BITMESSAGE_MAXTOTALCONNECTIONS" keys.dat
|
|
fi
|
|
|
|
# Set config values. Every expression is anchored to the start of the line and
|
|
# names its key in the replacement, so no backreference is involved and nothing
|
|
# in another section can match. With set -e a failure here now stops the
|
|
# container instead of leaving the daemon on its previous settings unnoticed --
|
|
# including the case of a bind mount with no keys.dat at all.
|
|
gosu bitmessage sed -i \
|
|
-e "s|^apiinterface = .*|apiinterface = 0.0.0.0|" \
|
|
-e "s|^apivariant = .*|apivariant = $(esc "$BITMESSAGE_APIVARIANT")|" \
|
|
-e "s|^apiusername = .*|apiusername = $(esc "$BITMESSAGE_API_USER")|" \
|
|
-e "s|^apipassword = .*|apipassword = $(esc "$BITMESSAGE_API_PASSWORD")|" \
|
|
-e "s|^apiport = .*|apiport = $(esc "$BITMESSAGE_API_PORT")|" \
|
|
-e "s|^apienabled = .*|apienabled = True|" \
|
|
-e "s|^ttl = .*|ttl = $(esc "$BITMESSAGE_TTL")|" \
|
|
-e "s|^stopresendingafterxdays = .*|stopresendingafterxdays = $(esc "$BITMESSAGE_STOPRESENDINGAFTERXDAYS")|" \
|
|
-e "s|^maxtotalconnections = .*|maxtotalconnections = $BITMESSAGE_MAXTOTALCONNECTIONS|" \
|
|
-e "s|^udp = .*|udp = False|" keys.dat
|
|
|
|
# generate address from seed
|
|
if [ "$BITMESSAGE_SEED_ADDRESSES" -gt 0 ]
|
|
then
|
|
# Four attempts, not a bash {1..4}: this runs under dash, where brace
|
|
# expansion is literal and the loop would have run once. The call is
|
|
# idempotent (createDeterministicAddresses returns nothing for an address
|
|
# that already exists), so these are retries while the API comes up.
|
|
for i in 1 2 3 4
|
|
do
|
|
sleep 15
|
|
gosu bitmessage /usr/bin/python /usr/local/bin/seed_addr_gen.py
|
|
done &
|
|
fi
|
|
|
|
exec gosu bitmessage pybitmessage -d
|