From 6a30ff11bda6d8cd8fd9aae4e8caef0c766aaedd Mon Sep 17 00:00:00 2001 From: archipelago Date: Thu, 11 Jun 2026 04:44:58 -0400 Subject: [PATCH] chore: release v1.7.84-alpha --- CHANGELOG.md | 8 +++ apps/bitcoin-core/manifest.yml | 17 +++++-- core/Cargo.lock | 2 +- core/archipelago/Cargo.toml | 2 +- core/archipelago/src/api/rpc/bitcoin_relay.rs | 51 +++++++++++++++++-- core/archipelago/src/container/quadlet.rs | 4 +- core/archipelago/src/server.rs | 34 ++++++++++--- neode-ui/package-lock.json | 4 +- neode-ui/package.json | 2 +- .../src/views/settings/AccountInfoSection.vue | 12 +++++ release-manifest.json | 36 +++++++------ releases/manifest.json | 36 +++++++------ scripts/image-versions.sh | 3 +- 13 files changed, 150 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d695165e..55f5ac69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## v1.7.84-alpha (2026-06-11) + +- Bitcoin trusted-node relay approvals now generate restricted `txrelay` RPC credentials when needed and restart the active Bitcoin backend so bitcoind loads the new `rpcauth` whitelist. +- Bitcoin Core now matches Bitcoin Knots for restricted relay RPC support, including the txrelay secret injection and sendrawtransaction-focused whitelist. +- The Bitcoin UI companion image is pinned to `1.7.84-alpha` across release metadata and the Quadlet fallback path, avoiding stale `latest` detection during OTA updates. +- Container scanning now uses an RAII in-flight guard so timeout and error paths cannot leave the scanner stuck in a permanently busy state. +- Validation passed with `cargo fmt`, `cargo check -p archipelago`, `git diff --check`, and focused source review of the relay message/approval path. + ## v1.7.83-alpha (2026-06-11) - App launch metadata now derives more consistently from app manifests, with typed launch interfaces and catalog generation updates that keep packaged apps aligned with their runtime ports and launch surfaces. diff --git a/apps/bitcoin-core/manifest.yml b/apps/bitcoin-core/manifest.yml index 7ca77373..accc3004 100644 --- a/apps/bitcoin-core/manifest.yml +++ b/apps/bitcoin-core/manifest.yml @@ -26,10 +26,19 @@ app: echo "bitcoind not found in image" >&2; exit 127; fi; - if [ "${DISK_GB:-0}" -lt 1000 ]; then - exec "$BITCOIND" -datadir=/home/bitcoin/.bitcoin -noconf -server=1 -prune=550 -rpcallowip=0.0.0.0/0 -rpcbind=0.0.0.0:8332 -listen=1 -bind=0.0.0.0:8333 -dbcache=1024 -par=0 -maxconnections=125 -rpcuser="${BITCOIN_RPC_USER}" -rpcpassword="${BITCOIN_RPC_PASS}"; + RPC_USER="$(printenv BITCOIN_RPC_USER)"; + RPC_PASS="$(printenv BITCOIN_RPC_PASS)"; + RPC_TXRELAY_AUTH="$(printenv BITCOIN_RPC_TXRELAY_RPCAUTH || true)"; + DISK_GB_VALUE="$(printenv DISK_GB || true)"; + RPC_HEADROOM="-rpcthreads=16 -rpcworkqueue=256"; + RPC_TXRELAY_FLAGS="-rpcwhitelistdefault=0"; + if [ -n "$RPC_TXRELAY_AUTH" ]; then + RPC_TXRELAY_FLAGS="$RPC_TXRELAY_FLAGS -rpcauth=$RPC_TXRELAY_AUTH -rpcwhitelist=txrelay:sendrawtransaction,testmempoolaccept,getmempoolinfo,getrawmempool,getmempoolentry,getnetworkinfo,getblockchaininfo,getblockcount,getblockhash,getblockheader,getrawtransaction,decoderawtransaction,decodescript,estimatesmartfee"; + fi; + if [ "${DISK_GB_VALUE:-0}" -lt 1000 ]; then + exec "$BITCOIND" -datadir=/home/bitcoin/.bitcoin -noconf -server=1 -prune=550 -rpcallowip=0.0.0.0/0 -rpcbind=0.0.0.0:8332 -listen=1 -bind=0.0.0.0:8333 -dbcache=1024 -par=0 -maxconnections=125 $RPC_HEADROOM $RPC_TXRELAY_FLAGS -rpcuser="$RPC_USER" -rpcpassword="$RPC_PASS"; else - exec "$BITCOIND" -datadir=/home/bitcoin/.bitcoin -noconf -server=1 -txindex=1 -rpcallowip=0.0.0.0/0 -rpcbind=0.0.0.0:8332 -listen=1 -bind=0.0.0.0:8333 -dbcache=4096 -par=0 -maxconnections=125 -rpcuser="${BITCOIN_RPC_USER}" -rpcpassword="${BITCOIN_RPC_PASS}"; + exec "$BITCOIND" -datadir=/home/bitcoin/.bitcoin -noconf -server=1 -txindex=1 -rpcallowip=0.0.0.0/0 -rpcbind=0.0.0.0:8332 -listen=1 -bind=0.0.0.0:8333 -dbcache=4096 -par=0 -maxconnections=125 $RPC_HEADROOM $RPC_TXRELAY_FLAGS -rpcuser="$RPC_USER" -rpcpassword="$RPC_PASS"; fi derived_env: - key: DISK_GB @@ -37,6 +46,8 @@ app: secret_env: - key: BITCOIN_RPC_PASS secret_file: bitcoin-rpc-password + - key: BITCOIN_RPC_TXRELAY_RPCAUTH + secret_file: bitcoin-rpc-txrelay-rpcauth data_uid: "100101:100101" dependencies: diff --git a/core/Cargo.lock b/core/Cargo.lock index cfddde2a..71b754b6 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -80,7 +80,7 @@ checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "archipelago" -version = "1.7.83-alpha" +version = "1.7.84-alpha" dependencies = [ "anyhow", "archipelago-container", diff --git a/core/archipelago/Cargo.toml b/core/archipelago/Cargo.toml index 77471852..4191fe21 100644 --- a/core/archipelago/Cargo.toml +++ b/core/archipelago/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "archipelago" -version = "1.7.83-alpha" +version = "1.7.84-alpha" edition = "2021" description = "Archipelago Bitcoin Node OS - Native backend" authors = ["Archipelago Team"] diff --git a/core/archipelago/src/api/rpc/bitcoin_relay.rs b/core/archipelago/src/api/rpc/bitcoin_relay.rs index 429489e7..4a29a170 100644 --- a/core/archipelago/src/api/rpc/bitcoin_relay.rs +++ b/core/archipelago/src/api/rpc/bitcoin_relay.rs @@ -3,6 +3,7 @@ use crate::container::docker_packages; use crate::data_model::{Notification, NotificationLevel}; use crate::{bitcoin_status, identity, peers}; use anyhow::{Context, Result}; +use archipelago_container::ContainerState; use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _}; use hmac::{Hmac, Mac}; use rand::RngCore; @@ -164,7 +165,11 @@ impl RpcHandler { update_endpoint(¶ms, "tor_endpoint", &mut state.settings.tor_endpoint)?; if state.settings.enabled_for_peers { + let credentials_were_ready = txrelay_credentials_available(&self.config.data_dir).await; ensure_txrelay_credentials(&self.config.data_dir).await?; + if !credentials_were_ready { + self.restart_bitcoin_backends_for_txrelay().await; + } } if params.get("selected_peer_pubkey").is_some() { @@ -354,7 +359,11 @@ impl RpcHandler { ); } let credentials = if status == RelayRequestStatus::Approved { - Some(ensure_txrelay_credentials(&self.config.data_dir).await?) + let credentials = ensure_txrelay_credentials(&self.config.data_dir).await?; + if request_direction == RelayRequestDirection::Incoming { + self.restart_bitcoin_backends_for_txrelay().await; + } + Some(credentials) } else { None }; @@ -476,6 +485,34 @@ impl RpcHandler { } self.state_manager.update_data(data).await; } + + async fn restart_bitcoin_backends_for_txrelay(&self) { + let Some(orchestrator) = self.orchestrator.as_ref().cloned() else { + tracing::debug!("Skipping txrelay backend restart; orchestrator unavailable"); + return; + }; + tokio::spawn(async move { + for app_id in ["bitcoin-knots", "bitcoin-core"] { + let Ok(status) = orchestrator.status(app_id).await else { + continue; + }; + if status.state != ContainerState::Running { + continue; + } + match orchestrator.restart(app_id).await { + Ok(()) => tracing::info!( + app_id, + "Restarted Bitcoin backend to load txrelay RPC credentials" + ), + Err(e) => tracing::warn!( + app_id, + error = %e, + "Failed to restart Bitcoin backend after txrelay credential update" + ), + } + } + }); + } } pub(crate) async fn record_incoming_relay_message( @@ -588,21 +625,29 @@ fn trusted_relay_peers( } async fn txrelay_credential_status(data_dir: &Path) -> serde_json::Value { + let credentials_available = txrelay_credentials_available(data_dir).await; let (password_path, rpcauth_path, client_env_path) = txrelay_secret_paths(data_dir); let password_available = fs::metadata(&password_path).await.is_ok(); let rpcauth_available = fs::metadata(&rpcauth_path).await.is_ok(); let client_env_available = fs::metadata(&client_env_path).await.is_ok(); json!({ "username": TXRELAY_USER, - "available": password_available && rpcauth_available && client_env_available, + "available": credentials_available, "password_available": password_available, "rpcauth_available": rpcauth_available, "client_env_available": client_env_available, "client_env_path": client_env_path.display().to_string(), - "restart_hint": "If this was just generated, restart Bitcoin Core/Knots so bitcoind loads the txrelay rpcauth whitelist.", + "restart_hint": "Archipelago restarts the active Bitcoin backend after generating txrelay credentials so bitcoind loads the restricted rpcauth whitelist.", }) } +async fn txrelay_credentials_available(data_dir: &Path) -> bool { + let (password_path, rpcauth_path, client_env_path) = txrelay_secret_paths(data_dir); + fs::metadata(&password_path).await.is_ok() + && fs::metadata(&rpcauth_path).await.is_ok() + && fs::metadata(&client_env_path).await.is_ok() +} + async fn ensure_txrelay_credentials(data_dir: &Path) -> Result { let (password_path, rpcauth_path, client_env_path) = txrelay_secret_paths(data_dir); let password = match read_trimmed(&password_path).await { diff --git a/core/archipelago/src/container/quadlet.rs b/core/archipelago/src/container/quadlet.rs index f0927472..45ecfde7 100644 --- a/core/archipelago/src/container/quadlet.rs +++ b/core/archipelago/src/container/quadlet.rs @@ -800,7 +800,7 @@ mod tests { QuadletUnit { name: "archy-bitcoin-ui".into(), description: "Bitcoin RPC UI proxy".into(), - image: "146.59.87.168:3000/lfg2025/bitcoin-ui:latest".into(), + image: "146.59.87.168:3000/lfg2025/bitcoin-ui:1.7.84-alpha".into(), network: NetworkMode::Host, user: Some("0:0".into()), memory_mb: Some(128), @@ -828,7 +828,7 @@ mod tests { let s = sample_unit().render(); assert!(s.contains("[Container]")); assert!(s.contains("ContainerName=archy-bitcoin-ui")); - assert!(s.contains("Image=146.59.87.168:3000/lfg2025/bitcoin-ui:latest")); + assert!(s.contains("Image=146.59.87.168:3000/lfg2025/bitcoin-ui:1.7.84-alpha")); assert!(s.contains("Pull=never")); assert!(s.contains("Network=host")); assert!(s.contains("DropCapability=ALL")); diff --git a/core/archipelago/src/server.rs b/core/archipelago/src/server.rs index dc1cafbc..d7500357 100644 --- a/core/archipelago/src/server.rs +++ b/core/archipelago/src/server.rs @@ -15,6 +15,7 @@ use hyper::server::conn::Http; use hyper::service::service_fn; use std::collections::HashMap; use std::net::SocketAddr; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::{Duration, Instant}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; @@ -28,6 +29,25 @@ pub struct Server { _state_manager: Arc, } +struct ContainerScanGuard<'a> { + scanning: &'a AtomicBool, +} + +impl<'a> ContainerScanGuard<'a> { + fn try_acquire(scanning: &'a AtomicBool) -> Option { + scanning + .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) + .ok() + .map(|_| Self { scanning }) + } +} + +impl Drop for ContainerScanGuard<'_> { + fn drop(&mut self) { + self.scanning.store(false, Ordering::Release); + } +} + impl Server { pub async fn new( config: Config, @@ -362,7 +382,7 @@ impl Server { // Skip missed ticks instead of catching up — prevents burst of scans // after a slow podman response (which causes DB lock storms) interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip); - let scanning = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)); + let scanning = std::sync::Arc::new(AtomicBool::new(false)); loop { tokio::select! { _ = interval.tick() => {} @@ -377,13 +397,12 @@ impl Server { continue; } } - if scanning.load(std::sync::atomic::Ordering::Relaxed) { + let Some(_scan_guard) = ContainerScanGuard::try_acquire(&scanning) else { debug!("Skipping container scan — previous scan still in progress"); scan_tick.send_modify(|n| *n = n.wrapping_add(1)); continue; - } - scanning.store(true, std::sync::atomic::Ordering::Relaxed); - if let Err(e) = scan_and_update_packages( + }; + let scan_result = scan_and_update_packages( &scanner, &state, identity_clone.as_ref(), @@ -391,8 +410,8 @@ impl Server { &mut absence_tracker, &mut transitional_since, ) - .await - { + .await; + if let Err(e) = scan_result { error!("Failed to update containers: {}", e); if is_podman_scan_timeout(&e) { scan_backoff_until = Some(Instant::now() + Duration::from_secs(30)); @@ -402,7 +421,6 @@ impl Server { scan_backoff_until = None; } scan_tick.send_modify(|n| *n = n.wrapping_add(1)); - scanning.store(false, std::sync::atomic::Ordering::Relaxed); } }); } diff --git a/neode-ui/package-lock.json b/neode-ui/package-lock.json index 78b9132b..4cf163b0 100644 --- a/neode-ui/package-lock.json +++ b/neode-ui/package-lock.json @@ -1,12 +1,12 @@ { "name": "neode-ui", - "version": "1.7.83-alpha", + "version": "1.7.84-alpha", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "neode-ui", - "version": "1.7.83-alpha", + "version": "1.7.84-alpha", "dependencies": { "@types/dompurify": "^3.0.5", "@vue-leaflet/vue-leaflet": "^0.10.1", diff --git a/neode-ui/package.json b/neode-ui/package.json index 94469940..f91fbbed 100644 --- a/neode-ui/package.json +++ b/neode-ui/package.json @@ -1,7 +1,7 @@ { "name": "neode-ui", "private": true, - "version": "1.7.83-alpha", + "version": "1.7.84-alpha", "type": "module", "scripts": { "start": "./start-dev.sh", diff --git a/neode-ui/src/views/settings/AccountInfoSection.vue b/neode-ui/src/views/settings/AccountInfoSection.vue index a28ed06b..b40e7653 100644 --- a/neode-ui/src/views/settings/AccountInfoSection.vue +++ b/neode-ui/src/views/settings/AccountInfoSection.vue @@ -188,6 +188,18 @@ init()
+ +
+
+ v1.7.84-alpha + June 11, 2026 +
+
+

