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:
@@ -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
|
||||
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"), {
|
||||
|
||||
BIN
neode-ui/public/assets/video/Kratter.MP3
Normal file
BIN
neode-ui/public/assets/video/Kratter.MP3
Normal file
Binary file not shown.
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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' \
|
||||
|
||||
Reference in New Issue
Block a user