microsoft/playwright-python

Xvfb-run not working with fastapi in python docker container

Ayan-Bandyopadhyay opened this issue · 3 comments

I'm running into an issue running playwright with headless=false while trying to run a fastapi server with poetry. The error message is Looks like you launched a headed browser without having a XServer running. Set either 'headless: true' or use 'xvfb-run <your-playwright-app>' before running Playwright.

Here is my Dockerfile:

FROM mcr.microsoft.com/playwright/python:v1.47.0-jammy

ENV POETRY_HOME=/opt/poetry
ENV POETRY_VENV=/opt/poetry-venv
ENV POETRY_DATA_DIR=/opt/poetry-data
ENV POETRY_CONFIG_DIR=/opt/poetry-config
# Tell Poetry where to place its cache and virtual environment
ENV POETRY_CACHE_DIR=/opt/.cache

VOLUME ./.poetry-data-cache /opt/poetry-data
VOLUME ./.poetry-cache /opt/.cache

RUN python -m pip install poetry==1.7.1
WORKDIR /workspace
RUN poetry config virtualenvs.create false

COPY ./pyproject.toml ./pyproject.toml
COPY ./poetry.lock ./poetry.lock
# install only deps in dependency list first and lockfile to cache them
RUN poetry install --no-root --only main

COPY . .
# then install our own module
RUN poetry install --only main

EXPOSE 8000

ENTRYPOINT ["xvfb-run", "--auto-servernum", "--server-num=1", "--server-args='-screen 0, 1920x1080x24'", "poetry", "run", "start" ]

And here is the fastapi endpoint that throws the above error:

@app.get("/test")
async def test():
    browser_args = [
        "--window-size=1300,570",
        "--window-position=000,000",
        "--disable-dev-shm-usage",
        "--no-sandbox",
        "--disable-web-security",
        "--disable-features=site-per-process",
        "--disable-setuid-sandbox",
        "--disable-accelerated-2d-canvas",
        "--no-first-run",
        "--no-zygote",
        "--use-gl=egl",
        "--disable-blink-features=AutomationControlled",
        "--disable-background-networking",
        "--enable-features=NetworkService,NetworkServiceInProcess",
        "--disable-background-timer-throttling",
        "--disable-backgrounding-occluded-windows",
        "--disable-breakpad",
        "--disable-client-side-phishing-detection",
        "--disable-component-extensions-with-background-pages",
        "--disable-default-apps",
        "--disable-extensions",
        "--disable-features=Translate",
        "--disable-hang-monitor",
        "--disable-ipc-flooding-protection",
        "--disable-popup-blocking",
        "--disable-prompt-on-repost",
        "--disable-renderer-backgrounding",
        "--disable-sync",
        "--force-color-profile=srgb",
        "--metrics-recording-only",
        "--enable-automation",
        "--password-store=basic",
        "--use-mock-keychain",
        "--hide-scrollbars",
        "--mute-audio",
    ]
    async with async_playwright() as pw:
        browser = await pw.chromium.launch(
            args=browser_args + [f"--remote-debugging-port=9222"],
            headless=False,
        )
        context = await browser.new_context()
        page = await context.new_page()
        await page.goto("https://example.com")
        html = await page.content()
        await browser.close()

    return {"html": html}

Originally posted by @Ayan-Bandyopadhyay in microsoft/playwright#14250 (comment)

Have you considered headless=True? This everything is faster and you don't need xvfb in the first place. You can run the DEBUG=pw:browser env to see the full output.

I do to be able to run headless=True for my use case. Although I may have found the solution on the support discord, this seems to work:

ENV PYTHONUNBUFFERED=1
ENV DISPLAY=:99

CMD Xvfb :99 -screen 0 1024x768x16 & poetry run start

Closing then since it seems solved / no Playwright bug.