playwright-python icon indicating copy to clipboard operation
playwright-python copied to clipboard

[Bug]: Chromium new_context({ proxy }) ignored when running inside Docker without CDP

Open 4dvisor opened this issue 6 months ago • 3 comments

Version

1.52.0

Steps to reproduce

import asyncio
import json
from playwright.async_api import async_playwright

TEST_URL = "https://api.ipify.org?format=json"
PROXY = {
    "server": "http://proxy_url:proxy_port",
    "username": "username",
    "password": "password", 
}

async def fetch_ip(context):
    page = await context.new_page()
    await page.goto(TEST_URL, wait_until="domcontentloaded")
    ip = json.loads(await page.text_content("body"))["ip"]
    await context.close()
    return ip


async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=True,
            proxy={"server": "per-context"},               # <-- required
            args=["--disable-blink-features=AutomationControlled"],
        )

        ctx1 = await browser.new_context(proxy=PROXY)
        print("CTX-1 IP ⇒", await fetch_ip(ctx1))

        await browser.close()

asyncio.run(main())

Expected behavior

CTX-1 IP ⇒ <IP-from-proxy>

Actual behavior

CTX-1 ⇒ <host-public-IP>

Additional context

When Chromium is launched with proxy={"server": "per-context"} inside a Docker container, no context created with browser.new_context(proxy=…) uses the proxy at all—all requests always fall back to the container’s outbound IP.

Environment

- Operating System: [Ubuntu 22.04]
- CPU: [amd64]
- Browser: [Chromium]
- Python Version: [3.12]
- Docker img: mcr.microsoft.com/playwright/python:v1.52.0-noble
- Other info:

4dvisor avatar Jun 10 '25 13:06 4dvisor

There is no need for per-context anymore since https://github.com/microsoft/playwright/issues/17252 was fixed.

Does it also happen if you do it without?

Does it happen if you do it via the proxy in the launch() call?

mxschmitt avatar Jun 11 '25 09:06 mxschmitt

Okay, I removed the per-context setting and changed it so that the proxy is set in the launch call, but it still uses the host IP address instead of the proxy.

4dvisor avatar Jun 11 '25 10:06 4dvisor

Also, adding the proxy in both the launch and new_context calls still results in the host IP address being used. Removing the per-context setting and only adding the proxy in the new_context call also uses the host IP address.

4dvisor avatar Jun 11 '25 10:06 4dvisor

I tried to reproduce but was not able to:

Other machine (different network):

docker run -it -p 3128:3128 --name squid-proxy alpine /bin/sh
apk update
apk add squid curl bash
mkdir -p /var/cache/squid
squid -z

cat > /etc/squid/squid.conf <<EOF
http_port 3128

# Allow CONNECT to port 443 (HTTPS)
acl SSL_ports port 443
acl Safe_ports port 443
acl CONNECT method CONNECT

# Allow all clients (not secure; restrict if needed)
http_access allow all
http_access allow CONNECT Safe_ports

# Deny everything else (redundant here since we allow all)
http_access deny all

cache deny all
EOF

squid -N -d1

Main machine:

docker run -it mcr.microsoft.com/playwright/python:v1.53.0-noble 
/bin/bash

cd
mkdir test
cd test
pip install playwright
apt update && apt install -y nano
nano test.py
python test.py

mxschmitt avatar Jul 10 '25 09:07 mxschmitt