728x90
반응형


최근 Playwright를 이용해 자동화 봇을 만들고 있었습니다. 로컬이나 실서버 Ubuntu의 .venv 환경에서는 제대로 동작하는 봇이, 유독 도커(Docker) 컨테이너 안으로만 들어가면 로그인 단계에서 Timeout 에러를 뱉으며 멈춰버리는 현상을 겪었습니다.

결론부터 말하자면, 이 문제는 스크립트의 논리 오류가 아니라 도커 환경의 리소스 제한과 브라우저 렌더링 방식의 차이 때문이었습니다. 저와 같은 삽질을 반복하지 않으시길 바라며 해결 과정을 정리합니다.

1. 증상: "로컬에선 되는데 왜 도커만 이래?"

로컬에서 실행할 때(특히 창 모드)는 아무 문제 없던 코드가 도커 내 Headless 환경에서는 다음과 같은 에러를 발생시켰습니다.

Error in automation: Page.click: Timeout 30000ms exceeded.
... <div role="dialog" ... intercepts pointer events

로그를 뜯어보니, 로그인 버튼을 누르려는데 정해진 시간 내에 버튼이 나타나지 않거나, 투명한 다이얼로그(팝업) 레이어가 버튼 위를 덮고 있어 클릭 이벤트가 전달되지 않는 상태였습니다.

2. 원인 분석

핵심 원인 1: 공유 메모리(/dev/shm)의 부족

도커 컨테이너는 기본적으로 공유 메모리 공간을 64MB로 극단적으로 제한합니다. 하지만 Chromium 브라우저는 복잡한 페이지를 렌더링할 때 이보다 훨씬 많은 메모리를 사용합니다. 메모리가 부족하면 화면 렌더링이 꼬이거나, 닫혔어야 할 팝업이 그대로 남아 버튼을 가리게 됩니다.

핵심 원인 2: 샌드박스 보안 충돌

도커라는 격리 공간 안에서 브라우저가 또 자체 샌드박스를 만들려다 보니 렌더링 스레드가 비정상적으로 작동하는 경우가 많습니다.

핵심 원인 3: Headless 환경의 UI 변형

환경 차이로 인해 평소엔 안 뜨던 보안 안내 팝업이나 공지사항이 도커 환경에서만 튀어나올 수 있습니다. 이때 Playwright의 일반적인 click()은 가려진 요소를 누르지 못하고 타임아웃에 빠집니다.

3. 해결 방안

Step 1. docker-compose 설정 (메모리 해방)

도커 컨테이너가 브라우저 렌더링을 위해 충분한 공유 메모리를 쓸 수 있도록 shm_size를 늘려줍니다.

# docker-compose.yml
services:
  library-bot:
    build: .
    shm_size: '2gb'  # 64MB의 족쇄를 풀어줍니다.

Step 2. 브라우저 실행 옵션(Launch Args) 추가

도커 환경에 최적화된 실행 옵션을 추가합니다. --no-sandbox--disable-dev-shm-usage를 많이 사용합니다.

# server.py
self.browser = await self.playwright.chromium.launch(
    headless=True,
    args=[
        "--no-sandbox",             # 샌드박스 비활성화
        "--disable-dev-shm-usage"  # /dev/shm 대신 /tmp 사용
    ]
)

Step 3. 강제 클릭 옵션 (force=True) 적용

팝업이 버튼을 가리고 있더라도, 요소를 찾았다면 무조건 이벤트를 발생시키도록 force=True 옵션을 부여합니다.

# 일반 클릭 대신 강제 클릭 사용
await page.click("button", force=True)
await page.click('button', force=True)

4. 결과: "Success!"

이렇게 설정을 바꾸고 나니, 기존 문제들이 모두 해결되었고, 정상적으로 동작하는 걸 확인할 수 있었습니다. 이번 일로 인해 잘 모르는 환경에선 먼저 어떻게 진행해야 하는지에 대한 기초 지식이 정말 중요하다고 느꼈습니다.


요약

  1. 도커의 shm_size를 늘리자.
  2. --no-sandbox 옵션을 잊지 말자.
  3. 방해물이 있다면 force=True 사용.

참고자료

Selenium 자동화를 위한 Chrome 브라우저 실행 옵션 총정리

도움이 되셨다면 공감 부탁드립니다! 궁금한 점은 댓글로 남겨주세요. :)

728x90
반응형
LIST

+ Recent posts