Skip to content

Docker container leaks zombie chrome-headless processes (no init/reaper) #477

Description

@manoj1919

Bug: Docker container leaks zombie chrome-headless processes (no init/reaper)

Description

When the server runs in Docker as a long-lived process, exited Chromium subprocesses accumulate as zombie (<defunct>) processes and never get reaped. Over a multi-day-lived container these pile up.

Steps to reproduce

  1. Run the published image as a long-running service, e.g. streamable-http:
    docker run -d --name linkedin-mcp \
      -v ~/.linkedin-mcp:/home/pwuser/.linkedin-mcp \
      stickerdaniel/linkedin-mcp-server:latest \
      --transport streamable-http --host 0.0.0.0 --port 8080 --path /mcp
  2. Issue a few scraping calls so the bridge/scrape flow launches Chromium.
  3. Inspect the container's process tree:
    docker top linkedin-mcp
    # or, on the host:
    ps -ef | grep defunct

Observed

Several [chrome-headless] <defunct> processes parented to the Python PID, e.g.:

python(1)-+-chrome-headless(...)   <- Z (zombie)
          |-chrome-headless(...)   <- Z (zombie)
          ...

In my case 4 zombies appeared within ~20s of the first request and sat there for 9 days.

Root cause

Dockerfile sets ENTRYPOINT ["python", "-m", "linkedin_mcp_server"], so Python runs as PID 1. When Patchright/Chromium helper processes exit, the kernel reparents them to PID 1, but Python never calls waitpid() (no SIGCHLD handler / asyncio child watcher), so they remain as zombies forever. On a normal host this is invisible because real init reaps orphans; inside a container with no init, only PID 1 can reap and Python doesn't.

Proposed fix

Add a minimal init (tini) as the entrypoint so PID 1 reaps orphaned subprocesses:

RUN apt-get update && apt-get install -y --no-install-recommends tini && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["tini", "--", "python", "-m", "linkedin_mcp_server"]

This fixes the published image for all consumers, including plain docker run users (i.e. without relying on docker run --init / compose init: true).

Environment

  • Image: stickerdaniel/linkedin-mcp-server:latest
  • Transport: streamable-http
  • Host: Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions