본문 바로가기

[2020-01-07] ec2 Next.js Docker 배포 이슈

웹챗 SDK 용 서버를 배포하기 위해 개인 ec2에서 docker로 배포하였다.

 

그런데 왠걸 지금까지 늘 해오던 배포인데 npm install에서 Dockerfile이 멈추는 현상이 발생했다.. 심지어 ec2 서버가 멈춰서 강제종료 후 프로세스가 알아서 죽을 때까지 기다렸다가 들어가야 하는 경우도 있었다..

 

 Dockerfile

FROM node:10

RUN mkdir -p /app/webchat

COPY package.json /app/webchat/package.json
RUN cd /app/webchat; npm install // 여기서 맛이 감...

RUN echo 'node version : ' && node --version
RUN echo 'npm  version : ' &&  npm --version

COPY . /app/webchat

WORKDIR /app/webchat

CMD npm run start:linux

EXPOSE 4001

 

1. npm config 설정

선배님께 여쭤보니 npm 레지스트리가 https://로 시작되는 주소로 받아올 때 못받아오는 경우가 있어 http://registry.npmjs.org/로 주소를 바꾸고 strict-ssl을 false로 설정하는 걸 알려주셨다!

 

Dockerfile

FROM node:10

RUN mkdir -p /app/webchat

COPY package.json /app/webchat/package.json
RUN cd /app/webchat; npm config set registry http://registry.npmjs.org/; npm config set strict-ssl false; npm install

RUN echo 'node version : ' && node --version
RUN echo 'npm  version : ' &&  npm --version

COPY . /app/webchat

WORKDIR /app/webchat

RUN node node_modules/node-sass/scripts/install.js

CMD npm run start:linux

EXPOSE 4001

BUT, 그래도 똑같은 문제로 install이 멈췄다...ㅜ

 

2. ec2 t2.micro Out of Memory

개인 ec2에 프리티어가 사용가능한 t2.micro(메모리 1GB)로 인스턴스를 받아서 깔려고 한게 문제여서 프로세스가 oom이 나버려 죽었는지 의심이 되었다.

 실제로 Docker 실행당시, top 명령어로 확인해보니 npm이 메모리를 60% 넘게 잡아먹다가 맛이 가는 순간을 확인하였다.

 

역시 가난하면 배포도 쉽게 못하는구나 생각하면서 돈을 내고 더 좋은 인스턴스를 발급받을까 고민하다가 ec2가 메모리 스왑을 default로 생성해주지 못한다는 걸 알고 아래 가이드를 참고하여 메모리 스왑 설정을 해주었다.

 

https://aws.amazon.com/ko/premiumsupport/knowledge-center/ec2-memory-swap-file/

 

스왑 파일을 사용하여 Amazon EC2 인스턴스의 스왑 공간으로 메모리 할당

Amazon Elastic Compute Cloud(Amazon EC2) 인스턴스에서 스왑 파일로 사용할 메모리를 할당하려고 합니다. 어떻게 하면 됩니까? 물리적 RAM을 이미 사용하고 있을 경우 Amazon EC2 인스턴스는 물리적 RAM에 대한 단기 교체로 스왑 공간을 사용합니다. 활성 상태가 아니거나 다른 데이터 또는 지침만큼 긴급히 필요하지 않은 RAM의 콘텐츠를 스왑 파일에 페이징할 수 있습니다. 그러면 RAM을 확보하여 즉시 사용할 수 있습니다

aws.amazon.com

 

3. npm permission

뒤늦게 .npm/logs/~.log에서 에러 로그를 보니 ENEEDAUTH 태그가 보였다..! 처음 보는 태그에 검색해보니 npm에 모듈을 배포 시, npm에 로그인 되어있지 않으면 나는 문제라는데 나는 모듈을 publish를 한적이 없다...!?

 

https://heropy.blog/2019/01/31/node-js-npm-module-publish/

 

내 NPM 패키지(모듈) 배포하기

개발을 위해 npm install xxx로 설치하는 모듈이 많아지면서 자주 사용하는 나의 코드들도 같은 방법으로 제공하고 싶었죠.하지만 ‘코드 복붙’이 더 쉬우니 차일피일 ...

heropy.blog

What is unsafe-perm flag in npm? 

Unsafe-perm flag is set to true to suppress the UID/GID (User Identifier/ Group Identifier) switching when running package scripts. The flag is explicitly set to false to prevent non-root user from installing packages.

더 검색해보니, Boolean package script를 실행할 때, 루트로 실행 중이면 false, 그렇지 않으면 true 로 내부적으로 전환되는데 root가 아닌 사용자로 설치하면 실패하게 된다. 이러한 UID/GID 전환을 억제하려면 true로 두어 무조건 설치가 되도록 하는 듯 하다.

 

사용하는 어떤 패키지가 배포중이었거나 어떠한 영향을 미쳤으리라 생각이 들지만 우선 flag를 달고 빌드해보니 정상적으로 되었다 ㅠㅠ

 

Dockerfile

FROM node:10

RUN mkdir -p /app/webchat

COPY package.json /app/webchat/package.json
RUN cd /app/webchat; npm config set registry http://registry.npmjs.org/; npm config set strict-ssl false; npm install --unsafe-perm=true

RUN echo 'node version : ' && node --version
RUN echo 'npm  version : ' &&  npm --version

COPY . /app/webchat

WORKDIR /app/webchat

RUN node node_modules/node-sass/scripts/install.js

CMD npm run start:linux

EXPOSE 4001