TryGhost/Ghost · critical · Error
Ghost container became unhealthy during initialization
Error message
Ghost container became unhealthy during initialization
What it means
During the readiness loop, the container's State.Health.Status is 'unhealthy' — Docker's HEALTHCHECK (defined in the Ghost image) marked the container failing. The manager dumps the last 100 log lines at error level and aborts initialization. This is a real Ghost-side failure: the process is running but the health probe (typically an HTTP check against /ghost/api/) is failing.
Source
Thrown at e2e/helpers/environment/service-managers/ghost-manager.ts:504
}
private async waitForHostReadiness(container: Container, timeoutMs: number): Promise<void> {
const startTime = Date.now();
while (Date.now() - startTime < timeoutMs) {
const info = await container.inspect();
const health = info.State.Health;
const status = health?.Status;
if (info.State.Running && await this.probeHostReadiness()) {
debug('Host readiness probe passed');
return;
}
if (status === 'unhealthy') {
const logs = await container.logs({stdout: true, stderr: true, tail: 100});
logging.error(`Container became unhealthy:\n${logs.toString()}`);
throw new Error('Ghost container became unhealthy during initialization');
}
if (!info.State.Running) {
const logs = await container.logs({stdout: true, stderr: true, tail: 100});
logging.error(`Container stopped unexpectedly:\n${logs.toString()}`);
throw new Error('Ghost container stopped during initialization');
}
// Still starting - wait and check again
await new Promise((r) => {
setTimeout(r, READINESS_POLL_INTERVAL_MS);
});
}
// Timeout
const logs = await container.logs({stdout: true, stderr: true, tail: 100});
logging.error(`Timeout waiting for container. Last logs:\n${logs.toString()}`);
throw new Error('Timeout waiting for Ghost to become ready');View on GitHub (pinned to 47d8b0e2ad)
Solutions
- Read the dumped container logs (last 100 lines) — the actual Ghost bootstrap error is there.
- Verify the database name and MySQL container are reachable from Ghost; check database__connection__* env values.
- Confirm the url env matches the gateway port and uses http://localhost:<getGatewayPort()>.
- Rebuild/re-pull the Ghost image if a code/config change broke boot; check for migration errors in logs.
Example fix
# before (opaque failure) # Error: Ghost container became unhealthy during initialization # after # Capture and surface logs proactively: docker logs <ghost-container> --tail 200 # Then fix the root cause shown (e.g. bad DB name, bad url env).
Defensive patterns
Strategy: try-catch
Validate before calling
// Before relying on the container, pre-flight the health:
const info = await container.inspect();
if (info.State.Health?.Status === 'unhealthy') {
const logs = (await container.logs({stdout:true, stderr:true, tail: 100})).toString('utf8');
throw new Error(`Refusing to start — Ghost unhealthy pre-check:\n${logs}`);
} Try / catch
try {
await ghostManager.waitForReady();
} catch (e) {
const logs = (await container.logs({stdout:true, stderr:true, tail: 200})).toString('utf8');
throw new Error(`Ghost readiness failed; logs:\n${logs}`, {cause: e});
} Prevention
- Always surface the dumped container logs when this fires — the real bootstrap error is there.
- Validate database name, url env, and DB reachability before starting Ghost.
- Use a migrated seed image to avoid migration-time bootstrap failures.
When it happens
Trigger: Ghost started but crashed during bootstrap (DB migration failure, bad config, missing env var, port conflict). The image's HEALTHCHECK endpoint is unreachable because Ghost errored on boot. A corrupt database or invalid url/config caused the admin API to never come up.
Common situations: Wrong database__connection__database pointing at a missing/corrupt DB; invalid url env (not http://localhost:port); a Ghost start-up exception (visible in the dumped logs); incompatible Ghost version vs config; port already bound by another container.
Related errors
- Ghost container stopped during initialization
- Egress monitor sidecar did not start in time
- Egress monitor container has no network IP
- Build image not found: ${BUILD_IMAGE}\n\nYou are running in
- Build gateway image not found: ${BUILD_GATEWAY_IMAGE}\n\nTo
AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13).
Data as JSON: /api/errors/f9194def8eedc88c.
Report an issue: GitHub.