TryGhost/Ghost · critical · Error

Ghost container stopped during initialization

Error message

Ghost container stopped during initialization

What it means

The container exited (info.State.Running is false) during the readiness window — it didn't go unhealthy, it stopped outright. Ghost process crashed or was OOM-killed. The manager dumps 100 log lines at error and aborts. Distinct from 105: unhealthy = running but failing probe; stopped = process gone.

Source

Thrown at e2e/helpers/environment/service-managers/ghost-manager.ts:510

            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');
    }

    private async probeHostReadiness(): Promise<boolean> {
        const controller = new AbortController();
        const timeout = setTimeout(() => controller.abort(), 500);

View on GitHub (pinned to 47d8b0e2ad)

Solutions

  1. Inspect the dumped logs for the exit cause; also docker inspect <id> and check State.OOMKilled and State.ExitCode.
  2. If OOMKilled, raise Docker memory limits / use a smaller config.
  3. Confirm dependencies (MySQL, gateway) are up before Ghost starts; check startup ordering in the manager.
  4. Rebuild the image if a code change introduced a crash on boot.

Example fix

// diagnostic
const info = await container.inspect();
console.log({oom: info.State.OOMKilled, exitCode: info.State.ExitCode});
// Raise memory or fix the boot crash indicated by the logs.
Defensive patterns

Strategy: try-catch

Validate before calling

const info = await container.inspect();
if (!info.State.Running) {
    throw new Error(`Pre-flight: container not running (OOMKilled=${info.State.OOMKilled}, exit=${info.State.ExitCode})`);
}

Try / catch

try {
    await ghostManager.waitForReady();
} catch (e) {
    if (!container) throw e;
    const info = await container.inspect();
    if (!info.State.Running) {
        throw new Error(`Ghost exited during init (OOMKilled=${info.State.OOMKilled}, exitCode=${info.State.ExitCode})`, {cause: e});
    }
    throw e;
}

Prevention

When it happens

Trigger: Ghost process threw an unrecoverable error and exited. Container hit a memory limit (OOMKilled). A start dependency (DB) vanished so Ghost exited. The entrypoint script ran exit on a failed preflight.

Common situations: Insufficient memory on the Docker host (OOMKilled); missing required env var causing immediate exit; DB connection refused at boot and Ghost gives up; image entrypoint bug after a rebuild.

Related errors


AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13). Data as JSON: /api/errors/259e506be3f92c49. Report an issue: GitHub.