Compare commits

..

No commits in common. "d91b858d9ba1cd3687d08d8dc4be6d4ca004c839" and "a992abcd06e549da5b01e8fa8186bcd90e1db13b" have entirely different histories.

7 changed files with 40 additions and 139 deletions

View File

@ -1,12 +1,5 @@
# Changelog # Changelog
## v1.7.62-alpha (2026-05-18)
- Nginx Proxy Manager start and restart now repair stale Podman containers that still publish the admin UI on host port `81`, which conflicts with host nginx on updated nodes.
- The repair recreates only the stale Nginx Proxy Manager container metadata while preserving `/var/lib/archipelago/nginx-proxy-manager` data and using the current `8081:81`, `8084:80`, and `8444:443` mappings.
- Runtime stale-listener cleanup for Nginx Proxy Manager is shared across start and restart paths so rootless port helper leftovers are still cleared before lifecycle retries.
- Validation passed with `cargo fmt --all --check --manifest-path core/Cargo.toml` and `cargo check -p archipelago --manifest-path core/Cargo.toml`.
## v1.7.61-alpha (2026-05-18) ## v1.7.61-alpha (2026-05-18)
- Multi-container stack installs now keep their app card in the `Installing` state for up to 20 minutes while dependency containers are being pulled and prepared. - Multi-container stack installs now keep their app card in the `Installing` state for up to 20 minutes while dependency containers are being pulled and prepared.

View File

@ -1,6 +1,6 @@
[package] [package]
name = "archipelago" name = "archipelago"
version = "1.7.62-alpha" version = "1.7.61-alpha"
edition = "2021" edition = "2021"
description = "Archipelago Bitcoin Node OS - Native backend" description = "Archipelago Bitcoin Node OS - Native backend"
authors = ["Archipelago Team"] authors = ["Archipelago Team"]

View File

