#!/usr/bin/env bash set -euo pipefail ########################################################## ################## Check dependencies #################### ########################################################## check_dependencies () { for cmd in "$@"; do if ! command -v $cmd >/dev/null 2>&1; then echo "This script requires \"${cmd}\" to be installed" exit 1 fi done } if [ ! "$(uname -s)" == "Linux" ]; then echo "Sorry, Umbrel only supports Linux-based systems at this point." echo echo "You may work around this by modifying the configuration script yourself, but it's highly experimental." echo "If you get it working, we hope you consider making a PR. :)" exit 1 fi check_dependencies docker docker-compose dirname readlink # Switch to Umbrel's root directory UMBREL_ROOT="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")"/..)" if [[ ! -d "$UMBREL_ROOT" ]]; then echo "Root dir does not exist '$UMBREL_ROOT'" exit 1 fi cd "$UMBREL_ROOT" # Make sure we use the status dir from the real Umbrel installation if this is # an OTA update. STATUS_DIR="${UMBREL_ROOT}/statuses" if [[ -f "${UMBREL_ROOT}/../.umbrel" ]]; then STATUS_DIR="${UMBREL_ROOT}/../statuses" fi # Configure for mainnet or testnet or regtest depending # upon the user-supplied value of $NETWORK BITCOIN_NETWORK="${NETWORK:-mainnet}" if [ "$BITCOIN_NETWORK" != "mainnet" ] && [ "$BITCOIN_NETWORK" != "testnet" ] && [ "$BITCOIN_NETWORK" != "regtest" ]; then echo "Error: Umbrel can only be configured for mainnet (default), testnet or regtest" exit 1 fi # Get current Umbrel version UMBREL_VERSION="$(cat ${UMBREL_ROOT}/info.json | jq -r .version)" echo echo "======================================" if [[ -f "${STATUS_DIR}/configured" ]]; then echo "=========== RECONFIGURING ============" else echo "============ CONFIGURING =============" fi echo "========= UMBREL (${BITCOIN_NETWORK}) ===========" echo "======================================" echo ########################################################## ############### Setup configuration files ############### ########################################################## # Store paths to intermediary config files BITCOIN_CONF_FILE="./templates/bitcoin.conf" LND_CONF_FILE="./templates/lnd.conf" TOR_CONF_FILE="./templates/torrc" ELECTRS_CONF_FILE="./templates/electrs.toml" ENV_FILE="./templates/.env" # Remove intermediary files if they exist from any # previous unclean configuration run [[ -f "$BITCOIN_CONF_FILE" ]] && rm -f "$BITCOIN_CONF_FILE" [[ -f "$LND_CONF_FILE" ]] && rm -f "$LND_CONF_FILE" [[ -f "$TOR_CONF_FILE" ]] && rm -f "$TOR_CONF_FILE" [[ -f "$ELECTRS_CONF_FILE" ]] && rm -f "$ELECTRS_CONF_FILE" [[ -f "$ENV_FILE" ]] && rm -f "$ENV_FILE" # Copy template configs to intermediary configs [[ -f "./templates/bitcoin-sample.conf" ]] && cp "./templates/bitcoin-sample.conf" "$BITCOIN_CONF_FILE" [[ -f "./templates/lnd-sample.conf" ]] && cp "./templates/lnd-sample.conf" "$LND_CONF_FILE" [[ -f "./templates/torrc-sample" ]] && cp "./templates/torrc-sample" "$TOR_CONF_FILE" [[ -f "./templates/electrs-sample.toml" ]] && cp "./templates/electrs-sample.toml" "$ELECTRS_CONF_FILE" [[ -f "./templates/.env-sample" ]] && cp "./templates/.env-sample" "$ENV_FILE" ########################################################## ############ Generate configuration variables ############ ########################################################## # Load existing credentials if we have some [[ -f "./.env" ]] && source "./.env" [[ ! -z ${PREV_ENV_FILE+x} ]] && [[ -f "${PREV_ENV_FILE}" ]] && source "${PREV_ENV_FILE}" # Bitcoin Core ports BITCOIN_RPC_PORT=8332 BITCOIN_P2P_PORT=8333 # Generate RPC credentials if [[ -z ${BITCOIN_RPC_USER+x} ]] || [[ -z ${BITCOIN_RPC_PASS+x} ]] || [[ -z ${BITCOIN_RPC_AUTH+x} ]]; then echo "Generating auth credentials" echo BITCOIN_RPC_USER="umbrel" BITCOIN_RPC_DETAILS=$("./scripts/rpcauth.py" "$BITCOIN_RPC_USER") BITCOIN_RPC_PASS=$(echo "$BITCOIN_RPC_DETAILS" | tail -1) BITCOIN_RPC_AUTH=$(echo "$BITCOIN_RPC_DETAILS" | head -2 | tail -1 | sed -e "s/^rpcauth=//") fi # Pull Tor image and generate Tor password if [[ -z ${TOR_PASSWORD+x} ]] || [[ -z ${TOR_HASHED_PASSWORD+x} ]]; then echo "Generating Tor password" echo TOR_PASSWORD=$("./scripts/rpcauth.py" "itdoesntmatter" | tail -1) TOR_HASHED_PASSWORD=$(docker run --rm getumbrel/tor:v0.4.1.9 --quiet --hash-password "$TOR_PASSWORD") fi ########################################################## ### Update config files with configuration variables ##### ########################################################## if [ "$BITCOIN_NETWORK" == "testnet" ]; then # Set testnet ports BITCOIN_RPC_PORT=18332 BITCOIN_P2P_PORT=18333 # Switch Bitcoin Core to testnet sed -i '1s/^/testnet=1\n[test]\n\n/' "$BITCOIN_CONF_FILE" # Switch LND to testnet sed -i "s/bitcoin.mainnet=1/bitcoin.testnet=1/g;" "$LND_CONF_FILE" # Uncomment testnet neutrino block and peers sed -i "s/\# \[neutrino\]/\[neutrino\]/g;" "$LND_CONF_FILE" sed -i "s/\# neutrino.addpeer=testnet1-btcd.zaphq.io/neutrino.addpeer=testnet1-btcd.zaphq.io/g;" "$LND_CONF_FILE" sed -i "s/\# neutrino.addpeer=testnet2-btcd.zaphq.io/neutrino.addpeer=testnet2-btcd.zaphq.io/g;" "$LND_CONF_FILE" # Set electrs to testnet sed -i "s/network = \"bitcoin\"/network = \"testnet\"/g;" "$ELECTRS_CONF_FILE" fi if [ "$BITCOIN_NETWORK" == "regtest" ]; then # Set regtest ports BITCOIN_RPC_PORT=18443 BITCOIN_P2P_PORT=18444 # Switch Bitcoin Core to regtest sed -i '1s/^/regtest=1\n[regtest]\n\n/' "$BITCOIN_CONF_FILE" # Switch LND to regtest sed -i "s/bitcoin.mainnet=1/bitcoin.regtest=1/g;" "$LND_CONF_FILE" # Use bitcoind as the node sed -i "s/bitcoin.node=neutrino/bitcoin.node=bitcoind/g;" "$LND_CONF_FILE" # Set electrs to regtest sed -i "s/network = \"bitcoin\"/network = \"regtest\"/g;" "$ELECTRS_CONF_FILE" fi # Update RPC and P2P Ports sed -i "s/rpcport=/rpcport=$BITCOIN_RPC_PORT/g;" "$BITCOIN_CONF_FILE" sed -i "s/port=/port=$BITCOIN_P2P_PORT/g;" "$BITCOIN_CONF_FILE" sed -i "s//$BITCOIN_RPC_PORT/g;" "$TOR_CONF_FILE" sed -i "s//$BITCOIN_P2P_PORT/g;" "$TOR_CONF_FILE" sed -i "/daemon_rpc_addr/s//$BITCOIN_RPC_PORT/g;" "$ELECTRS_CONF_FILE" sed -i "s/BITCOIN_RPC_PORT=/BITCOIN_RPC_PORT=$BITCOIN_RPC_PORT/g;" "$ENV_FILE" sed -i "s/BITCOIN_P2P_PORT=/BITCOIN_P2P_PORT=$BITCOIN_P2P_PORT/g;" "$ENV_FILE" # Add rpcauth sed -i "s/rpcauth=/rpcauth=$BITCOIN_RPC_AUTH/g;" "$BITCOIN_CONF_FILE" sed -i "s/BITCOIN_RPC_AUTH=/BITCOIN_RPC_AUTH='$BITCOIN_RPC_AUTH'/g;" "$ENV_FILE" # Add RPC credentials to lnd.conf sed -i "s/bitcoind.rpcuser=/bitcoind.rpcuser=$BITCOIN_RPC_USER/g;" "$LND_CONF_FILE" sed -i "s/bitcoind.rpcpass=/bitcoind.rpcpass=$BITCOIN_RPC_PASS/g;" "$LND_CONF_FILE" # Add RPC credentials to env file sed -i "s/BITCOIN_RPC_USER=/BITCOIN_RPC_USER=$BITCOIN_RPC_USER/g;" "$ENV_FILE" sed -i "s/BITCOIN_RPC_PASS=/BITCOIN_RPC_PASS=$BITCOIN_RPC_PASS/g;" "$ENV_FILE" # Add chain to env file sed -i "s/BITCOIN_NETWORK=/BITCOIN_NETWORK=$BITCOIN_NETWORK/g;" "$ENV_FILE" # Add Tor password sed -i "s/HashedControlPassword /HashedControlPassword $TOR_HASHED_PASSWORD/g;" "$TOR_CONF_FILE" sed -i "s/torpassword=/torpassword=$TOR_PASSWORD/g;" "$BITCOIN_CONF_FILE" sed -i "s/tor.password=/tor.password=$TOR_PASSWORD/g;" "$LND_CONF_FILE" sed -i "s/TOR_PASSWORD=/TOR_PASSWORD=$TOR_PASSWORD/g;" "$ENV_FILE" sed -i "s/TOR_HASHED_PASSWORD=/TOR_HASHED_PASSWORD=$TOR_HASHED_PASSWORD/g;" "$ENV_FILE" # Store docker binary path DOCKER_BINARY=$(readlink -f "$(which docker)") sed -i "s#DOCKER_BINARY=#DOCKER_BINARY=$DOCKER_BINARY#g;" "$ENV_FILE" # Set Umbrel version in electrs banner sed -i "/server_banner/s//$UMBREL_VERSION/g;" "$ELECTRS_CONF_FILE" # Add hostname to lnd.conf for TLS certificate DEVICE_HOSTNAME="$(hostname)" sed -i "s/tlsextradomain=/tlsextradomain=$DEVICE_HOSTNAME.local/g;" "$LND_CONF_FILE" # If node is already synced, do not reset to neutrino if [[ -f "${STATUS_DIR}/node-status-bitcoind-ready" ]]; then sed -i "s/bitcoin.node=.*/bitcoin.node=bitcoind/g;" "$LND_CONF_FILE" fi ########################################################## ############### Performance optimizations ################ ########################################################## echo echo "Making performance optimizations" echo echo "Setting dbcache size" echo DBCACHE_SIZE=$(awk '/MemTotal/{printf "%d\n", ($2/2^10 * 0.5) - 300}' /proc/meminfo) sed -i -e "s/dbcache=/dbcache=$DBCACHE_SIZE/g" "$BITCOIN_CONF_FILE" # TODO: Adjust prune size based on available disk space ########################################################## ############## Override main config files ################ ########################################################## mv -f "$BITCOIN_CONF_FILE" "./bitcoin/bitcoin.conf" mv -f "$LND_CONF_FILE" "./lnd/lnd.conf" mv -f "$TOR_CONF_FILE" "./tor/torrc" mv -f "$ELECTRS_CONF_FILE" "./electrs/electrs.toml" mv -f "$ENV_FILE" "./.env" ########################################################## ################ Configuration complete ################## ########################################################## echo "Pulling Umbrel Docker images" echo docker-compose pull --quiet echo "Configuring permissions..." echo chown -R 1000:1000 "$UMBREL_ROOT" # Create configured status touch "${STATUS_DIR}/configured" echo "Configuration successful" echo "You can now start Umbrel by running:" echo " sudo ./scripts/start" echo