[Docker | selenium] SessionNotCreatedError 에러 & 해결방법

최자은·2023년 9월 8일
0

도커

목록 보기
3/3
post-custom-banner

chromedriver

1. mac-arm64

docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" selenium/standalone-chrome:116.0

  • 경고 메세지
    WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
  • 해결
    docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" --platform linux/amd64 selenium/standalone-chrome:116.0

2. linux/arm64 (최종 설치)

docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" --platform linux/amd64 selenium/standalone-chrome:116.0

  • 에러
(node:75772) UnhandledPromiseRejectionWarning: SessionNotCreatedError: Could not start a new session. Error while creating session with the driver service. Stopping driver service: Could not start a new session. Response code 500. Message: unknown error: Chrome failed to start: crashed.
  (unknown error: DevToolsActivePort file doesn't exist)
  (The process started from chrome location /home/seluser/.cache/selenium/chrome/linux64/116.0.5845.96/chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.) 
Host info: host: '0b691d4b123a', ip: '172.17.0.2'
Build info: version: '4.12.1', revision: '8e34639b11'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '5.15.49-linuxkit-pr', java.version: '11.0.20.1'
Driver info: driver.version: unknown
Build info: version: '4.12.1', revision: '8e34639b11'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '5.15.49-linuxkit-pr', java.version: '11.0.20.1'
Driver info: driver.version: unknown

실행 순서

1. 로컬의 크롬 드라이버 버전 확인 후, chromedriver linux64 버전 설치. (*mac-arm64 환경도 설치해봄)
  	- 로컬 환경 크롬 드라이버 116.0.5845.96(*현재 최신 버전)
 	- docker 이미지 selenium/standalone-chrome의 버전 116.0(*현재 최신 버전)
	- mac-arm64 환경(m1칩)으로 처음 설치했다가 드라이버 관련 문제가 계속나서 linux 버전으로 재설치
    
2. /usr/local/bin 경로에 옮겨 저장 (맥 os)

3. 셀레니움 코드 (테스트)
const { Builder, By, until, Key } = require('selenium-webdriver')
const chrome = require('selenium-webdriver/chrome')

const chromeDriverPath = '/path/to/chromedriver'

const options = new chrome.Options()
options.addArguments(
  '--headless',
  '--disable-dev-shm-usage',
  '--disable-gpu',
  '--no-sandbox',
  '--remote-allow-origins=*',
)
options.setChromeBinaryPath('/usr/local/bin')

;(async function example() {
  let driver = await new Builder()
    .forBrowser('chrome')
    .usingServer('http://localhost:4444/wd/hub') // 이 부분이 없으면 실행은 되나 도커 환경 아니고 로컬 실행.
    .setChromeOptions(options)
    .build()

  try {
    await driver.get('https://google.com')
    await driver.findElement(By.name('q')).sendKeys('Automation Bro', Key.ENTER)

    let firstResult = await driver.wait(
      until.elementLocated(By.css('h3')),
      10000,
    )

    console.log('1', await firstResult.getAttribute('textContent'))
    console.log('2', await (await driver.getCapabilities()).getBrowserName())
    console.log('3', await (await driver.getCapabilities()).getBrowserVersion())

  } catch (error) {
    console.log('Error:', error.message)
  } finally {
    await driver.quit()
  }
})()
// 실행결과 
Selenium Manager binary found at /Users/ella/Projects/selenium-docker-test/test-230905/node_modules/selenium-webdriver/bin/macos/selenium-manager
Driver path: /Users/ella/.cache/selenium/chromedriver/mac-arm64/116.0.5845.96/chromedriver
Browser path: /Users/ella/.cache/selenium/chrome/mac-arm64/116.0.5845.96/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing
1 SDET Unicorns: Master Software Testing and Automation
2 chrome
3 116.0.5845.96
4. docker 최신 버전 업데이트 후 실행
	- docker pull selenium/standalone-chrome:116.0`
    - docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" --platform linux/amd64 selenium/standalone-chrome:116.0
    
5. 셀레니움 파일 실행
	- node ./test.js
    
6. 에러 메세지
(node:68472) UnhandledPromiseRejectionWarning: SessionNotCreatedError: Could not start a new session. Error while creating session with the driver service. Stopping driver service: Could not start a new session. Response code 500. Message: unknown error: Chrome failed to start: crashed.
  (unknown error: DevToolsActivePort file doesn't exist)
  // **options.setChromeBinaryPath('/usr/local/bin') 추가 전
  (The process started from chrome location /opt/google/chrome/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.) 
  // **options.setChromeBinaryPath('/usr/local/bin') 추가 후
  (The process started from chrome location /home/seluser/.cache/selenium/chrome/linux64/116.0.5845.96/chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.) 
Host info: host: '623eff99115c', ip: '172.17.0.2'
Build info: version: '4.12.1', revision: '8e34639b11'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '5.15.49-linuxkit-pr', java.version: '11.0.20.1'
Driver info: driver.version: unknown
Build info: version: '4.12.1', revision: '8e34639b11'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '5.15.49-linuxkit-pr', java.version: '11.0.20.1'
Driver info: driver.version: unknown
    at Object.throwDecodedError (/Users/ella/Projects/selenium-docker-test/test-230905/node_modules/selenium-webdriver/lib/error.js:524:15)
    at parseHttpResponse (/Users/ella/Projects/selenium-docker-test/test-230905/node_modules/selenium-webdriver/lib/http.js:601:13)
    at Executor.execute (/Users/ella/Projects/selenium-docker-test/test-230905/node_modules/selenium-webdriver/lib/http.js:529:28)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
7. 컨테이너 로그
  (unknown error: DevToolsActivePort file doesn’t exist)
  (The process started from chrome location /opt/google/chrome/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
  (..중략)
  • SessionNotCreatedError, 세션이 생성되지 않고 크롬 브라우저가 실행되지 않아 종료되는 문제.
    • 구글링을 해보니 여러 원인 중 드라이버 버전의 호환이 있어 삭제하고 재설치 => 해결안됨
  • --remote-allow-origins= 추가
    https://groups.google.com/g/chromedriver-users/c/xL5-13_qGaA 에 같은 에러 내용에 대해 논의한 글이 있어 참고하여 크롬 옵션에 --remote-allow-origins=
    추가 (Chrome 웹 브라우저를 원격으로 제어하거나 테스트하는 데 필요한 원격 호스트의 접근을 허용하는 옵션) 후 다시 실행 => 같은 에러. 해결안됨

  1. docker pull selenium/standalone-chrome:116.0
  2. docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" --platform linux/amd64 selenium/standalone-chrome:116.0
  3. node ./test.js 입력 (js 코드에 .usingServer('http://localhost:4444/wd/hub') 포함)
  4. 컨테이너 로그 확인
13:06:50.304 INFO [LocalDistributor.newSession] - Session request received by the Distributor: 
 [Capabilities {browserName: chrome, goog:chromeOptions: {args: [--headless, --disable-dev-shm-usage, --disable-gpu, --no-sandbox, --remote-allow-origins=*], binary: /usr/local/bin}}]
13:07:18.735 WARN [SeleniumManager.lambda$runCommand$1] - Exception managing chrome: Unable to discover proper chromedriver version in offline mode
13:07:22.333 WARN [DriverServiceSessionFactory.apply] - Error while creating session with the driver service. Stopping driver service: Could not start a new session. Response code 500. Message: unknown error: Chrome failed to start: crashed.
  (unknown error: DevToolsActivePort file doesn't exist)
  (The process started from chrome location /home/seluser/.cache/selenium/chrome/linux64/116.0.5845.96/chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.) 
Host info: host: 'c15f3b0c10d9', ip: '172.17.0.2'
Build info: version: '4.12.1', revision: '8e34639b11'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '5.15.49-linuxkit-pr', java.version: '11.0.20.1'
Driver info: driver.version: unknown
13:07:22.493 WARN [SeleniumSpanExporter$1.lambda$export$3] - {"traceId": "654b584039f60ec99b2e13166db49d41","eventTime": 1694178442483313223,"eventName": "Unable to create session with the driver","attributes": {"current.session.count": 0,"logger": "org.openqa.selenium.grid.node.local.LocalNode","session.request.capabilities": "Capabilities {browserName: chrome, goog:chromeOptions: {args: [--headless, --disable-dev-shm-usage, --disable-gpu, --no-sandbox, --remote-allow-origins=*], binary: \u002fusr\u002flocal\u002fbin}}","session.request.downstreamdialect": "[W3C]"}}

문제 및 해결

1. (근본적인 원인) docker image

  • selenium/node-chrome, selenium/standalone-chrome 이 둘을 주구장창 썼는데, 결국 이 둘다 답이 아니었음.
    • 구글, 유튜브에 도커 환경에서 셀레니움을 실행하는 예제들을 보면 거의 대부분 위 두 가지 이미지를 사용함.
  • 답은 공식 깃허브에 나와있었음.
    https://github.com/SeleniumHQ/docker-selenium#install-certificates-for-Chromium-based-browsers

    Experimental Mult-Arch aarch64/armhf/amd64 Images
    For experimental docker container images, which run on platforms such as the Mac M1 or Raspberry Pi, see the community-driven repository hosted at seleniumhq-community/docker-seleniarm. These images are built for three separate architectures: linux/arm64 (aarch64), linux/arm/v7 (armhf), and linux/amd64.
    Furthermore, these experimental container images are published on Seleniarm Docker Hub registry.
    See issue #1076 for more information on these images.
    If you're working on an Intel or AMD64 architecture, we recommend using the container images in this repository (SeleniumHQ/docker-selenium) instead of the experimental ones.

  • 결론적으로, docker-seleniarmlinux/arm64 (aarch64), linux/arm/v7 (armhf), and linux/amd64 세 가지를 지원하기 위해 제작되었다고 한다. 또, Intel 또는 AMD64 아키텍처를 사용하는 경우 해당 저장소의 컨테이너 이미지(Selenium HQ/docker-selenium)를 실험 이미지 대신 사용하는 것이 좋다고 나온다.
  • selenium이 아닌 seleniarm이 커뮤니티 주도로 유지보수 되고 있다.
    - ⭐️ 따라서, seleniarm/standalone-chromium 이미지를 사용하면 문제가 해결된다.

2. 셀레니움 코드 내에 path를 명시적으로 지정

  • options.setChromeBinaryPath('/usr/local/bin')
  • 이미지를 생성해서 컨테이너를 생성하고 코드를 실행할 때, 계속해서 드라이버와 관련 문제가 생겼고, 여러 번의 드라이버 재설치를 해보면서 버전의 문제가 아니라면, 경로를 찾지 못해서 생기는 문제일까 싶어 셀레니움 코드에 명시적으로 chromedriver의 경로를 지정해줌. 결정적으로 경로의 문제는 아니었음.
  • seleniarm/standalone-chromium으로 이미지를 정상적으로 생성하더라도 셀레니움 코드 내에 명시적으로 지정해준 크롬드라이버 옵션의 경로가 잘못되었거나 해당 경로가 에러의 근본적인 원인이 아니라면, 에러 메세지 UnhandledPromiseRejectionWarning: SessionNotCreatedError: Could not start a new session. 가 생길 수 있다.

최종 코드

const { Builder, By, until, Key } = require('selenium-webdriver')
const chrome = require('selenium-webdriver/chrome')

const chromeDriverPath = '/path/to/chromedriver'

const options = new chrome.Options()
options.addArguments(
  '--headless',
  '--disable-dev-shm-usage',
  '--disable-gpu',
  '--no-sandbox',
  '--remote-allow-origins=*',
)

// options.setChromeBinaryPath('/usr/local/bin')

;(async function example() {
  let driver = await new Builder()
    .forBrowser('chrome')
    .usingServer('http://localhost:4444/wd/hub')
    .setChromeOptions(options)
    .build()

  try {
    await driver.get('https://google.com')
    await driver.findElement(By.name('q')).sendKeys('Automation Bro', Key.ENTER)

    let firstResult = await driver.wait(
      until.elementLocated(By.css('h3')),
      10000,
    )

    console.log('1', await firstResult.getAttribute('textContent'))
    console.log('2', await (await driver.getCapabilities()).getBrowserName())
    console.log('3', await (await driver.getCapabilities()).getBrowserVersion())
  } catch (error) {
    console.log('Error:', error.message)
  } finally {
    await driver.quit()
  }
})()
// seleniarm/standalone-chromium
// docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" --platform linux/amd64 seleniarm/standalone-chromium:116.0

참고 사이트

profile
모든 과정을 기록하며 꾸준히 성장하고 실수를 반복하지 말자 !
post-custom-banner

1개의 댓글

comment-user-thumbnail
2024년 4월 6일

감사합니다 도움이 많이 되었습니다!
그럼 현재도 seleniarm 이미지로 셀레니움 그리드 서버를 띄워서 분산환경에서 사용중이신 걸까요?

답글 달기