Bitcoin trusted-node relay approvals now generate restricted txrelay credentials and restart the active Bitcoin backend so the new RPC whitelist is live.

+

Bitcoin Core now matches Bitcoin Knots for restricted relay RPC support, including txrelay secret injection and sendrawtransaction-focused permissions.

+

The Bitcoin UI companion image is pinned for OTA updates, and container scanning now avoids getting stuck busy after timeout or error paths.

+
+
diff --git a/release-manifest.json b/release-manifest.json index b1edf27f..fe35b704 100644 --- a/release-manifest.json +++ b/release-manifest.json @@ -1,31 +1,29 @@ { - "version": "1.7.83-alpha", + "version": "1.7.84-alpha", "release_date": "2026-06-11", "changelog": [ - "App launch metadata now derives more consistently from app manifests, with typed launch interfaces and catalog generation updates that keep packaged apps aligned with their runtime ports and launch surfaces.", - "Revoked or unsupported app surfaces were removed from the catalog and release path, including OnlyOffice and the unvalidated Saleor surface, so the Marketplace no longer exposes apps that cannot be safely supported in this release.", - "The frontend production build now passes strict TypeScript checks after tightening app details, Web5, cloud refresh, and credential test typing.", - "Mobile and desktop app surfaces received release polish: improved mobile app layout, safer mesh desktop/tablet scrolling, and the Home system card now routes directly to monitoring.", - "Bitcoin UI status rendering now avoids false stale/reconnecting states when fresh block snapshots advance, and guards optional DOM updates so the standalone Bitcoin UI is more resilient.", - "Deploy tooling now excludes local Codex scratch output, archived image-build artifacts, and upload screenshots from target syncs, and bounded optional IndeedHub fixups so a stuck Podman helper cannot hold the deploy.", - "Validation passed with `npm run type-check`, production `npm run build`, backend `cargo build --release`, catalog/release manifest checks, focused frontend tests, and live `.198` deploy verification through the frontend/service restart phase." + "Bitcoin trusted-node relay approvals now generate restricted `txrelay` RPC credentials when needed and restart the active Bitcoin backend so bitcoind loads the new `rpcauth` whitelist.", + "Bitcoin Core now matches Bitcoin Knots for restricted relay RPC support, including the txrelay secret injection and sendrawtransaction-focused whitelist.", + "The Bitcoin UI companion image is pinned to `1.7.84-alpha` across release metadata and the Quadlet fallback path, avoiding stale `latest` detection during OTA updates.", + "Container scanning now uses an RAII in-flight guard so timeout and error paths cannot leave the scanner stuck in a permanently busy state.", + "Validation passed with `cargo fmt`, `cargo check -p archipelago`, `git diff --check`, and focused source review of the relay message/approval path." ], "components": [ { "name": "archipelago", - "current_version": "1.7.83-alpha", - "new_version": "1.7.83-alpha", - "download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.83-alpha/archipelago", - "sha256": "cf1cfeadadb34ff7b7d786fbed1aa3ca035bac0b480d85fc740c5683ad613cf6", - "size_bytes": 43845952 + "current_version": "1.7.84-alpha", + "new_version": "1.7.84-alpha", + "download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.84-alpha/archipelago", + "sha256": "620743db2cb0839e56d126a8eac18612a1e54ea15ee6eb412a036f80d54717e7", + "size_bytes": 43891848 }, { - "name": "archipelago-frontend-1.7.83-alpha.tar.gz", - "current_version": "1.7.83-alpha", - "new_version": "1.7.83-alpha", - "download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.83-alpha/archipelago-frontend-1.7.83-alpha.tar.gz", - "sha256": "c8d21d9ee01497610dc460cbdc68ab30c6cd1544efc71308e29f7708f41f2f97", - "size_bytes": 184082906 + "name": "archipelago-frontend-1.7.84-alpha.tar.gz", + "current_version": "1.7.84-alpha", + "new_version": "1.7.84-alpha", + "download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.84-alpha/archipelago-frontend-1.7.84-alpha.tar.gz", + "sha256": "be9a572ee749d9f7f1f8a93a0bee96f30c58aa3ba245bc63763c07fdf000faf9", + "size_bytes": 184083908 } ] } diff --git a/releases/manifest.json b/releases/manifest.json index b1edf27f..fe35b704 100644 --- a/releases/manifest.json +++ b/releases/manifest.json @@ -1,31 +1,29 @@ { - "version": "1.7.83-alpha", + "version": "1.7.84-alpha", "release_date": "2026-06-11", "changelog": [ - "App launch metadata now derives more consistently from app manifests, with typed launch interfaces and catalog generation updates that keep packaged apps aligned with their runtime ports and launch surfaces.", - "Revoked or unsupported app surfaces were removed from the catalog and release path, including OnlyOffice and the unvalidated Saleor surface, so the Marketplace no longer exposes apps that cannot be safely supported in this release.", - "The frontend production build now passes strict TypeScript checks after tightening app details, Web5, cloud refresh, and credential test typing.", - "Mobile and desktop app surfaces received release polish: improved mobile app layout, safer mesh desktop/tablet scrolling, and the Home system card now routes directly to monitoring.", - "Bitcoin UI status rendering now avoids false stale/reconnecting states when fresh block snapshots advance, and guards optional DOM updates so the standalone Bitcoin UI is more resilient.", - "Deploy tooling now excludes local Codex scratch output, archived image-build artifacts, and upload screenshots from target syncs, and bounded optional IndeedHub fixups so a stuck Podman helper cannot hold the deploy.", - "Validation passed with `npm run type-check`, production `npm run build`, backend `cargo build --release`, catalog/release manifest checks, focused frontend tests, and live `.198` deploy verification through the frontend/service restart phase." + "Bitcoin trusted-node relay approvals now generate restricted `txrelay` RPC credentials when needed and restart the active Bitcoin backend so bitcoind loads the new `rpcauth` whitelist.", + "Bitcoin Core now matches Bitcoin Knots for restricted relay RPC support, including the txrelay secret injection and sendrawtransaction-focused whitelist.", + "The Bitcoin UI companion image is pinned to `1.7.84-alpha` across release metadata and the Quadlet fallback path, avoiding stale `latest` detection during OTA updates.", + "Container scanning now uses an RAII in-flight guard so timeout and error paths cannot leave the scanner stuck in a permanently busy state.", + "Validation passed with `cargo fmt`, `cargo check -p archipelago`, `git diff --check`, and focused source review of the relay message/approval path." ], "components": [ { "name": "archipelago", - "current_version": "1.7.83-alpha", - "new_version": "1.7.83-alpha", - "download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.83-alpha/archipelago", - "sha256": "cf1cfeadadb34ff7b7d786fbed1aa3ca035bac0b480d85fc740c5683ad613cf6", - "size_bytes": 43845952 + "current_version": "1.7.84-alpha", + "new_version": "1.7.84-alpha", + "download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.84-alpha/archipelago", + "sha256": "620743db2cb0839e56d126a8eac18612a1e54ea15ee6eb412a036f80d54717e7", + "size_bytes": 43891848 }, { - "name": "archipelago-frontend-1.7.83-alpha.tar.gz", - "current_version": "1.7.83-alpha", - "new_version": "1.7.83-alpha", - "download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.83-alpha/archipelago-frontend-1.7.83-alpha.tar.gz", - "sha256": "c8d21d9ee01497610dc460cbdc68ab30c6cd1544efc71308e29f7708f41f2f97", - "size_bytes": 184082906 + "name": "archipelago-frontend-1.7.84-alpha.tar.gz", + "current_version": "1.7.84-alpha", + "new_version": "1.7.84-alpha", + "download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.84-alpha/archipelago-frontend-1.7.84-alpha.tar.gz", + "sha256": "be9a572ee749d9f7f1f8a93a0bee96f30c58aa3ba245bc63763c07fdf000faf9", + "size_bytes": 184083908 } ] } diff --git a/scripts/image-versions.sh b/scripts/image-versions.sh index 2854770d..ba29d974 100644 --- a/scripts/image-versions.sh +++ b/scripts/image-versions.sh @@ -104,8 +104,7 @@ PENPOT_EXPORTER_IMAGE="$ARCHY_REGISTRY/penpot-exporter:2.4" PENPOT_FRONTEND_IMAGE="$ARCHY_REGISTRY/penpot-frontend:2.4" # Custom UI containers (built from docker/ dirs, pushed to registry) -# These use :latest because they're internally built and pushed — acceptable for self-hosted images -BITCOIN_UI_IMAGE="$ARCHY_REGISTRY/bitcoin-ui:latest" +BITCOIN_UI_IMAGE="$ARCHY_REGISTRY/bitcoin-ui:1.7.84-alpha" LND_UI_IMAGE="$ARCHY_REGISTRY/lnd-ui:latest" ELECTRS_UI_IMAGE="$ARCHY_REGISTRY/electrs-ui:latest"