diff --git a/scripts/deploy.mjs b/scripts/deploy.mjs index d9443c1..0fa171f 100644 --- a/scripts/deploy.mjs +++ b/scripts/deploy.mjs @@ -41,6 +41,21 @@ async function waitForHealth(container, timeoutMs = 90_000) { throw new Error("Timed out waiting for candidate health check"); } +async function reportContainerFailure(container) { + try { + const state = await container.inspect(); + console.error(`Candidate status: ${state.State.Status}; health: ${state.State.Health?.Status || "unavailable"}`); + for (const check of state.State.Health?.Log?.slice(-3) || []) { + const output = check.Output?.trim(); + if (output) console.error(`Health check: ${output}`); + } + const logs = await container.logs({ stdout: true, stderr: true, tail: 100 }); + if (logs.length) console.error(`Candidate logs:\n${logs.toString("utf8")}`); + } catch (diagnosticError) { + console.error(`Could not read candidate diagnostics: ${diagnosticError.message}`); + } +} + async function followBuild(stream) { const output = await new Promise((resolve, reject) => { docker.modem.followProgress(stream, (error, events) => error ? reject(error) : resolve(events), (event) => { @@ -93,7 +108,10 @@ try { if (hasCurrent) await removeContainer(previous); console.log(`Deployed ${image} on port ${port}`); } catch (error) { - if (next) await removeContainer(candidate).catch(() => undefined); + if (next) { + await reportContainerFailure(next); + await removeContainer(candidate).catch(() => undefined); + } if (hasCurrent) { const rollback = docker.getContainer(previous); await rollback.rename({ name: service });