Jenkins 와 AWS Elastic Beanstalk 를 이용해서 NodeJS 서버를 자동으로 배포하는 기능을 회사 프로젝트에 넣었다. Jenkins 는 전 직장에서도 사용했기 때문에 부담감이 덜 했지만 Beanstalk 은 처음 접해보는 거라 긴장감이 있었다. 2일동안 작업을 하면서 겪었던 삽질들을 정리해보고자 한다.
여기서 Jenkins plugin 은 배포파일을 만들어주고 (직접 만들어도 된다), 그 파일을 S3 bucket에 올려주고 Beanstalk에서 배포하는데 사용할 수 있게 해 준다. 그래서 Beanstalk Environment 를 자알 생성하고 Jenkins Build Step 을 자알 설정하면 알.아.서. Beanstalk 이 배포에 성공한다. (사실 이부분이 삽질기의 핵심이다.)
1yarn install // 빌드하기 위한 모듈 설치2yarn run build // 프로덕션 번들 빌드34rm -rf node_modules && yarn install --production // 프로덕션용 모듈 설치56zip -rq bundle.zip app.js node_modules/ // 배포용 압축파일을 만든다.
공식 문서 를 보고 시작했다.
새 환경 생성 페이지에서 도메인은 필수값이다. 배포된 웹 서비스를 확인할 수 있는 URL을 가리킨다. 근데 입력폼에서 필수값 표시도 안되고 별 설명도 없어서 그냥 넘겨보니 넘어가진다. 10~20분 정도를 기다리다 보면 생성에 실패한다. 꼭 입력하자.
기본 구성만으로 빌드 단계까지는 넘어가도 생성이 안될 수 있다. 회사의 경우 보안때문에 필수적으로 네트워크 구성을 달리 해주어야 한다. 이를 생각하지 못하고 계속 기본값으로 생성을 시도했고, Beanstalk log 에서는 [재시도->실패] 를 30분정도 반복하다 죽어버린다. 무엇이 문제인지 얘기해주지 않는다. 정상적으로 동작하면 3~5분만에 생성이 완료되니 그 이상 걸릴 경우 환경 구성에 문제가 있는 것이다.
배포파일에 package.json 파일이 있으면 Beanstalk 은 자체적으로 npm install 을 수행한다. 설치되는 위치는 배포 파일들이 생성되는 /var/app/current/
다. 그런데 만약 npm install 을 하던 중에 실패하면 npm install 자체가 실패한다.
나의 경우, firebase 모듈의 firestore > grpc > node-pre-gyp 가 node v8.11 과 호환되지 않는다는 에러를 뿜었다. 그러면서 node-pre-gyp install --fallback-to-build
명령어를 수행하는데 이 때 권한 문제(Permission Denied)에 부딫혀 npm install 이 실패했다. firebase가 firestore 만 덜어낼 수 없는 구조였기 때문에 npm install 을 성공시킬 방법이 없었다. package.json dependency 에서 따로 exclude 하는 방법도 없고...
결국 node_modules 을 번들파일과 함께 압축해서 S3에 업로드하는 방식을 선택했다. 그리고 기본적으로 npm install 이 실행되는 것을 .ebextensions 폴더의 config 파일을 생성해서 막았다. 그렇기 때문에 S3에 업로드되는 배포파일의 용량이 커진다는 문제점이 남아 있다.
/var/app/current/
/var/log/
/opt/elasticbeanstalk/hooks/appdeploy/pre/50npm.sh
/opt/elasticbeanstalk/containerfiles/ebnode.py
/opt/elasticbeanstalk/node-install/{노드 버전}/bin/
/tmp/deployment/application
(배포성공하면 삭제된다)/etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf