bcrpyt가 설치된 express서버를 docker에서 구동하고자 하였다.
단순히 express만 설치하여 구동하였을 때 문제가 없었기 때문에 아무런 걱정 없이 하던 일을 계속 하였다.
하지만 bcrpyt를 설치하고 docker이미지를 재생성하는 순간 문제가 발생하였다...😱
error /app/node_modules/bcrypt: Command failed.
Exit code: 1
Command: node-pre-gyp install --fallback-to-build
Arguments:
Directory: /app/node_modules/bcrypt
//생략//
gyp ERR! find Python **********************************************************
gyp ERR! find Python You need to install the latest version of Python.
gyp ERR! find Python Node-gyp should be able to find and use Python. If not,
gyp ERR! find Python you can try one of the following options:
gyp ERR! find Python - Use the switch --python="/path/to/pythonexecutable"
gyp ERR! find Python (accepted by both node-gyp and npm)
gyp ERR! find Python - Set the environment variable PYTHON
gyp ERR! find Python - Set the npm configuration variable python:
gyp ERR! find Python npm config set python "/path/to/pythonexecutable"
gyp ERR! find Python For more information consult the documentation at:
gyp ERR! find Python https://github.com/nodejs/node-gyp#installation
gyp ERR! find Python **********************************************************
//생략//
ERROR: Service 'server' failed to build : The command '/bin/sh -c yarn install' returned a non-zero code: 1
대충 이런 에러 메시지가 나왔다. 즉, node-gyp 때문에 뭐가 안된다는 것이다.
여기에 python 어쩌구 하는 메시지가 많이 보여서 "아니 python이 거기서 왜 나와?" 하고 당황하였다.😑
" python이면 c계열 문제일 것이고 m1 맥을 사용 중이니 이것 때문인가..? " 하면서 불안감에 휩싸였지만 침착하게 구글링을 시작하였다.
express의 Dockerfile이다.
FROM node:14.16-alpine
WORKDIR "/app"
COPY ./package.json ./
RUN yarn install
RUN yarn global add pm2
COPY . .
CMD ["pm2-runtime", "start", "ecosystem.config.js"]
메인 이미지를 잘 보자.
alpine버전은 alpine linux을 기반으로 만들어진 버전이다. 공식사이트
즉, 경량화 버전이라고 보면 된다. 여기에는 python이 설치되어 있지 않다.
alpine버전의 도커쉘에 들어가서 python --version을 입력해보자 없다고 할 것이다.😲
nodejs가 뭔지부터 알아야한다.🤯
간단하게 알아보자. (가능할지는 모르겠다.)
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
nodejs 공식 홈페이지에 들어가면 눈에 띄는 문구이다.
즉, v8엔진으로 빌드된 js런타임이라는 것 이다.
v8엔진은 javascript를 기계어로 번역하는 일을 하는데 c++로 만들어졌다.
빠른 속도와 로우레벨에 접근할 수 있기 때문에 c계열을 사용한다는 것은 알 것이다.
이런 이유 때문에 bcrypt는 느린 javascript 대신 c++로 만들어졌다.
그렇다면 왜 python을 애타게 찾을까?
bcrypt는 python으로 c/c++을 wrapping하여 사용한다고 한다.
그래서 python을 애타게 찾았던 것이다.
node-gyp는 뭘까?
bcrypt처럼 c++로 만들어진 모듈을 c++ Addon 또는 Natvie Node Module 또는 Native Addon Module이라고 한다.
node-gyp 문서를 보면 "nodejs에서 native addon를 빌드하는 툴" 이라고 소개되어 있다.
bcrypt의 공식문서에 node-pre-gyp에 대한 이슈가 소개되어 있고 여기에 해결방법이 소개되어 있다.
alpine버전에 python을 설치하자.
apk --no-cache add --virtual builds-deps build-base python를 실행하라고 한다.
Dockerfile에서 Run apk --no-cache add --virtual builds-deps build-base python를 추가하도록 하자.
apline버전이 아닌 일반버전을 사용하면 된다.
Dockerfile에서 alpine을 지우고 빌드해보자.
bcrypt모듈 아닌 bcryptjs모듈을 설치하면 된다고 한다.
npm i bcryptjs
yarn add bcryptjs
첫번째 방법을 추천한다.
그 이유를 알아보자.
nomal 버전은 사이즈가 크다.
| 버전 | 일반 image | 빌드 image |
|---|---|---|
| alpine | 115MB | 125.71MB |
| alpine + python | 115MB | 392.88MB |
| nomal | 889.64MB | 967.07MB |
물론 요즘 시대에 이미지 크기가 중요한건 아니지만 그래도 가벼운게 좋지 않을까?
bcrypt
bcryptjs
이 둘의 차이는 dependencies(종속성) 차이가 있다.
bcrypt는 node-pre-gyp와 node-addon-api와 종속관계이기 때문에 alpine버전에서 빌드가 안되는 이슈가 발생하였고 bcryptjs는 종속관계가 없기 때문에 이슈가 발생하지 않았다.
그러면 bcryptjs를 쓰면 되는것이 아닐까?
이 둘은 종속성 말고 버전에도 차이가 있다.
bcrypt가 9개월 전 5.0.0버전이 업데이트 되면서 이런 이슈가 업데이트 되었다고 한다.
bcryptjs의 마지막 업데이트는 4년 전 이기 때문에 해당 이슈는 해결되지 않은 것 같다. (추측)
아무래도 보안 관련 모듈이다 보니 최근 업데이트가 좋지 않을까?