diff --git a/CHANGELOG.md b/CHANGELOG.md index cacb2e9f..f4c0c9e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## v1.7.66-alpha (2026-05-18) + +- Nginx Proxy Manager stale-port repair now detects stopped or `Created` Podman records by inspecting `podman ps -a` port metadata, covering records where `podman port nginx-proxy-manager` returns no mapping until start. +- Live recovery on `100.70.96.88` removed only the stale Nginx Proxy Manager container record and recreated it with `8081:81`, `8084:80`, and `8444:443`, preserving `/var/lib/archipelago/nginx-proxy-manager` data. +- Validation confirmed Nginx Proxy Manager recovered as healthy and responds through direct admin port `8081`, host compatibility port `81`, and `/app/nginx-proxy-manager/`. + ## v1.7.65-alpha (2026-05-18) - Orchestrator-backed app starts now run the same pre-start repairs as the legacy Podman path, so Nginx Proxy Manager stale `81:81` container metadata is removed and recreated before the orchestrator tries to start it. diff --git a/core/archipelago/src/api/rpc/package/runtime.rs b/core/archipelago/src/api/rpc/package/runtime.rs index 07fe8bd6..0048f88c 100644 --- a/core/archipelago/src/api/rpc/package/runtime.rs +++ b/core/archipelago/src/api/rpc/package/runtime.rs @@ -891,17 +891,35 @@ async fn repair_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 { + if let Ok(output) = podman_control(&["port", "nginx-proxy-manager", "81/tcp"]).await { + if output.status.success() + && String::from_utf8_lossy(&output.stdout).lines().any(|line| { + line.rsplit(':') + .next() + .is_some_and(|port| port.trim() == "81") + }) + { + return true; + } + } + + let Ok(output) = podman_control(&[ + "ps", + "-a", + "--format", + "{{.Ports}}", + "--filter", + "name=^nginx-proxy-manager$", + ]) + .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") - }) + let ports = String::from_utf8_lossy(&output.stdout); + ports.contains(":81->81/tcp") || ports.contains(":8443->443/tcp") } async fn recreate_nginx_proxy_manager_container() -> Result<()> {