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 <noreply@anthropic.com>
This commit is contained in:
Patrick Mulligan 2026-02-15 16:03:13 -05:00
commit c3564beccf

View file

@ -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,19 +392,28 @@ 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."
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
fi
# 2. Build from worktree if specified
if [[ -n "$worktree" ]]; then
@ -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 <path> Build Lightning.Pub from git worktree"
echo " --image <name> 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=<sats> 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"