[AWS] ECS 환경에서 puppeteer 사용하기

해달·2023년 5월 9일
0
post-thumbnail

서두

정해진 페이지에서 필요한 데이터를 확인하여 매주 데이터를 업데이트 해야 했다.
puppeteer를 사용하여 셀렉터를 정해 데이터를 긁어왔고 DB에 업데이트하는 쿼리를 작성해 로컬에서 원하는 로직대로 동작하는 스크립트를 작성 후 테스트를 완료한 뒤에
원하는 일정에 맞추어 배치를 돌리기 위해서 백엔드 분에게 요청해 ECS 서버에 테스크를 올려서 배포를 완료했으나 클라우드 워치에 에러로그가 찍히는걸 발견하였다.
그 과정을 해결하면서 배운 내용들을 토대로 정리해놓으려고 한다.


문제점

발생한 에러 로그

npm WARN exec The following package was not found and will be installed: ts-node@10.9.1
Error: Failed to launch the browser process!/root/.cache/puppeteer/chrome/linux-1108766/chrome-linux/chrome: error while loading shared libraries: libnss3.so: cannot open shared object file: No such file or directory
TROUBLESHOOTING: https://pptr.dev/troubleshooting
  • 지금 보니 이미 트러블슈팅에 관한 글을 안내해주고 있었다.. 그 당시에는 왜 바로 보지 못했는지..

우선 에러로 발생한 Failed to launch the browser process! 문구를 중점으로 에러를 해결할 방법을 찾기 시작했다.

위에서 나온 문구대로 발생한 에러는 puppeteer에서 사용하는 브라우저를 설치할 수 없다는 것이였다.

ECS환경은 VM환경이기때문에 로컬에서 사용하는 크롬브라우저를 바로 사용할 수 없어서 가상환경에서도 사용할 수 있게끔 처리를 해주어야 했다.

VM환경

VM은 가상머신(Virtual Machine)의 약어입니다. 가상머신은 호스트 컴퓨터에서 실행되는 소프트웨어를 통해 다른 운영 체제(OS)나 애플리케이션을 실행하는 가상 환경을 제공합니다. 이것은 하드웨어 자원을 가상화하여 여러 개의 가상 머신이 하나의 호스트에서 실행될 수 있도록 합니다.

VM 환경을 사용하면 다른 운영 체제를 설치하고 실행할 수 있으며, 다른 운영 체제에 대한 테스트 및 개발 환경을 만들 수 있습니다. 또한, 서버 컴퓨터에서 여러 가상 머신을 실행하면 하나의 물리적 서버로 여러 서버를 운영할 수 있어 하드웨어 비용과 전기료를 절감할 수 있습니다.

VM은 클라우드 컴퓨팅 및 가상화된 인프라스트럭처에서 중요한 역할을 합니다. AWS, Azure 및 Google Cloud Platform과 같은 클라우드 서비스 제공 업체는 가상 머신을 사용하여 다른 운영 체제를 실행하는 서버를 제공합니다. 이것은 사용자가 필요에 따라 필요한 서버 자원을 확장하거나 축소할 수 있게 합니다.


해결방안

처음에는 공식문서의 트러블슈팅 챕터를 확인하지못하고 스택오버플로우에 나와있는 해결방법대로 수정하려 하였으나, 동작되지가 않아 그 내용의 출처를 찾아보니
공식문서에서 AWS EC2환경에서 puppeteer를 사용하려면 추가로 설정해야주어야한다는 내용을 찾을 수 있었다.

  1. 리눅스 환경에서 크롬을 여는 경우 발생할 수 있는 에러

리눅스에서 사용되는 크롬에서는 신뢰할 수 없는 웹 콘텐츠로부터 호스트 환경을 보호하기 위해 여러계층의 샌드박스를 사용한다고 한다.
내가 동작하면서 만난 에러는 아니였지만,
puppeteer로 크롬을 열면서 허용해주는 옵션이 없으면 No useable sandbox! 와 같은 오류를 만날 수 있다고 한다.

우리가 여는 콘텐츠(홈페이지)가 신뢰할 수 있는 사이트라면 -no-sandbox, --disable-setuid-sandbox 같은 옵션을 전달해주어 위와 같은 에러를 방지할 수 있다고 한다.

export const launchBrowser = async (isHeadless: boolean) => {
  const browser = await puppeteer.launch({
    headless: isHeadless,
    protocolTimeout: 60000, // 이건 다른 에러때문에 넣어놓은 옵션
    args: ['--no-sandbox', '--disable-setuid-sandbox'],
  });

  return browser;
};

위 내용을 정리하면서 발견한 내용인데 이와 같이 옵션을 꺼버리는것은 권장하지 않는 방법이라고 한다.
아래와 같이 샌드박스를 구성하도록 하는 방법을 추천해주고 있다.


  1. EC2에서 사용할 수 있도록 패키지 설치해주기

공식문서에서 EC2 인스턴스를 사용하고 있다면 아래와 같은 단계를 수행해야 한다고 한다.

위와 같은 패키치 설치코드를 추가로 넣어줘야했기에,
테스크를 등록할 때 사용 된 dockerfile을 수정해 주었다.

공식문서에서는 yum이라는 패키지 매니저를 이용해 chromium 을 설치하라고 나와있다.

yum 은 리눅스 환경의 레드햇 계열에서 사용되는 패키지 매니저이다
리눅스 환경에서는 우분투 패키지매니저를 사용해도 되기에 apt-get 패키지 매니저를 사용해 필요한 패키지를 설치해 주었다.
(이전에 우분투로 개발했었던 경험이 있어 더 익숙했다. 굳이 차이점은 없다.)

RUN 명령어를 순서에 맞게 입력하지 않으면 잘못입력하면 에러와 같은 에러도 만날 수 있다...

// 에러
unable to locate package sudo docker
E: Unable to locate package sudo
sudo: not found

지금 보면 간단한 명령어 추가였지만.. 내용들을 찾아보고 적용하느라 꽤나 오랜시간을 사용했다.. 🥲

수정한 도커파일

...,

RUN apt-get update && apt-get install -y sudo
// apt-get update 명령어를 실행하여 패키지 목록을 업데이트하고, sudo 패키지를 설치합니다.

RUN apt install sudo
// 이미 설치된 패키지를 확인하고, 필요한 경우 sudo 패키지를 추가로 설치합니다.

RUN /bin/sh -c su -c 'amazon-linux-extras install epel -y'
RUN apt-get install chromium -y
//공식문서에서의 설치 명령어

, ...

설치 명령어로 이것저것 하면서 찾을 수 없다는 not found 명령어를 마주하며 위와 같이 적용하니 ECS에서 드디어! 성공하는 콘솔이 찍히기 시작했다..

DOCKFILE에서 RUN 명령어는 다양하게 사용되는 명령어이다.
나는 패키지설치를 위해 사용한것 ..!

차후에는 puppeteer를 사용하면서 마주한 에러들에 관해 정리해봐야겠다.


reference

0개의 댓글