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년 전 이기 때문에 해당 이슈는 해결되지 않은 것 같다. (추측)
아무래도 보안 관련 모듈이다 보니 최근 업데이트가 좋지 않을까?