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.