chrome cdp 를 local에서 켜고, 연결을 docker 에서 할때 mitmproxy 사용해서 해결
Updated on
Chrome 은 localhost, 127.0.0.1이 아니면 접근이 불가능 하다.
그래서 옛날에는
netsh advfirewall firewall delete rule name="Allow Port 9222"
netsh interface portproxy delete v4tov4 listenport=9222 listenaddress=0.0.0.0
timeout 3
netsh advfirewall firewall add rule name="Allow Port 9222" dir=in action=allow protocol=TCP localport=9222
start /b cmd /c call "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --lang=ko-KR --no-default-browser-check --no-first-run --disable-dev-shm-usage --window-size=2560,1440 --start-maximized --disable-infobars
timeout 5
netsh interface portproxy add v4tov4 listenport=9222 listenaddress=0.0.0.0 connectport=9222 connectaddress=127.0.0.1이 window shell 명령어를 통해서 해결하고는 했는데, 문제가 크롬이 켜진 이후에 netsh 로 연결을 열어줬어야 했고.
그러다보니, 항상 크롬이 켜진 이후라서 5초라는 딜레이가 발생했었다.
근데 이 문제를 더 간단히 해결하기 위해서 발견한 것이
mitmproxy 라는 건데.
https://github.com/mitmproxy/mitmproxy
https://mitmproxy.org/downloads/#
매우 좋은 것 같다.
from mitmproxy import http
import json
TARGET_HOST = "127.0.0.1"
TARGET_PORT = 9222
PROXY_HOST = "host.docker.internal"
PROXY_PORT = 9223
def request(flow: http.HTTPFlow) -> None:
"""HTTP 요청을 수정하여 실제 Chrome 디버그 서버로 포워딩"""
try:
print("HTTP request intercepted")
flow.request.headers["Host"] = "localhost"
flow.request.host = TARGET_HOST
flow.request.port = TARGET_PORT
except Exception as e:
print(f"Request modification error: {e}")
def websocket_handshake(flow: http.HTTPFlow) -> None:
"""WebSocket 핸드셰이크 요청을 수정하여 실제 Chrome 디버그 서버로 포워딩"""
try:
print("WebSocket handshake intercepted")
flow.request.headers["Host"] = "localhost"
flow.request.host = TARGET_HOST
flow.request.port = TARGET_PORT
except Exception as e:
print(f"WebSocket handshake modification error: {e}")
def response(flow: http.HTTPFlow) -> None:
"""HTTP 응답을 수정하여 webSocketDebuggerUrl을 mitmproxy 포트으로 변경"""
try:
content_type = flow.response.headers.get("Content-Type", "")
if "application/json" in content_type:
data = json.loads(flow.response.text)
if "webSocketDebuggerUrl" in data:
original_ws_url = data["webSocketDebuggerUrl"]
# 원래의 WS URL을 변경
new_ws_url = original_ws_url.replace(
f"ws://{TARGET_HOST}:{TARGET_PORT}",
f"ws://{PROXY_HOST}:{PROXY_PORT}"
)
data["webSocketDebuggerUrl"] = new_ws_url
flow.response.text = json.dumps(data)
print(f"Modified webSocketDebuggerUrl: {new_ws_url}")
except json.JSONDecodeError:
print("Failed to decode JSON response")
except Exception as e:
print(f"Error modifying response: {e}")
"""
mitmproxy --mode reverse:http://127.0.0.1:9222/ --listen-port 9223 -s modify_host.py
"""위 코드가 파이썬으로 만들어진 코드이고,
mitmproxy --mode reverse:http://127.0.0.1:9222/ --listen-port 9223 -s modify_host.py
명령어를 통해서 mitmproxy 를 실행시키면 된다.
그러면, 도커 안에서 도는 프로세스에서 puppeteer나 playwright를 연결할때.
host.docker.internal:9223 으로 연결되게 타겟해놓게 되면 실제 연결하게 되면 로컬에서 켠 브라우저에서 작동하게 된다.
C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --lang=ko-KR --no-default-browser-check --no-first-run --disable-dev-shm-usage --window-size=2560,1440 --start-maximized --disable-infobars
이게 왜 유용하냐면, 실제로 개발이나 서버에서는 도커에서 돌아가기 마련인데, 생각보다 이게 정확히 작동하는지에 대해서 체크가 어려울때가 있다.
그래서 개발할때는 빠르게 개발해야하기 때문에 이 방식으로 개발을 하고, 실제로 서버에서 돌아갈때는 또 서버에서 잘 도는지 체크를 해주면 된다.
puppeteer-screen-recorder 같은거로 체크했었음.