자라나라 개발머리

[puppeteer/docker] node:16-alpine 빌드 에러 본문

etc.

[puppeteer/docker] node:16-alpine 빌드 에러

iammindy 2024. 3. 4. 05:03

 

node:16-alpine 환경에서 puppeteer를 사용하고자 한다.

로컬에선 잘 동작하나 도커 동작 시도 시 이미지 빌드부터 제대로 빌드 되지 않는 상황이다.

 

이를 해결하기 위한 시도와 결과를 기록한다.

 

1. puppeteer troubleshooting 참고하여 시도

(참고 : https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-on-alpine )

 

작성 코드

FROM alpine

# Installs latest Chromium (100) package.
RUN apk add --no-cache \\
      chromium \\
      nss \\
      freetype \\
      harfbuzz \\
      ca-certificates \\
      ttf-freefont \\
      nodejs \\
      yarn

...

# Tell Puppeteer to skip installing Chrome. We'll be using the installed package.
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

# Puppeteer v13.5.0 works with Chromium 100.
RUN yarn add puppeteer@13.5.0

# Add user so we don't need --no-sandbox.
RUN addgroup -S pptruser && adduser -S -G pptruser pptruser \\
    && mkdir -p /home/pptruser/Downloads /app \\
    && chown -R pptruser:pptruser /home/pptruser \\
    && chown -R pptruser:pptruser /app

# Run everything after as non-privileged user.
USER pptruser

...

 

발생 에러

57.99 npm ERR! code 255
57.99 npm ERR! path /usr/src/app/node_modules/core-js
58.00 npm ERR! command failed
58.00 npm ERR! command sh -c -- node -e "try{require('./postinstall')}catch(e){}"
58.00 npm ERR! qemu-x86_64: Could not open '/lib64/ld-linux-x86-64.so.2': No such file or directory
58.01 
58.01 npm ERR! A complete log of this run can be found in:
58.01 npm ERR!     /root/.npm/_logs/2024-03-02T18_57_10_854Z-debug-0.log

 

 

 

2. 같은 node:16-alpine 블로그 글 참고 시도

https://velog.io/@jsomedev/docker로-puppeteer-크롤링-프로젝트-배포시-오류-해결하기

FROM node:16-alpine  # Node.js 16과 alpine Linux를 기반으로 하는 이미지 사용

RUN apk add --no-cache chromium nss freetype harfbuzz ca-certificates ttf-freefont udev xvfb x11vnc fluxbox dbus  # puppeteer 실행을 위해 필요한 패키지들을 설치

RUN apk add --no-cache --virtual .build-deps curl \\
    && echo "<http://dl-cdn.alpinelinux.org/alpine/edge/main>" >> /etc/apk/repositories \\
    && echo "<http://dl-cdn.alpinelinux.org/alpine/edge/community>" >> /etc/apk/repositories \\
    && echo "<http://dl-cdn.alpinelinux.org/alpine/edge/testing>" >> /etc/apk/repositories \\
    && apk add --no-cache curl wget \\
    && apk del .build-deps  # puppeteer 다운로드를 위해 필요한 라이브러리들을 설치하고 마지막에는 빌드를 위해 추가적으로 설치한 패키지들을 삭제

ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser  # puppeteer가 chromium-browser를 실행할 수 있도록 설정
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true  # 이미 chromium을 설치했기 때문에 puppeteer가 chromium을 다시 다운로드하지 않도록 설정
ENV DISPLAY=:99  # Xvfb에서 사용할 디스플레이 설정

WORKDIR /var/app  # 작업 디렉토리를 /var/app으로 설정

# 캐시를 이용해 npm 패키지 설치를 한번만 실행하도록 합니다.
COPY package.json package-lock.json ./
RUN npm ci --only=production  # production 환경에서 필요한 모듈들만 설치
RUN npm install puppeteer  # puppeteer 설치

COPY . .

RUN npm run build  # 앱 빌드

ENV NODE_OPTIONS="--max-old-space-size=2048"  # 메모리 사용량 설정

EXPOSE 3030  # 컨테이너의 포트를 3030으로 열어줌
CMD Xvfb :99 -screen 0 1024x768x16 -ac & node dist/src/main.js  # Xvfb를 실행하고, node 앱 실행

 

발생 에러

//충돌 에러가 났긴 했는데 그거 주석 처리하고 다시 해보니까 걍 또 이 에러 뜸
58.23 npm ERR! code 255
58.23 npm ERR! path /usr/src/app/node_modules/puppeteer
58.24 npm ERR! command failed
58.24 npm ERR! command sh -c -- node install.js
58.24 npm ERR! qemu-x86_64: Could not open '/lib64/ld-linux-x86-64.so.2': No such file or directory
58.25 
58.25 npm ERR! A complete log of this run can be found in:
58.25 npm ERR!     /root/.npm/_logs/2024-03-02T19_08_59_178Z-debug-0.log

 

 

