본문 바로가기

Docker

[Docker] RUN·WORKDIR·EXPOSE로 Nest.js 실행하기

 

RUN : 이미지를 생성하는 과정에서 사용할 명령문 실행

 

의미

RUN은 이미지 생성 과정에서 명령어를 실행시켜야 할 때 사용한다.

 

사용법

# 문법
RUN [명령문]

# 예시
RUN npm install

 

✅ RUN vs ENTRYPOINT

 

RUN 명령어와 ENTRYPOINT 명령어가 헷갈릴 때가 있다. 둘 다 같이 명령어를 실행시키기 때문이다

하지만 엄연히 둘의 사용 용도는 다르다. RUN은 '이미지 생성 과정'에서 필요한 명령어를 실행시킬 때 사용하고, ENTRYPOINT는 생성된 이미지를 기반으로 컨테이너를 생성한 직후에 명령어를 실행시킬 때 사용한다.

 

 

예제

미니 컴퓨터 환경이 ubuntu로 구성되었으면 좋겠고 git이 깔려있으면 좋겠다고 가정하자. 이런 환경을 구성하기 위해 Dockerfile을 활용해 ubuntu, git이 깔려있는 이미지를 만들면 된다

 

1. Dockerfile 작성하기

 

Dockerfile

 

FROM ubuntu

RUN apt update && apt install -y git

ENTRYPOINT ["/bin/bash", "-c", "sleep 500"]

 

 

 

2. 이미지 빌드 및 컨테이너 실행

 

$ docker build -t my-server .
$ docker run -d my-server
$ docker exec -it [Container ID] bash

$ git -v # 컨테이너 내에 git이 잘 설치됐는 지 확인

 


 

WORKDIR : 작업 디렉토리를 지정

 

의미

WORKDIR으로 작업 디렉터리를 전환하면 그 이후에 등장하는 모든 RUN, CMD, ENTRYPOINT, COPY, ADD 명령문은 해당 디렉터리를 기준으로 실행된다. 작업 디렉터리를 굳이 지정해주는 이유는 컨테이너 내부의 폴더를 깔끔하게 관리하기 위해서이다.
컨테이너도 미니 컴퓨터와 같기 때문에 Dockerfile을 통해 생성되는 파일들을 특정 폴더에 정리해두는 것이 추후에 관리가 쉽다. 만약 WORKDIR을 쓰지 않으면 컨테이너 내부에 존재하는 기존 파일들과 뒤섞여버린다

 

 

사용법

# 문법
WORKDIR [작업 디렉토리로 사용할 절대 경로]

# 예시
WORKDIR /usr/src/app

 

예제

1. app.txt, src, config.json 파일 만들기

 

2. Dockerfile 만들어서 이미지 생성 및 컨테이너 실행

WORKDIR을 안 썼을 때 파일이 어떻게 구성되는 지 먼저 확인해보자

 

Dockerfile

FROM ubuntu

COPY ./ ./

ENTRYPOINT ["/bin/bash", "-c", "sleep 500"] # 디버깅용 코드

 

 

$ docker build -t my-server .
$ docker run -d my-server
$ docker exec -it [Container ID] bash

$ ls

 

 

WORKDIR을 썼을 때 파일이 어떻게 구성되는 지 확인해보자

 

Dockerfile

 

FROM ubuntu

WORKDIR /my-dir

COPY ./ ./

ENTRYPOINT ["/bin/bash", "-c", "sleep 500"]

 

 

$ docker build -t my-server .
$ docker run -d my-server
$ docker exec -it [Container ID] bash

$ ls

 


 

 

EXPOSE : 컨테이너 내부에서 사용 중인 포트를 문서화하기

 

✅ 의미

EXPOSE는 컨테이너 내부에서 어떤 포트에 프로그램이 실행되는 지를 문서화하는 역할만 한다

docker -p 8080:8080 ... 와 같은 명령어의 -p 옵션과 같은 역할을 일체 하지 않는다. 쉽게 표현 하자면 EXPOSE 명령어는 쓰나 안 쓰나 작동하는 방식에는 영향을 미치지 않는다

 

 

✅ 사용법

# 문법
EXPOSE [포트 번호]

# 예시
EXPOSE 3000

 

 

[실습] 백엔드 프로젝트 (Nest.js)를 Docker로 실행시키기

 

1. Nest.js 프로젝트 만들기

# Nest CLI 설치
$ npm i -g @nestjs/cli

# nest new {프로젝트명}
$ nest new my-server

 

2. Dockerfile 작성하기

FROM node

WORKDIR /app

COPY . .

RUN npm install

RUN npm run build

EXPOSE 3000

ENTRYPOINT [ "node", "dist/main.js" ]

 

  • 심화) Docker 이미지 생성 시 캐시를 활용해서 최적화할 수 있는 방법이 있다. 입문자한테는 불필요한 내용이기 때문에 별도로 설명하지 않았다. 관심 있는 분들은 아래 링크를 참고하자

https://medium.com/@hee98.09.14/docker-layer%EC%99%80-cache-574c12a1e9f7

 

3. .dockerignore 작성하기

.dockerignore

node_modules

 

이미지를 생성할 때 npm install을 통해 처음부터 깔끔하게 필요한 의존성만 설치한다. 따라서 호스트 컴퓨터에 있는 node_modules는 컨테이너로 복사해갈 필요가 없다

 

4. Dockerfile을 바탕으로 이미지 빌드하기

$ docker build -t my-server .

 

5. 이미지가 잘 생성됐는 지 확인하기

$ docker image ls

 

6. 생성한 이미지를 컨테이너로 실행시켜보기

$ docker run -d -p 3000:3000 my-server

 

7. 컨테이너 잘 실행되고 있는 지 확인하기

docker ps

 

8. localhost:3000으로 들어가보기

9. 실행시킨 컨테이너 중지 / 삭제하기, 이미지 삭제하기

 

$ docker stop {컨테이너 ID}
$ docker rm {컨테이너 ID}
$ docker image rm {이미지 ID}