Why do some Playwright checks fail with a `connect_over_cdp` timeout after a host reboot?

I’m running changedetection.io with Playwright in Docker. After I reboot my Ubuntu host and start the Docker Compose setup, some checks randomly fail with this error:

Exception: BrowserType.connect_over_cdp: Timeout 60000ms exceeded. Call log: ws://playwright-chrome:3000/

Here’s part of my docker-compose.yml:

services:
  changedetection:
    image: ghcr.io/dgtlmoon/changedetection.io:dev
    environment:
      - PLAYWRIGHT_DRIVER_URL=ws://playwright-chrome:3000

  playwright-chrome:
    image: dgtlmoon/sockpuppetbrowser:latest
    environment:
      - MAX_CONCURRENT_CHROME_PROCESSES=10

If I manually restart the containers after the initial startup post-reboot, the error doesn’t occur.

How can I make connect_over_cdp reliable even after a host reboot?

I ran into this exact issue with Playwright and Docker.

After a host reboot, the connect_over_cdp call sometimes times out because the browser container (playwright-chrome) isn’t fully ready when the main app tries to connect.

What worked for me was adding a simple wait-for-ready script or using depends_on with healthchecks in Docker Compose:

services:
  changedetection:
    depends_on:
      playwright-chrome:
        condition: service_healthy

  playwright-chrome:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000"]
      interval: 5s
      retries: 10

This ensures your main service only attempts connect_over_cdp after the browser is fully listening.

Instead of relying only on Docker startup order, I wrapped my connect_over_cdp call in a small retry loop.

After a host reboot, it occasionally takes longer than 60s for Chrome to be ready, so retrying a few times fixed random failures:

for _ in range(5):
    try:
        browser = await playwright.chromium.connect_over_cdp(driver_url)
        break
    except TimeoutError:
        await asyncio.sleep(5)
else:
    raise RuntimeError("Failed to connect to browser")

This is lightweight and works even if the container starts slowly after a reboot.

In my setup, a host reboot caused network stack and Docker startup delays.

Simply increasing the timeout can help in addition to depends_on:

browser = await playwright.chromium.connect_over_cdp(
    "ws://playwright-chrome:3000", timeout=120000
)

Combined with healthchecks, this made the connection almost 100% reliable.