@ -1,7 +1,4 @@
use super::config::{ use super::config::{get_containers_for_app, get_data_dirs_for_app, is_valid_docker_image};
get_app_capabilities, get_containers_for_app, get_data_dirs_for_app, get_health_check_args,
get_memory_limit, is_valid_docker_image,
};
use super::dependencies::ordered_containers_for_start; use super::dependencies::ordered_containers_for_start;
use super::install::install_log; use super::install::install_log;
use super::validation::validate_app_id; use super::validation::validate_app_id;
@ -866,98 +863,11 @@ async fn repair_before_package_start(container_name: &str) {
repair_nextcloud_dirs().await; repair_nextcloud_dirs().await;
cleanup_stale_pasta_port("8085").await; cleanup_stale_pasta_port("8085").await;
} }
"nginx-proxy-manager" => repair_nginx_proxy_manager_container().await,
"gitea" => cleanup_gitea_stale_ports().await, "gitea" => cleanup_gitea_stale_ports().await,
_ => {} _ => {}
} }
} }
async fn repair_nginx_proxy_manager_container() {
if !nginx_proxy_manager_has_legacy_admin_port().await {
cleanup_nginx_proxy_manager_ports().await;
return;
}
install_log(
"START REPAIR: nginx-proxy-manager - recreating stale container using host port 8081",
)
.await;
let _ = podman_control(&["rm", "-f", "nginx-proxy-manager"]).await;
cleanup_nginx_proxy_manager_ports().await;
if let Err(err) = recreate_nginx_proxy_manager_container().await {
tracing::warn!(error = %err, "failed to recreate stale nginx-proxy-manager container");
}
}
async fn nginx_proxy_manager_has_legacy_admin_port() -> bool {
let Ok(output) = podman_control(&["port", "nginx-proxy-manager", "81/tcp"]).await else {
return false;
};
if !output.status.success() {
return false;
}
String::from_utf8_lossy(&output.stdout).lines().any(|line| {
line.rsplit(':')
.next()
.is_some_and(|port| port.trim() == "81")
})
}
async fn recreate_nginx_proxy_manager_container() -> Result<()> {
tokio::process::Command::new("sudo")
.args([
"mkdir",
"-p",
"/var/lib/archipelago/nginx-proxy-manager/data",
"/var/lib/archipelago/nginx-proxy-manager/letsencrypt",
])
.output()
.await
.context("failed to create nginx-proxy-manager data directories")?;
let image = crate::container::image_versions::pinned_image_for_app("nginx-proxy-manager")
.unwrap_or_else(|| "docker.io/jc21/nginx-proxy-manager:latest".to_string());
let mut args = vec![
"run".to_string(),
"-d".to_string(),
"--name".to_string(),
"nginx-proxy-manager".to_string(),
"--restart=unless-stopped".to_string(),
"--network=slirp4netns:allow_host_loopback=true".to_string(),
"--cap-drop=ALL".to_string(),
"--security-opt=no-new-privileges:true".to_string(),
"--pids-limit=4096".to_string(),
];
args.extend(get_app_capabilities("nginx-proxy-manager"));
args.extend([
"-p".to_string(),
"8081:81".to_string(),
"-p".to_string(),
"8084:80".to_string(),
"-p".to_string(),
"8444:443".to_string(),
"-v".to_string(),
"/var/lib/archipelago/nginx-proxy-manager/data:/data".to_string(),
"-v".to_string(),
"/var/lib/archipelago/nginx-proxy-manager/letsencrypt:/etc/letsencrypt".to_string(),
"--memory".to_string(),
get_memory_limit("nginx-proxy-manager").to_string(),
"--cpus=2".to_string(),
]);
args.extend(get_health_check_args("nginx-proxy-manager", ""));
args.push(image);
let refs = args.iter().map(String::as_str).collect::<Vec<_>>();
let output = podman_control(&refs).await?;
if !output.status.success() {
anyhow::bail!(
"podman run nginx-proxy-manager failed: {}",
String::from_utf8_lossy(&output.stderr).trim()
);
}
Ok(())
}
async fn ensure_runtime_host_port_listener(container_name: &str) -> Result<()> { async fn ensure_runtime_host_port_listener(container_name: &str) -> Result<()> {
let Some(port) = runtime_required_host_port(container_name) else { let Some(port) = runtime_required_host_port(container_name) else {
return Ok(()); return Ok(());
@ -1165,17 +1075,15 @@ async fn cleanup_start_conflict(container_name: &str, stderr: &str) {
"homeassistant" | "home-assistant" => cleanup_stale_pasta_port("8123").await, "homeassistant" | "home-assistant" => cleanup_stale_pasta_port("8123").await,
"vaultwarden" => cleanup_stale_pasta_port("8082").await, "vaultwarden" => cleanup_stale_pasta_port("8082").await,
"nextcloud" => cleanup_stale_pasta_port("8085").await, "nextcloud" => cleanup_stale_pasta_port("8085").await,
"nginx-proxy-manager" => cleanup_nginx_proxy_manager_ports().await, "nginx-proxy-manager" => {
cleanup_stale_pasta_port("8081").await;
cleanup_stale_pasta_port("8084").await;
cleanup_stale_pasta_port("8444").await;
}
_ => {} _ => {}
} }
} }
async fn cleanup_nginx_proxy_manager_ports() {
cleanup_stale_pasta_port("8081").await;
cleanup_stale_pasta_port("8084").await;
cleanup_stale_pasta_port("8444").await;
}
async fn cleanup_stale_pasta_port(port: &str) { async fn cleanup_stale_pasta_port(port: &str) {
let kill_listener = format!( let kill_listener = format!(
"ss -ltnp 'sport = :{}' 2>/dev/null | sed -n 's/.*pid=\\([0-9]*\\).*/\\1/p' | xargs -r kill 2>/dev/null || true", "ss -ltnp 'sport = :{}' 2>/dev/null | sed -n 's/.*pid=\\([0-9]*\\).*/\\1/p' | xargs -r kill 2>/dev/null || true",

View File

@ -1,12 +1,12 @@
{ {
"name": "neode-ui", "name": "neode-ui",
"version": "1.7.62-alpha", "version": "1.7.61-alpha",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "neode-ui", "name": "neode-ui",
"version": "1.7.62-alpha", "version": "1.7.61-alpha",
"dependencies": { "dependencies": {
"@types/dompurify": "^3.0.5", "@types/dompurify": "^3.0.5",
"@vue-leaflet/vue-leaflet": "^0.10.1", "@vue-leaflet/vue-leaflet": "^0.10.1",

View File

@ -1,7 +1,7 @@
{ {
"name": "neode-ui", "name": "neode-ui",
"private": true, "private": true,
"version": "1.7.62-alpha", "version": "1.7.61-alpha",
"type": "module", "type": "module",
"scripts": { "scripts": {
"start": "./start-dev.sh", "start": "./start-dev.sh",

View File

@ -1,28 +1,28 @@
{ {
"version": "1.7.62-alpha", "version": "1.7.61-alpha",
"release_date": "2026-05-17", "release_date": "2026-05-18",
"changelog": [ "changelog": [
"Nginx Proxy Manager start and restart now repair stale Podman containers that still publish the admin UI on host port `81`, which conflicts with host nginx on updated nodes.", "Multi-container stack installs now keep their app card in the `Installing` state for up to 20 minutes while dependency containers are being pulled and prepared.",
"The repair recreates only the stale Nginx Proxy Manager container metadata while preserving `/var/lib/archipelago/nginx-proxy-manager` data and using the current `8081:81`, `8084:80`, and `8444:443` mappings.", "BTCPay Server installs no longer appear to vanish or fail after two minutes while Postgres and NBXplorer are still being created before the primary `btcpay-server` container exists.",
"Runtime stale-listener cleanup for Nginx Proxy Manager is shared across start and restart paths so rootless port helper leftovers are still cleared before lifecycle retries.", "The stale-transition escape hatch remains short for start, stop, restart, update, and removal operations, so genuinely wedged lifecycle actions still recover quickly.",
"Validation passed with `cargo fmt --all --check --manifest-path core/Cargo.toml` and `cargo check -p archipelago --manifest-path core/Cargo.toml`." "Live validation on `100.70.96.88` confirmed BTCPay Server completed installation and responds on port `23000` with the expected HTTP redirect."
], ],
"components": [ "components": [
{ {
"name": "archipelago", "name": "archipelago",
"current_version": "1.7.62-alpha", "current_version": "1.7.61-alpha",
"new_version": "1.7.62-alpha", "new_version": "1.7.61-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.62-alpha/archipelago", "download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.61-alpha/archipelago",
"sha256": "5b08f66aa9a685475b86cdcbabe96c3132f3cc0e72d8daaeb0ddd52a01ca87b6", "sha256": "5b08f66aa9a685475b86cdcbabe96c3132f3cc0e72d8daaeb0ddd52a01ca87b6",
"size_bytes": 42738544 "size_bytes": 42738544
}, },
{ {
"name": "archipelago-frontend-1.7.62-alpha.tar.gz", "name": "archipelago-frontend-1.7.61-alpha.tar.gz",
"current_version": "1.7.62-alpha", "current_version": "1.7.61-alpha",
"new_version": "1.7.62-alpha", "new_version": "1.7.61-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.62-alpha/archipelago-frontend-1.7.62-alpha.tar.gz", "download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.61-alpha/archipelago-frontend-1.7.61-alpha.tar.gz",
"sha256": "5923368c4cd00cfcc40c0fc2eccc9d086b5ff450ae9da3e09bede48d434dc95e", "sha256": "80c5bef31460ece8c1416a8f4e5e88626d1ef4103d40fec0e4872aafb3332dcc",
"size_bytes": 166467764 "size_bytes": 166470847
} }
] ]
} }

View File

@ -1,28 +1,28 @@
{ {
"version": "1.7.62-alpha", "version": "1.7.61-alpha",
"release_date": "2026-05-17", "release_date": "2026-05-18",
"changelog": [ "changelog": [
"Nginx Proxy Manager start and restart now repair stale Podman containers that still publish the admin UI on host port `81`, which conflicts with host nginx on updated nodes.", "Multi-container stack installs now keep their app card in the `Installing` state for up to 20 minutes while dependency containers are being pulled and prepared.",
"The repair recreates only the stale Nginx Proxy Manager container metadata while preserving `/var/lib/archipelago/nginx-proxy-manager` data and using the current `8081:81`, `8084:80`, and `8444:443` mappings.", "BTCPay Server installs no longer appear to vanish or fail after two minutes while Postgres and NBXplorer are still being created before the primary `btcpay-server` container exists.",
"Runtime stale-listener cleanup for Nginx Proxy Manager is shared across start and restart paths so rootless port helper leftovers are still cleared before lifecycle retries.", "The stale-transition escape hatch remains short for start, stop, restart, update, and removal operations, so genuinely wedged lifecycle actions still recover quickly.",
"Validation passed with `cargo fmt --all --check --manifest-path core/Cargo.toml` and `cargo check -p archipelago --manifest-path core/Cargo.toml`." "Live validation on `100.70.96.88` confirmed BTCPay Server completed installation and responds on port `23000` with the expected HTTP redirect."
], ],
"components": [ "components": [
{ {
"name": "archipelago", "name": "archipelago",
"current_version": "1.7.62-alpha", "current_version": "1.7.61-alpha",
"new_version": "1.7.62-alpha", "new_version": "1.7.61-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.62-alpha/archipelago", "download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.61-alpha/archipelago",
"sha256": "5b08f66aa9a685475b86cdcbabe96c3132f3cc0e72d8daaeb0ddd52a01ca87b6", "sha256": "5b08f66aa9a685475b86cdcbabe96c3132f3cc0e72d8daaeb0ddd52a01ca87b6",
"size_bytes": 42738544 "size_bytes": 42738544
}, },
{ {
"name": "archipelago-frontend-1.7.62-alpha.tar.gz", "name": "archipelago-frontend-1.7.61-alpha.tar.gz",
"current_version": "1.7.62-alpha", "current_version": "1.7.61-alpha",
"new_version": "1.7.62-alpha", "new_version": "1.7.61-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.62-alpha/archipelago-frontend-1.7.62-alpha.tar.gz", "download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.61-alpha/archipelago-frontend-1.7.61-alpha.tar.gz",
"sha256": "5923368c4cd00cfcc40c0fc2eccc9d086b5ff450ae9da3e09bede48d434dc95e", "sha256": "80c5bef31460ece8c1416a8f4e5e88626d1ef4103d40fec0e4872aafb3332dcc",
"size_bytes": 166467764 "size_bytes": 166470847
} }
] ]
} }