Update Development Workflow documentation, modify app configuration for Archipelago, and enhance deployment scripts

- Updated the Development-Workflow.mdc to clarify testing procedures for apps launching in iframes or new tabs.
- Changed Archipelago app configuration to use new credentials for RPC and database connections.
- Enhanced deployment scripts to improve handling of mempool-electrs and added support for NBXplorer in the BTCPay Server setup.
This commit is contained in:
Dorian 2026-02-25 17:23:38 +00:00
parent 129d7fe6f4
commit f0ef84e4a5
8 changed files with 98 additions and 39 deletions

View File

@ -11,7 +11,11 @@ alwaysApply: true
1. **Make the change** the user requests
2. **SSH and build to live server** - Run `./scripts/deploy-to-target.sh --live` once done
3. **Test that it works** - Verify apps launch and show their UI in a new browser tab on their server port (e.g. http://192.168.1.228:4080 for Mempool)
3. **Test that it works** - Verify apps launch: iframe for most apps, new tab for BTCPay/Home Assistant
## App Launcher (iframe + new tab fallback)
Most apps launch in the iframe overlay. BTCPay (port 23000) and Home Assistant (port 8123) set `X-Frame-Options` and don't support subpath proxying—they open in a new tab instead.
4. **If broken, fix and repeat** - Debug, fix, redeploy, and test again until complete
5. **End loop** only when everything works

View File

@ -1251,8 +1251,8 @@ fn get_app_config(
"ELECTRUM_TLS_ENABLED=false".to_string(),
format!("CORE_RPC_HOST={}", host_ip),
"CORE_RPC_PORT=8332".to_string(),
"CORE_RPC_USERNAME=bitcoin".to_string(),
"CORE_RPC_PASSWORD=bitcoinpass".to_string(),
"CORE_RPC_USERNAME=archipelago".to_string(),
"CORE_RPC_PASSWORD=archipelago123".to_string(),
"DATABASE_ENABLED=true".to_string(),
"DATABASE_HOST=archy-mempool-db".to_string(),
"DATABASE_DATABASE=mempool".to_string(),
@ -1271,7 +1271,7 @@ fn get_app_config(
"--daemon-rpc-addr".to_string(),
format!("{}:8332", host_ip),
"--cookie".to_string(),
"bitcoin:bitcoinpass".to_string(),
"archipelago:archipelago123".to_string(),
"--jsonrpc-import".to_string(),
"--electrum-rpc-addr".to_string(),
"0.0.0.0:50001".to_string(),
@ -1428,8 +1428,8 @@ fn get_app_config(
vec!["/var/lib/archipelago/fedimint:/data".to_string()],
vec![
"FM_DATA_DIR=/data".to_string(),
"FM_BITCOIND_USERNAME=bitcoin".to_string(),
"FM_BITCOIND_PASSWORD=bitcoinpass".to_string(),
"FM_BITCOIND_USERNAME=archipelago".to_string(),
"FM_BITCOIND_PASSWORD=archipelago123".to_string(),
"FM_BITCOIN_NETWORK=bitcoin".to_string(),
"FM_BIND_P2P=0.0.0.0:8173".to_string(),
"FM_BIND_API=0.0.0.0:8174".to_string(),

View File

@ -499,7 +499,7 @@ mkdir -p "$IMAGES_DIR"
IMAGES_CAPTURED_FROM_SERVER=0
if [ -n "$DEV_SERVER" ] && [ "$DEV_SERVER" != "localhost" ] && [ "$DEV_SERVER" != "127.0.0.1" ]; then
echo " Capturing container images from live server ($DEV_SERVER)..."
CAPTURE_PATTERNS="bitcoin-ui bitcoin-knots lnd lnd-ui filebrowser mempool mempool-electrs tailscale homeassistant btcpayserver nostr-rs-relay strfry alpine-tor"
CAPTURE_PATTERNS="bitcoin-ui bitcoin-knots lnd lnd-ui filebrowser mempool mempool-electrs tailscale homeassistant btcpayserver nbxplorer postgres nostr-rs-relay strfry alpine-tor"
REMOTE_TMP="/tmp/archipelago-image-capture-$$"
SAVED_LIST=$(ssh "$DEV_SERVER" "mkdir -p $REMOTE_TMP && for p in $CAPTURE_PATTERNS; do img=\$(sudo podman images --format '{{.Repository}}:{{.Tag}}' 2>/dev/null | grep -i \"\$p\" | head -1); [ -n \"\$img\" ] && sudo podman save -o \"$REMOTE_TMP/\$p.tar\" \"\$img\" 2>/dev/null && echo \"\$p\"; done" 2>/dev/null) || true
for p in $SAVED_LIST; do
@ -521,6 +521,8 @@ bitcoinknots/bitcoin:29 bitcoin-knots.tar
lightninglabs/lnd:v0.18.4-beta lnd.tar
ghcr.io/home-assistant/home-assistant:stable homeassistant.tar
btcpayserver/btcpayserver:latest btcpayserver.tar
docker.io/nicolasdorier/nbxplorer:2.6.0 nbxplorer.tar
docker.io/library/postgres:16 postgres-btcpay.tar
mempool/frontend:latest mempool-frontend.tar
mempool/backend:v2.5.0 mempool-backend.tar
mempool/electrs:latest mempool-electrs.tar

View File

@ -82,7 +82,7 @@ define(['./workbox-21a80088'], (function (workbox) { 'use strict';
"revision": "3ca0b8505b4bec776b69afdba2768812"
}, {
"url": "index.html",
"revision": "0.uegfpird2pk"
"revision": "0.dbmr9lf4rv4"
}], {});
workbox.cleanupOutdatedCaches();
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {

Binary file not shown.

View File

@ -1,13 +1,27 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
/** BTCPay and Home Assistant set X-Frame-Options and don't support subpath proxy - open in new tab */
function mustOpenInNewTab(url: string): boolean {
try {
const u = new URL(url)
return u.port === '23000' || u.port === '8123'
} catch {
return false
}
}
export const useAppLauncherStore = defineStore('appLauncher', () => {
const isOpen = ref(false)
const url = ref('')
const title = ref('')
let previousActiveElement: HTMLElement | null = null
function open(payload: { url: string; title: string }) {
function open(payload: { url: string; title: string; openInNewTab?: boolean }) {
if (payload.openInNewTab || mustOpenInNewTab(payload.url)) {
window.open(payload.url, '_blank', 'noopener,noreferrer')
return
}
previousActiveElement = (document.activeElement as HTMLElement) || null
url.value = payload.url
title.value = payload.title

View File

@ -635,8 +635,8 @@ function launchApp() {
prod: 'http://localhost:8332'
},
'btcpay-server': {
dev: 'http://localhost:14142',
prod: 'http://localhost:14142'
dev: 'http://localhost:23000',
prod: 'http://localhost:23000'
},
'homeassistant': {
dev: 'http://localhost:8123',

View File

@ -202,7 +202,8 @@ if [ "$LIVE" = true ]; then
TARGET_IP='$TARGET_IP'
NET_OPT='--network archy-net'
# Clean any duplicate/old mempool containers (user may have two versions)
for c in mempool mempool-api mempool-electrs mempool-web archy-mempool-api archy-mempool-web; do
# EXCLUDE mempool-electrs - indexing takes days, do not recreate on every deploy
for c in mempool mempool-api mempool-web archy-mempool-api archy-mempool-web; do
sudo \$DOCKER stop \$c 2>/dev/null
sudo \$DOCKER rm -f \$c 2>/dev/null
done
@ -223,26 +224,35 @@ if [ "$LIVE" = true ]; then
MYSQL_CNT=\${MYSQL_CNT:-archy-mempool-db}
# Ensure DB is on archy-net so mempool-api can resolve it
sudo \$DOCKER network connect archy-net \$MYSQL_CNT 2>/dev/null || true
# Create mempool-electrs (indexer - connects to Bitcoin, exposes Electrum protocol on 50001)
for c in \$(sudo \$DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep mempool-electrs); do
echo ' Recreating mempool-electrs...'
sudo \$DOCKER stop \"\$c\" 2>/dev/null
sudo \$DOCKER rm -f \"\$c\" 2>/dev/null
done
# Create mempool-electrs ONLY if missing - do NOT recreate (indexing takes days, data is 800GB+)
# One-time migration: if on bridge (wrong network), recreate with archy-net so it can reach bitcoin-knots
if sudo \$DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -q mempool-electrs; then
MEMPOOL_ELECTRS_NET=\$(sudo \$DOCKER inspect mempool-electrs --format '{{range \$k, \$v := .NetworkSettings.Networks}}{{\$k}}{{end}}' 2>/dev/null || true)
if [ \"\$MEMPOOL_ELECTRS_NET\" = \"bridge\" ] || [ \"\$MEMPOOL_ELECTRS_NET\" = \"\" ]; then
echo ' Migrating mempool-electrs to archy-net (preserving 800GB+ index)...'
sudo \$DOCKER stop mempool-electrs 2>/dev/null
sudo \$DOCKER rm mempool-electrs 2>/dev/null
fi
fi
if ! sudo \$DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q mempool-electrs; then
echo ' Creating mempool-electrs (indexer - may take hours to sync)...'
sudo mkdir -p /var/lib/archipelago/mempool-electrs
# Use host IP to reach Bitcoin (TARGET_IP:8332) - more reliable than container DNS (bitcoin-knots)
sudo \$DOCKER run -d --name mempool-electrs --restart unless-stopped \
-p 50001:50001 \
-v /var/lib/archipelago/mempool-electrs:/data \
docker.io/mempool/electrs:latest \
--daemon-rpc-addr \$TARGET_IP:8332 \
--cookie archipelago:archipelago123 \
--jsonrpc-import \
--electrum-rpc-addr 0.0.0.0:50001 \
--db-dir /data \
--lightmode
if sudo \$DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -q mempool-electrs; then
echo ' Starting existing mempool-electrs (preserving index)...'
sudo \$DOCKER start mempool-electrs 2>/dev/null || true
else
echo ' Creating mempool-electrs (indexer - may take days to sync, do not recreate)...'
sudo mkdir -p /var/lib/archipelago/mempool-electrs
# Use archy-net + bitcoin-knots for reliable Bitcoin connectivity (not host IP from bridge)
sudo \$DOCKER run -d --name mempool-electrs --restart unless-stopped \$NET_OPT \
-p 50001:50001 \
-v /var/lib/archipelago/mempool-electrs:/data \
docker.io/mempool/electrs:latest \
--daemon-rpc-addr bitcoin-knots:8332 \
--cookie archipelago:archipelago123 \
--jsonrpc-import \
--electrum-rpc-addr 0.0.0.0:50001 \
--db-dir /data \
--lightmode
fi
fi
# Create/recreate mempool-api (backend on 8999) - required for mempool to work
for c in \$(sudo \$DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -E 'mempool-api|archy-mempool-api'); do
@ -288,7 +298,7 @@ if [ "$LIVE" = true ]; then
fi
" 2>&1 | sed 's/^/ /' || true
# Fix BTCPay Server: requires PostgreSQL; create archy-btcpay-db, recreate btcpay-server with BTCPAY_POSTGRES
# Fix BTCPay Server: requires PostgreSQL + NBXplorer (BTCPay needs NBXplorer for block indexing)
echo " Fixing BTCPay Server stack..."
TARGET_IP="$(echo "$TARGET_HOST" | cut -d@ -f2)"
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "
@ -297,6 +307,8 @@ if [ "$LIVE" = true ]; then
TARGET_IP='$TARGET_IP'
sudo \$DOCKER network create archy-net 2>/dev/null || true
NET_OPT='--network archy-net'
# Ensure bitcoin-knots is on archy-net for NBXplorer/BTCPay to reach it
sudo \$DOCKER network connect archy-net bitcoin-knots 2>/dev/null || true
# Create PostgreSQL for BTCPay if missing
if ! sudo \$DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -qE 'archy-btcpay-db|postgres-btcpay'; then
echo ' Creating archy-btcpay-db (PostgreSQL)...'
@ -309,12 +321,38 @@ if [ "$LIVE" = true ]; then
docker.io/postgres:15-alpine
sleep 3
fi
# Recreate btcpay-server with PostgreSQL and Bitcoin RPC
for c in \$(sudo \$DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -E 'btcpay-server|archy-btcpay'); do
echo ' Recreating btcpay-server with PostgreSQL...'
sudo \$DOCKER stop \"\$c\" 2>/dev/null
sudo \$DOCKER rm -f \"\$c\" 2>/dev/null
break
# Create NBXplorer database in PostgreSQL (NBXplorer needs its own DB)
sudo \$DOCKER exec archy-btcpay-db psql -U postgres -tc \"SELECT 1 FROM pg_database WHERE datname='nbxplorer'\" 2>/dev/null | grep -q 1 || \
sudo \$DOCKER exec -e PGPASSWORD=btcpaypass archy-btcpay-db psql -U postgres -c \"CREATE DATABASE nbxplorer;\" 2>/dev/null || true
# Create NBXplorer (required by BTCPay - indexes blocks for payment tracking)
if ! sudo \$DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q archy-nbxplorer; then
if sudo \$DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -q archy-nbxplorer; then
sudo \$DOCKER start archy-nbxplorer 2>/dev/null || true
else
echo ' Creating archy-nbxplorer...'
sudo mkdir -p /var/lib/archipelago/nbxplorer
sudo \$DOCKER run -d --name archy-nbxplorer --restart unless-stopped \$NET_OPT \
-p 32838:32838 \
-v /var/lib/archipelago/nbxplorer:/data \
-e NBXPLORER_DATADIR=/data \
-e NBXPLORER_NETWORK=mainnet \
-e NBXPLORER_CHAINS=btc \
-e NBXPLORER_BIND=0.0.0.0:32838 \
-e NBXPLORER_BTCRPCURL=http://bitcoin-knots:8332 \
-e NBXPLORER_BTCRPCUSER=archipelago \
-e NBXPLORER_BTCRPCPASSWORD=archipelago123 \
-e NBXPLORER_POSTGRES='User ID=btcpay;Password=btcpaypass;Host=archy-btcpay-db;Port=5432;Database=nbxplorer;Include Error Detail=true' \
docker.io/nicolasdorier/nbxplorer:2.6.0
sleep 5
fi
fi
# Recreate btcpay-server with PostgreSQL, NBXplorer URL, and Bitcoin RPC
for c in btcpay-server archy-btcpay; do
if sudo \$DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -qx \"\$c\"; then
echo ' Recreating btcpay-server with NBXplorer...'
sudo \$DOCKER stop \"\$c\" 2>/dev/null
sudo \$DOCKER rm -f \"\$c\" 2>/dev/null
fi
done
if ! sudo \$DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q btcpay-server; then
echo ' Creating btcpay-server on 23000...'
@ -326,7 +364,8 @@ if [ "$LIVE" = true ]; then
-e BTCPAY_PROTOCOL=http \
-e BTCPAY_HOST=\$TARGET_IP:23000 \
-e BTCPAY_CHAINS=btc \
-e BTCPAY_BTCRPCURL=http://\$TARGET_IP:8332 \
-e BTCPAY_BTCEXPLORERURL=http://archy-nbxplorer:32838 \
-e BTCPAY_BTCRPCURL=http://bitcoin-knots:8332 \
-e BTCPAY_BTCRPCUSER=archipelago \
-e BTCPAY_BTCRPCPASSWORD=archipelago123 \
-e BTCPAY_POSTGRES='User ID=btcpay;Password=btcpaypass;Host=archy-btcpay-db;Port=5432;Database=btcpay;Include Error Detail=true' \