[Docker] Node.js 앱만들기

2023. 8. 10. 13:23초기 과업/DevSecOps

작성자알 수 없는 사용자

728x90
반응형

 
안녕하세요. 기깔나는 사람들에서 DMSO를 맡고있는 정우입니다.

오늘은 Node.js 앱을 만들어보겠습니다. 


NodeJs 앱만들기 순서

package.json : 프로젝트의 정보와 프로젝트에서 사용중인 패키지의 의존성을 관리하는곳
server.js : 시작점으로서 가장먼저 시작되는 파일
 
package.json 만들기 순서
 
패키지하나만들기

 

$ npm init

 
 "main"을 index.js 가 아닌 server.js로 변경해주겠습니다.

 
package.json이 생성된게 보입니다. 

 
express 모듈 : Node.js 의 단순화하고 새로운 기능을 추가해서 Node.js를 더 쉽고 유용하게 사용할 수 있습니다. 
그러기 위해 라이브러리를 넣어주겠습니다.
 
가장 최신버전을 사용할게요 

 
 
start :  어떤 것을 먼저 실행할 건지 명시해주기

 
 


server.js생성

server.js 파일을 만들어줍니다
 

 

 
server.js 내부 

// Express 모듈 가져오기
const express = require('express');

const PORT = 8080; //express를 위한 포트설정
//const HOST = ; //현재 사용 x

//APP
const app = express();

//'/' 경로로 요청이 들어오면 "Hello world"라는 문구를 보내주겠다! 
app.get('/', (req, res) => {
    res.send("Hello World")
});

// listen된 포트에서 실행됩니다.
app.listen(PORT);

# 서버가 실행중이면 콘솔에 넣어주기
console.log("server is running")

 
 
 


Dockerfile 작성

Nodejs 앱을 도커환경에서 실행하려면

  1.  이미지를 생성
  2. 이미지를 이용해서 컨테이너를 실행한후
  3. 그 컨테이너 안에서 Nodejs 앱 실행

 
Dockerfile을 작성해줍니다. 
 

 

# 베이스 이미지를 명시해줍니다.
FROM node:10

# 추가
RUN npm install

CMD ["node", "server.js"]

 
 
 
npm install
package.json을 바라보고 필요한 library를 다운받게 해줍니다. 

 


docker build

Dockerfile을 모두 작성했는데 docker build . 를 통해 이미지를 생성해 보겠습니다. 

 
 
강의에서는 package.json 없다는 에러가 난다고하는데
저는 정상적으로 작동됐습니다.
 
만약 package.json이 없다는 에러가 뜨시는 분들은 
노드 베이스 이미지를 임시 컨테이너에 넣어서 사용하게되는데
임시컨테이너 안에는 package,json이 없기때문에 에러가 발생하는 것이라고 합니다. 
 

 
 
이걸 해결하기 위해서
COPY를 사용해 package를 만들어서 컨테이너 안으로 넣어서 관리 해주는게 좋습니다.
 
COPY 사용법

COPY  package.json <내가 사용할 경로>

 

# 베이스 이미지를 명시해줍니다.
FROM node:10

# COPY 해주기
COPY package.json ./

# 추가
RUN npm install

# node 웹서버를 작동시키려면 node + 엔트리 파일 이름이 필요합니다 .
# 우리가 설정한 엔트리 파일은 server.js입니다.
CMD ["node", "server.js"]

 
 
이번에 빌드는 이름을 줘서 사용해보겠습니다.

 
실행해보기

$ docker run jjwdocker/nodejs:latest

 
server .js 오류

 
package.json과 같은이유!
 
 
컨테이너 안에 COPY 해줍니다
어차피 전체 파일 패키징 해주면 되니 현재 경로로 지정해줄게요
 

# 베이스 이미지를 명시해줍니다.
FROM node:10

# COPY 해주기
# 어차피 전체 파일 다 패키징 하면 되니까 ./ ==> 현재 경로 사용하기
COPY ./ ./


# 추가
RUN npm install

# node 웹서버를 작동시키려면 node + 엔트리 파일 이름이 필요합니다 .
# 우리가 설정한 엔트리 파일은 server.js입니다.
CMD ["node", "server.js"]

 
 
 
 
다시 빌드 해보겠습니다. 
 

 

$ docker run jjwdocker/nodejs:latest

 
 

$ docker ps -a

 
 
localhost:8080으로 접속
잘 떠있는데 왜 안될까ㅜ

 
생성한 이미지로 어플리케이션 접근 안되는 이유
 
현재까지 사용했던 명령어
docker run 이미지 이름
 
 
앞으로 사용해야 할 명령어
docker run -p  <로컬호스트 네트워크> : <내가 도커 컨테이너 내에서 설정한 네트워크 포트> 이미지 이름
 
로컬호스트 네트워크도커 내부에서 사용하는 포트를 연결해줘야합니다. 
 
예를 들어
5000번을 로컬호스트 네트워크로 사용하고 ,
8080번을 도커 컨테이너 내에서 설정한 네트워크 포트로 사용하겠다  

 
localhost :5000 접속

 
 
 
내가 도커 Image로 사용한 이름과
포트를 확인해보겠습니다.

$ docker ps -a

 


Working Directory 설정

 
Dockerfile에 WORKDIR를 설정해줘야합니다

 

# 베이스 이미지를 명시해줍니다.
FROM node:10

# WORKDIR
WORKDIR /usr/src/app


# COPY 해주기
# 어차피 전체 파일 다 패키징 하면 되니까 ./ ==> 현재 경로 사용하기
COPY ./ ./

# 추가
RUN npm install

# node 웹서버를 작동시키려면 node + 엔트리 파일 이름이 필요합니다 .
# 우리가 설정한 엔트리 파일은 server.js입니다.
CMD ["node", "server.js"]

 
 
Working Directory란?
이미지 안에서 애플리케이션 소스 코드를 갖고있을 디렉토리를 생성하는 것
 
왜 따로 Working Dir 가 필요한가?
 
copy 한것들이 이미지 안으로 들어오게 됩니다. 

$ docker run -it jjwdocker:nodejs sh
  1.  혹시라도 이중에 원래 이미지에 잇던 파일과 이름이 같아버린다면?
  2.  모든 파일이 한 디렉토리에 있으니 정리정돈이 안된다.

다시 빌드 해볼겠습니다.

$ docker buld -t jjwdocker/nodejs ./

 
 
file system을 다시 확인해볼게요
 

$ docker run -it <이미지 이름> sh 

$ docker run -it jjwdocker/nodejs:latest sh

$ ls 

$ pwd

 


어플리케이션 소스 변경으로 다시 빌드하는 것의 문제점

지금까지 실행중에 어플리케이션이 변경될때마다 
build를 진행했습니다. 
 
소스 하나 변경됐다 해서 
이게 효율적인 것인가? 
 
Server.js에서 다시 변경해줄게요
Hello World -> 반갑습니다.
 

 
 
 
기존의 방식
$ docker build -t jjwdocker/nodejs ./
$ docker run -d -p 4000:8080 

 
 
 
그럼 효율적으로 어떻게 하나???
 
우선 패키지를 먼저 COPY 해줍니다.
변경된 부분
AS-IS 

 
TO-BE

 
npm install을 할때는 불필요한 다운로드를 피하기 위해서 입니다.
이미 설치되어있는 npm이 있는지 확인하고
있으면 install
없으면 다음으로 넘어가기때문에 효율적입니다. 
 

# 베이스 이미지를 명시해줍니다.
FROM node:10

# WORKDIR
WORKDIR /usr/src/app

# COPY 해주기
COPY package.json ./

# 추가
RUN npm install


# 어차피 전체 파일 다 패키징 하면 되니까 ./ ==> 현재 경로 사용하기
COPY ./ ./

# node 웹서버를 작동시키려면 node + 엔트리 파일 이름이 필요합니다 .
# 우리가 설정한 엔트리 파일은 server.js입니다.
CMD ["node", "server.js"]

 
다시 server.js 부분을 다시  변경 시키고 빌드해보겠습니다.
 
반가워요 -> 반가워요!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 

 
 

$ docker build ./

훨씬 빨라진것을 볼 수 있습니다. 
 
 
 


도커 Volume
아직도 소스를 변경할 때마다 
변경된 소스 부분은 COPY 한 후 이미지를 다시 빌드를 해주고 컨테이너를 다시 실행해줘야 변경된 소스가 화면에 반영이 됩니다. 
너무나 시간 소요가 크며 이미지도 너무나 많이 빌드하게 되기 때문에 
 
효율적으로 실행하기 위해
Volume을 사용하게 된다. 
 
docker run -o 5000:8080 -v /usr/src/app/node_modules -v 현재디렉토리:/usr/src/app <이미지ID>
 
-v /usr/src/app/node_modules: 호스트 디렉토리에서는 node_module은 필요가 없기때문에 컨테이너에 매핑하지말아라
-v ./usr/src/app : pwd경로에 있는 디렉토리 혹은 파일을 /usr/src/app 경로에서 참조
 
빌드를 하고 실행해볼겠습니다.
 

$ docker build ./

$ docker run -d -p 5000:8080 -v /usr/src/app/node_modules -v .:/usr/src/
app jjwdocker/nodejs:latest

 
 

 
소스코드가 바뀌어도 바로 실행되도록 한것 : Volume
 

 
도커 app을 반영해주기 위해 컨테이너 다시 껐다가 켜보겠습니다.
 

 
다시 실행을 해줄게요
 
 

docker run -d -p 5000:8080 -v /usr/src/app/node_modules -v .:/usr/src/app jjwdocker/nodejs:latest

 
 
 


 
오늘은 Nodejs 앱을 설치하며 
도커 이미지, 컨테이너 를 어떻게 사용하는지 알아보았는데
 
다음엔 Docker Compose란 무엇인지 공부해볼게요.
 
 
 


참고자료

🔗 - 인프런- 따라하며 배우는 도커와 CI 환경
 

 
 
 

728x90
반응형