From c3564beccfbf3e10b4572c8d5edad7c9b2de547d Mon Sep 17 00:00:00 2001 From: Patrick Mulligan Date: Sun, 15 Feb 2026 16:03:13 -0500 Subject: [PATCH] feat(docker): add standalone mode and external orchestration support - Add --standalone flag to use self-contained bitcoind/lnd - Default to unified mode using shared regtest - Track compose mode in state file for down/logs/reset - Add _setup_after_start internal command for external orchestration - Update help text with new options Co-Authored-By: Claude Opus 4.5 --- docker/dev.sh | 74 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 14 deletions(-) diff --git a/docker/dev.sh b/docker/dev.sh index c0fd90a..e1d55b2 100755 --- a/docker/dev.sh +++ b/docker/dev.sh @@ -8,7 +8,8 @@ # - Auto-configured ATM application # # Usage: -# ./dev.sh up # Start everything +# ./dev.sh up # Start (uses shared regtest) +# ./dev.sh up --standalone # Start self-contained (own bitcoind/lnd) # ./dev.sh up --fund # Start and auto-fund ATM with 100k sats # ./dev.sh up --fund=50000 # Start and auto-fund with specific amount # ./dev.sh up --machine # Start and launch ATM app @@ -38,6 +39,17 @@ PUBKEY_FILE="$STATE_DIR/lightning-pub-pubkey" NPROFILE_FILE="$STATE_DIR/lightning-pub-nprofile" APP_TOKEN_FILE="$STATE_DIR/atm-app-token" APP_ID_FILE="$STATE_DIR/atm-app-id" +MODE_FILE="$STATE_DIR/compose-mode" # "standalone" or "unified" + +# Get current compose file based on last used mode +get_compose_file() { + local mode=$(cat "$MODE_FILE" 2>/dev/null || echo "unified") + if [[ "$mode" == "standalone" ]]; then + echo "docker-compose.dev.yml" + else + echo "docker-compose.regtest.yml" + fi +} # Colors GREEN='\033[0;32m' @@ -363,6 +375,8 @@ cmd_up() { local auto_fund=false local fund_amount="$DEFAULT_FUNDING_SATS" local launch_machine=false + local standalone=false + local compose_file="docker-compose.regtest.yml" # Parse arguments while [[ $# -gt 0 ]]; do @@ -370,6 +384,7 @@ cmd_up() { --image) image="$2"; shift 2 ;; --worktree) worktree="$2"; shift 2 ;; --skip-regtest) skip_regtest=true; shift ;; + --standalone) standalone=true; shift ;; --fund) auto_fund=true; shift ;; --fund=*) auto_fund=true; fund_amount="${1#*=}"; shift ;; --machine|--atm) launch_machine=true; shift ;; @@ -377,18 +392,27 @@ cmd_up() { esac done + # Determine compose file + if [[ "$standalone" == "true" ]]; then + compose_file="docker-compose.dev.yml" + skip_regtest=true # Standalone mode has its own bitcoind/lnd + log "Starting in STANDALONE mode (self-contained bitcoind/lnd)" + else + log "Starting in UNIFIED mode (shared regtest)" + fi + echo "" log "Starting Lamassu development environment..." echo "" - # 1. Start regtest if needed - if [[ "$skip_regtest" != "true" ]]; then + # 1. Start shared regtest if needed (not in standalone mode) + if [[ "$standalone" != "true" ]] && [[ "$skip_regtest" != "true" ]]; then start_regtest || exit 1 - else - if ! is_regtest_running; then - error "Regtest not running. Remove --skip-regtest or start it manually." - exit 1 - fi + elif [[ "$standalone" != "true" ]] && ! is_regtest_running; then + error "Shared regtest not running." + echo " Start with: regtest-start" + echo " Or use: ./dev.sh up --standalone" + exit 1 fi # 2. Build from worktree if specified @@ -413,8 +437,15 @@ cmd_up() { export LIGHTNING_PUB_IMAGE="$image" export HOST_IP=$(get_local_ip) + # Save mode for other commands + if [[ "$standalone" == "true" ]]; then + echo "standalone" > "$MODE_FILE" + else + echo "unified" > "$MODE_FILE" + fi + log "Starting lamassu services..." - docker compose -f "$SCRIPT_DIR/docker-compose.regtest.yml" up -d + docker compose -f "$SCRIPT_DIR/$compose_file" up -d # 5. Wait for Lightning.Pub if ! wait_for_lightning_pub; then @@ -450,8 +481,9 @@ cmd_up() { } cmd_down() { + local compose_file=$(get_compose_file) log "Stopping lamassu services..." - docker compose -f "$SCRIPT_DIR/docker-compose.regtest.yml" down 2>/dev/null || true + docker compose -f "$SCRIPT_DIR/$compose_file" down 2>/dev/null || true if [[ "$1" == "--all" ]]; then stop_regtest @@ -469,8 +501,9 @@ cmd_reset() { exit 0 fi + local compose_file=$(get_compose_file) log "Stopping services..." - docker compose -f "$SCRIPT_DIR/docker-compose.regtest.yml" down -v 2>/dev/null || true + docker compose -f "$SCRIPT_DIR/$compose_file" down -v 2>/dev/null || true log "Removing state files..." rm -rf "$STATE_DIR" @@ -480,7 +513,8 @@ cmd_reset() { } cmd_logs() { - docker compose -f "$SCRIPT_DIR/docker-compose.regtest.yml" logs -f "$@" + local compose_file=$(get_compose_file) + docker compose -f "$SCRIPT_DIR/$compose_file" logs -f "$@" } cmd_status() { @@ -672,6 +706,16 @@ case "${1:-help}" in shift cmd_logs "$@" ;; + # Internal command for external orchestration (called by regtest-start --with-lamassu) + _setup_after_start) + if ! is_lightning_pub_ready; then + wait_for_lightning_pub || exit 1 + fi + local pubkey=$(extract_lightning_pub_info) + update_atm_env "$pubkey" + setup_atm_app || true + echo "ATM setup complete" + ;; status|info) cmd_status ;; @@ -709,15 +753,17 @@ case "${1:-help}" in echo " ./dev.sh logs miner" echo "" echo "Options for 'up':" + echo " --standalone Use self-contained mode (own bitcoind/lnd)" echo " --worktree Build Lightning.Pub from git worktree" echo " --image Use specific Docker image" - echo " --skip-regtest Don't auto-start regtest" + echo " --skip-regtest Don't auto-start shared regtest" echo " --fund Auto-fund ATM with 100k sats after startup" echo " --fund= Auto-fund ATM with specific amount" echo " --machine Launch ATM app after startup" echo "" echo "Examples:" - echo " $0 up # Start with default image" + echo " $0 up # Start (uses shared regtest)" + echo " $0 up --standalone # Start self-contained" echo " $0 up --fund # Start and fund ATM" echo " $0 up --fund --machine # Start, fund, and launch ATM" echo " $0 up --fund=50000 # Start and fund with 50k sats"