feat: bitcoin-ui CSS fix, HTTPS proxy support, deploy script improvements

Bitcoin UI:
- Replace cdn.tailwindcss.com with locally bundled tailwind.css (CSP blocks external scripts)
- Make all asset paths relative for nginx proxy compatibility
- Add bitcoin-ui build/deploy to deploy-to-target.sh (was missing entirely)
- Use --network host (bitcoin-ui proxies Bitcoin RPC at 127.0.0.1:8332)

HTTPS mixed content fix:
- Add HTTPS_PROXY_PATHS in AppSession.vue — when parent page is HTTPS,
  iframe loads through nginx proxy instead of direct HTTP port
- Prevents browser blocking HTTP iframes inside HTTPS pages
- All Tailscale servers use HTTPS, this was breaking all app iframes

Deploy & first-boot improvements:
- first-boot-containers.sh auto-detects disk size for pruning vs txindex
- first-boot-containers.sh checks fallback source path for UI containers
- Added mempool-electrs to APP_PORTS mapping
- ElectrumX container creation in first-boot
- Podman doctor/fix/uptime skills added

Also includes: session persistence, identity management, LND transactions,
ElectrumX status UI, nostr-provider improvements, Web5 enhancements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-16 12:58:35 +00:00
parent 4e54b8bd4d
commit 367b483a72
49 changed files with 6180 additions and 495 deletions

View File

@@ -66,6 +66,41 @@ impl PodmanClient {
}
}
/// Map container name to its UI launch URL
fn lan_address_for(name: &str) -> Option<String> {
let url = match name {
"bitcoin-knots" | "bitcoin-ui" => "http://localhost:8334",
"lnd" | "archy-lnd-ui" => "http://localhost:8081",
"tailscale" => "http://localhost:8240",
"homeassistant" => "http://localhost:8123",
"archy-mempool-web" | "mempool" => "http://localhost:4080",
"btcpay-server" => "http://localhost:23000",
"grafana" => "http://localhost:3000",
"searxng" => "http://localhost:8888",
"ollama" => "http://localhost:11434",
"onlyoffice" => "http://localhost:9980",
"penpot" => "http://localhost:9001",
"nextcloud" => "http://localhost:8085",
"vaultwarden" => "http://localhost:8082",
"jellyfin" => "http://localhost:8096",
"photoprism" => "http://localhost:2342",
"immich_server" | "immich" => "http://localhost:2283",
"filebrowser" => "http://localhost:8083",
"nginx-proxy-manager" => "http://localhost:81",
"portainer" => "http://localhost:9000",
"uptime-kuma" => "http://localhost:3001",
"fedimint" => "http://localhost:8175",
"fedimint-gateway" => "http://localhost:8176",
"nostr-rs-relay" => "http://localhost:18081",
"indeedhub" => "http://localhost:7777",
"dwn" => "http://localhost:3100",
"endurain" => "http://localhost:8080",
"electrs" | "archy-electrs-ui" => "http://localhost:50002",
_ => return None,
};
Some(url.to_string())
}
fn podman_async(&self) -> TokioCommand {
// Always use sudo podman to access system-wide containers
let mut cmd = TokioCommand::new("sudo");
@@ -348,6 +383,7 @@ impl PodmanClient {
vec![]
};
let lan_address = Self::lan_address_for(&name);
result.push(ContainerStatus {
id: container["Id"].as_str().unwrap_or("").to_string(),
name,
@@ -355,7 +391,7 @@ impl PodmanClient {
image: container["Image"].as_str().unwrap_or("").to_string(),
created: container["Created"].as_str().unwrap_or("").to_string(),
ports,
lan_address: None, // Set by docker_packages scanner
lan_address,
});
}
} else {
@@ -365,7 +401,7 @@ impl PodmanClient {
if line.trim().is_empty() {
continue;
}
if let Ok(container) = serde_json::from_str::<serde_json::Value>(line) {
// Handle both Names as array and Names as string
let name = if let Some(names_array) = container["Names"].as_array() {
@@ -373,7 +409,7 @@ impl PodmanClient {
} else {
container["Names"].as_str().unwrap_or("").to_string()
};
// Parse ports from the Ports array
let ports = if let Some(ports_array) = container["Ports"].as_array() {
ports_array.iter().filter_map(|port| {
@@ -390,7 +426,8 @@ impl PodmanClient {
} else {
vec![]
};
let lan_address = Self::lan_address_for(&name);
result.push(ContainerStatus {
id: container["Id"].as_str().unwrap_or("").to_string(),
name,
@@ -398,7 +435,7 @@ impl PodmanClient {
image: container["Image"].as_str().unwrap_or("").to_string(),
created: container["Created"].as_str().unwrap_or("").to_string(),
ports,
lan_address: None, // Set by docker_packages scanner
lan_address,
});
}
}