3. 에러난 해당 라이브러리 설치

(참고: https://musclebear.tistory.com/148)

 

상기 문제된 패키지는 /lib64/ld-linux-x86-64.so.2 인데, 이는 gcompat 라이브러리를 가리킨다.

(https://pkgs.alpinelinux.org/contents?file=ld-linux-x86-64.so.2)

 

그래서 해당 라이브러리를 설치해봤다.

 

작성 코드

RUN apk add --no-cache gcompat

 

발생 에러

57.52 npm ERR! code 1
57.52 npm ERR! path /usr/src/app/node_modules/core-js
57.53 npm ERR! command failed
57.53 npm ERR! command sh -c -- node -e "try{require('./postinstall')}catch(e){}"
57.53 npm ERR! ld-linux-x86-64.so.2: /usr/src/app/node_modules/node/bin/node: Not a valid dynamic program
57.53 
57.54 npm ERR! A complete log of this run can be found in:
57.54 npm ERR!     /root/.npm/_logs/2024-03-03T13_28_29_507Z-debug-0.log
------

 

4.  glibc 설치 (해결 방법)

# Install glibc(for puppeteer)
ENV GLIBC_VERSION="2.32-r0"
RUN apk add --no-cache wget \\
    && wget -q -O /etc/apk/keys/sgerrand.rsa.pub <https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub> \\
    && wget <https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-${GLIBC_VERSION}.apk> \\
    && apk add --force-overwrite glibc-${GLIBC_VERSION}.apk \\
    && rm glibc-${GLIBC_VERSION}.apk \\
    && wget <https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-bin-${GLIBC_VERSION}.apk> \\
    && apk add --force-overwrite glibc-bin-${GLIBC_VERSION}.apk \\
    && rm glibc-bin-${GLIBC_VERSION}.apk \\
    && wget <https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-i18n-${GLIBC_VERSION}.apk> \\
    && apk add --force-overwrite glibc-i18n-${GLIBC_VERSION}.apk \\
    && rm glibc-i18n-${GLIBC_VERSION}.apk \\
    && /usr/glibc-compat/bin/localedef -i en_US -f UTF-8 en_US.UTF-8 \\
    && echo "export LANG=en_US.UTF-8" > /etc/profile.d/locale.sh

 

해당 코드로 빌드 했더니 도커 이미지가 정상적으로 빌드되고, puppeteer 동작도 가능하단 것을 확인했다.

 

5.  마무리

당장 동작이 급하여 glibc 설치로 해결을 했지만, 이러한 해결법은 좋은 방법이 아니다.

좋은 방법이 아닌 이유를 알려면, apline 이미지에 대한 지식이 필요하다.

 

alpine 이미지를 쓰는 이유는 경량화 및 최적화이다.

alpine은 경량화를 달성하기 위해 중요하지 않은 라이브러리를 덜어내는 방법을 사용한다.

 

그리고 puppeteer는 그 덜어내진 라이브러리 중 하나에 의존성을 가지고 있는 라이브러리였다.

따라서 alpine의 장점을 취하면서, puppeteer를 쓰려면 puppeteer가 필요한 라이브러리만 쏙쏙 뽑아서 설치하는게 최선의 방법이라고 생각했다. 그래서 여러가지 시도를 해봤지만 .. 아무래도 의존성이 엮이고 엮여 있는지 충돌도 났고, 알 수 없는 에러도 마주쳤다. 

 

그래서 설치한게 glibc다. 이게 안 좋은 이유는 다음과 같다.

기존 linux 이미지에선 glibc 라는 라이브러리를 사용하는데, alpine은 거기서 알짜배기들만 모은 musl libc 라이브러리를 사용한다.

내가 alpine 이미지에 glibc 라이브러리를 설치하여 문제를 해결한 것은, 기껏 덜어내고 덜어낸 아이들을 다시 갖다 붙인 셈인 것이다. alpine의 장점을 없애는 해결 방법이다.

 

그래서 glibc를 설치한 도커 이미지는 기존 alpine이미지에 비해 이미지 용량이 어마어마하게 크다.. ^_^ ㅎ

혹시 누군가 이 글을 봤다면 .. 다른 .. 인텔리전트한 방법으로 해결을 하셨다면 .. 댓글로 남겨주시면 정말 감사하겠습니다 ..