daily

Dockerization [0] - docker build 하기

Juhyuck 2023. 5. 15. 21:19
728x90

Node.js 환경에서 만든 API를 Docker 이미지로 만들어 배포하기를 해보고 있다. 우선 Docker Desktop 설치에서부터 문제 해결을 하고, Docker image를 만들고 실행하면서 생긴 문제를 기록해본다.

 

"Cannot enable Hyper-V service" 문제.

 

1. AMD에 MSI Bios에서 AMD IOMMU 옵션을 찾아서 enable, SVM 옵션을 찾아서 enable로 바꿔주고,

 

2. 윈도우 시작메뉴 우클릭 > 앱 및 기능 > 프로그램 및 기능 > Windows 기능 켜기/끄기 > Hyper-V 체크, 가상머신 플랫폼 체크

 

두가지 적용하고나니 Hyper-V 문제가 해결되었다.

 

그 다음은,

"WSL 2 installation" 에러

이건 팝업에 있는 해결 방법 링크에서 알려주는 단계를 따라하니 해결되었다.

 

WSL 2 설치까지 마치면, Docker Desktop이 실행된다.

 

이제 Build를 할 차례.


Docker를 사용하여 Node.js 백엔드 API를 이미지로 만들어 배포하는 방법은,

  1. Dockerfile 작성: 프로젝트 루트 디렉토리에 Dockerfile이라는 이름의 파일을 생성한다.
    Dockerfile은 Docker 이미지를 빌드하는 데 사용되는 파일인데, 아래처럼 작성하면 된다.
# base 이미지 선택
FROM node:18.16.0

# 작업 디렉토리 생성
WORKDIR /app

# 종속성 설치
COPY package*.json ./
RUN npm install

# 소스 코드 복사
COPY . .

# 포트 노출
EXPOSE 3000

# 컨테이너 시작 시 실행할 명령어
CMD [ "npm", "start" ]

FROM node:18.16.0 으로, 내가 설치한 node.js 버전과 동일하게 18.16.0을 선택했고,

WORKDIR /app 으로 폴더를 설정하고,

COPY package*.json ./ 으로 종속성(의존성) 설치를 위해 package.json과 package-lock.json을 WORKDIR에 COPY하고,

RUN npm install 명령어로 package를 설치 실행하고,

COPY . . 로 현재 프로젝트 디렉토리 전체를 WORKDIR에 복사하고,
(이때, .dockerignore로 node_modules을 무시하도록 설정해야 한다. 뒤에 다시 설명)

EXPOSE 3000 으로 node실행할 때 설정하는 PORT 값을 넣어서, Docker 이미지 외부로 열어줄 포트를 설정해 주고,

CMD ["npm", "start"] 로 컨테이너 시작할 때 실행할 명령어를 적어준다.
(이때, package.json에 script를 설정해줘야 한다.)

 

  1. Docker 이미지 빌드: 터미널을 열고 프로젝트 루트 디렉토리로 이동한 후 다음 명령어를 실행하여 Docker 이미지를 빌드한다.
docker build -t 이미지명:태그 .

예를 들어, 이미지명을 my-node-api로, 태그를 v1.0으로 설정하려면 다음과 같다.

docker build -t my-node-api:v1.0 .
  1. Docker 컨테이너 실행: 이미지를 빌드한 후에는 아래 명령어를 사용하여 컨테이너로 실행하여 API를 배포할 수 있다.
docker run -p 호스트포트:컨테이너포트 이미지명:태그

예를 들어, 호스트의 포트 8080을 컨테이너의 포트 3000에 매핑하여 컨테이너를 실행하려면 다음과 같이 실행하면 된다.

docker run -p 8080:3000 my-node-api:v1.0

 


"Error: /app/node_modules/bcrypt/lib/binding/napi-v3/bcrypt_lib.node: invalid ELF header" 발생

아까 위에서, "(이때, .dockerignore로 node_modules을 무시하도록 설정해야 한다. 뒤에 다시 설명)" 으로 해결되는 오류인데, 해결 방법은 stackoverflow 에서 찾았다. 문제의 요지는, window환경에서 설치한 bcrypt 모듈을 Docker 이미지 빌드할 때, "COPY . ." 명령어로 node_modules까지 모두 복사했기 때문에 윈도우에서 실행되는 bcrypt가 리눅스 환경(Docker는 리눅스 환경인가? 그렇다고 한다. nodejs.org에서 확인)에서 실행되지 않기 때문에 생기는 문제이다.

 

이 오류를 해결하려면, "COPY . ."할 때, node_modules 폴더를 무시해야 하는데, 무시하기 위해서는 .gitignore같이 .dockerignore 파일을 아래와 같이 만들면 된다.

# 패키지 폴더 복사 제외
node_modules/

그러고 나면 아까 Docker 이미지 파일 빌드에 사용된 명령어에서, RUN npm install 으로 설치된 것들이 그대로 사용되기 때문에 bcrypt 모듈의 바인딩 파일(bcrypt_lib.node)이 올바르지 않은 ELF(Executable and Linkable Format) 헤더를 가지고 있다는 에러가 나타나지 않게 된다.


일단 여기까지 진행하고, docker를 실행시키면 localhost의 호스트 포트로 docker 이미지로 만든 API가 잘 작동하는 것을 확인할 수 있었다.

'daily' 카테고리의 다른 글

Swagger  (0) 2023.05.16
Dockerization [1] - AWS EB에 docker 배포하기  (1) 2023.05.15
PWM 신호로 Fan 제어해 압력값 세팅하기  (0) 2023.05.15
23, 19주차  (0) 2023.05.11
3-Tier, 3-Layered Architecture  (0) 2023.05.09