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
같은거로 체크했었음.