diff --git a/core/archipelago/src/container/companion.rs b/core/archipelago/src/container/companion.rs index 96809dd2..d861046c 100644 --- a/core/archipelago/src/container/companion.rs +++ b/core/archipelago/src/container/companion.rs @@ -285,7 +285,15 @@ async fn ensure_image_present(spec: &CompanionSpec) -> Result { async fn image_exists(image: &str) -> bool { let mut cmd = Command::new("podman"); - cmd.args(["image", "inspect", image]); + // Only the exit status matters. WITHOUT a `--format`, `podman image inspect` + // prints the image's full multi-KB manifest JSON; `.status()` inherits the + // service's stdout, so on a hit that whole blob lands in the journal — once + // per companion image, every reconcile pass. That flood spikes journald + + // IO and starves the async runtime (UI websocket then drops → "connection + // lost"/reconnect). Discard the child's stdout/stderr; we read neither. + cmd.args(["image", "inspect", image]) + .stdout(std::process::Stdio::null()) + .stderr(std::process::Stdio::null()); match tokio::time::timeout(COMPANION_IMAGE_CHECK_TIMEOUT, cmd.status()).await { Ok(Ok(status)) => status.success(), Ok(Err(err)) => {