Skip to content

Chromium seems to crash when running on Ubuntu in Docker #41

@dleber

Description

@dleber

Firstly, thank you for this repo. I love that the stealthiness is implemented in the binary and that it integrates so seamlessly with Playwright/Pupeteer. I'll be inquiring about extra profiles as soon as I get this working.

I'm hitting an issue when running in an Ubuntu Docker container, details are below:

Setup

Host: Mac M2

Docker image largely taken from Playright's repo. I've modified it to install BotBrowser at the end.

FROM ubuntu:noble

ARG DEBIAN_FRONTEND=noninteractive
ARG TZ=America/Los_Angeles
ARG DOCKER_IMAGE_NAME_TEMPLATE="mcr.microsoft.com/playwright/python:v%version%-noble"

# Install Python
RUN apt-get update && \
    apt-get install -y python3 curl && \
    rm /usr/lib/python3.12/EXTERNALLY-MANAGED && \
    update-alternatives --install /usr/bin/python python /usr/bin/python3 1 && \
    curl -sSL https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \
    python get-pip.py && \
    rm get-pip.py && \
    # Feature-parity with node.js base images.
    apt-get install -y --no-install-recommends git openssh-client gpg && \
    # clean apt cache
    rm -rf /var/lib/apt/lists/* && \
    # Create the pwuser
    adduser pwuser

ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
RUN mkdir -p /ms-playwright && chmod -R 777 /ms-playwright

RUN pip install --upgrade pip && \
    pip install playwright && \
    playwright install --with-deps chromium && \
    rm -rf /var/lib/apt/lists/*

# Install BotBrowser
RUN curl -sSL https://github.com/MiddleSchoolStudent/BotBrowser/releases/download/20250523/botbrowser_20250525_136.0.7103.115_arm64.deb -o /tmp/botbrowser_20250525_136.0.7103.115_arm64.deb

RUN apt-get update && \
    dpkg -i /tmp/botbrowser_20250525_136.0.7103.115_arm64.deb || apt-get -f install -y --no-install-recommends && \
    rm /tmp/botbrowser_20250525_136.0.7103.115_arm64.deb && \
    rm -rf /var/lib/apt/lists/*

This is the script, largely taken from the BotBrowser Playwright demo:

import asyncio

from playwright.async_api import async_playwright

BOTBROWSER_EXEC_PATH: str = '/opt/chromium.org/chromium/chromium-browser'
BOT_PROFILE_PATH: str = './profiles/chrome136_win10_x64.enc'


async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch_persistent_context(
            user_data_dir="./user_data",
            executable_path=BOTBROWSER_EXEC_PATH,
            headless=True, # Set to True for production
            ignore_default_args=[
                "--disable-crash-reporter",
                "--disable-crashpad-for-testing",
                "--disable-gpu-watchdog",
            ],
            args=[
                "--no-sandbox",
                "--disable-blink-features=AutomationControlled",
                "--disable-audio-output",
                f"--bot-profile={BOT_PROFILE_PATH}",
            ],
        )
        page = await browser.new_page()

        # Remove Playwright's bindings to avoid detection.
        await page.add_init_script("""
            delete window.__playwright__binding__;
            delete window.__pwInitScripts;
        """)

        await page.goto("https://abrahamjuliot.github.io/creepjs/")
        await page.wait_for_timeout(3000)  # Wait for the page to load completely
        await page.screenshot(full_page=True, path='./screenshot.png')

asyncio.run(main())

Error (snippet)

...
await self._main_frame.wait_for_timeout(timeout)
  File "/usr/local/lib/python3.12/dist-packages/playwright/_impl/_frame.py", line 756, in wait_for_timeout
    await self._channel.send("waitForTimeout", locals_to_params(locals()))
  File "/usr/local/lib/python3.12/dist-packages/playwright/_impl/_connection.py", line 61, in send
    return await self._connection.wrap_api_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/playwright/_impl/_connection.py", line 528, in wrap_api_call
    raise rewrite_error(error, f"{parsed_st['apiName']}: {error}") from None
playwright._impl._errors.TargetClosedError: Page.wait_for_timeout: Target page, context or browser has been closed

The error can occur on or after await page.goto, the exact line can vary because I suspect the browser is crashing on its own schedule. I've seen this same behavior using sync Playwright and various combinations of Chromium arguments.

✅ If I remove the executable_path parameter and use Playwright's default Chromium version, this script works.

✅ Furthermore a standalone call to BotBrowser Chromium works:

/opt/chromium.org/chromium/chromium-browser --no-sandbox --headless --bot-profile=./profiles/chrome136_win10_x64.enc  --disable-gpu --screenshot=screenshot.png --window-size=1280,800   https://bot.sannysoft.com/

I've tried verbose logging, but it doesn't seem to show anything useful.

I'd be interested to know if you could reproduce the issue or offer any guidance. I appreciate any help with this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions