Dandy Now!
  • Docker를 활용한 Nest.js 애플리케이션 컨테이너화 및 관리
    2025년 07월 18일 18시 42분 51초에 업로드 된 글입니다.
    작성자: DandyNow
    728x90
    반응형

    Docker를 활용한 Nest.js 애플리케이션 컨테이너화 및 관리

    1. Nest.js 프로젝트 생성

    my-nest-server 프로젝트를 생성 후 해당 프로젝트로 이동, 해당 프로젝트 내에서 Dockerfile을 생성하면 된다.

    C:\Users\dandycode\Documents\GitHub\docker-practice>nest new my-nest-server

    2. Dockerfile 생성

    FROM node
    
    WORKDIR /app
    
    COPY . .
    
    RUN npm install
    
    RUN npm run build
    
    EXPOSE 3000
    
    ENTRYPOINT [ "node", "dist/main.js" ]
    • FROM node
      • 이 Dockerfile은 Node.js 런타임이 포함된 공식 node 이미지를 기반으로 시작한다. 즉, Node.js 개발 환경을 따로 구축할 필요 없이 바로 사용 가능하도록 준비된 환경에서 시작한다는 의미이다.
    • WORKDIR /app
      • 컨테이너 내부에서 작업할 기본 디렉토리를 /app으로 설정한다. 이후에 실행되는 모든 명령어(예: 파일 복사, 명령 실행)는 이 디렉토리 안에서 이루어진다.
    • COPY . .
      • Dockerfile이 위치한 호스트(로컬 컴퓨터)의 현재 디렉토리(.)에 있는 모든 파일과 폴더를 컨테이너 내부의 작업 디렉토리(/app)로 복사한다. 이 단계에서 Node.js 프로젝트의 소스 코드가 컨테이너 안으로 들어간다. 별도의 .dockerignore 파일을 생성하여 node_module 폴더는 도커 빌드에 포함되지 않도록 한다.
    • RUN npm install
      • 컨테이너 내부에서 npm install 명령어를 실행하여 package.json 파일에 정의된 모든 프로젝트 의존성 패키지를 설치한다.
    • RUN npm run build
      • 프로젝트의 빌드 스크립트를 실행한다. 예를 들어, TypeScript로 작성된 코드를 JavaScript로 컴파일하거나, React나 Vue 같은 프론트엔드 프로젝트를 배포 가능한 형태로 변환하는 과정을 수행한다.
    • EXPOSE 3000
      • 이 컨테이너가 런타임 시 3000번 포트를 통해 서비스를 제공할 것이라고 Docker에게 알려주는 역할을 한다. 이는 일종의 "문서화" 개념으로, 실제로 호스트 컴퓨터와 컨테이너의 포트를 연결하려면 docker run 명령어에 추가 옵션이 필요하다.
    • ENTRYPOINT [ "node", "dist/main.js" ]
      • 컨테이너가 시작될 때 자동으로 실행될 명령어를 지정한다. 여기서는 Node.js 런타임으로 빌드된 애플리케이션의 메인 파일인 dist/main.js를 실행하여 Nest.js 서버를 구동시킨다.

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

    이제 작성된 Dockerfile을 사용하여 Docker 이미지를 빌드하고, 이 이미지를 통해 컨테이너를 실행하는 과정을 살펴보자.

    1. 이미지 빌드:

      C:\Users\dandycode\Documents\GitHub\docker-practice\my-nest-server>docker build -t my-nest-server .
      • 이 명령어는 현재 디렉토리(.)에 있는 Dockerfile을 사용하여 my-nest-server라는 이름의 Docker 이미지를 빌드한다.
    2. 컨테이너 실행:

      C:\Users\dandycode\Documents\GitHub\docker-practice\my-nest-server>docker run -d -p 3000:3000 my-nest-server
      e315d306905088af8170cdde76884898f590d4a84521d2ecaff5c513ee95a9bb
      • 빌드된 my-nest-server 이미지를 기반으로 컨테이너를 실행한다.
      • -d 옵션은 컨테이너를 백그라운드(detached mode)에서 실행하여 터미널을 계속 사용할 수 있도록 한다.
      • -p 3000:3000 옵션은 호스트 컴퓨터의 3000번 포트와 컨테이너 내부의 3000번 포트를 연결(포트 포워딩)한다. 이로써 호스트에서 localhost:3000으로 접속하면 컨테이너 내부의 Nest.js 애플리케이션에 접근할 수 있게 된다.
      • 명령어를 실행하면 컨테이너 ID(e315d3069050...)가 출력된다.

    4. 실행 중인 컨테이너 확인

    컨테이너가 잘 실행되고 있는지 docker ps 명령어로 확인할 수 있다.

    C:\Users\dandycode\Documents\GitHub\docker-practice\my-nest-server>docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
    e315d3069050        my-nest-server      "node dist/main.js" 6 seconds ago       Up 6 seconds        0.0.0.0:3000->3000/tcp   compassionate_buck
    • CONTAINER ID: 컨테이너의 고유 식별자이다.
    • IMAGE: 컨테이너를 생성하는 데 사용된 이미지 이름이다.
    • COMMAND: 컨테이너가 실행될 때 수행하는 명령어이다.
    • CREATED: 컨테이너가 생성된 시점이다.
    • STATUS: 컨테이너의 현재 상태이다. Up은 컨테이너가 정상적으로 실행 중임을 나타낸다.
    • PORTS: 포트 매핑 정보이다. 0.0.0.0:3000->3000/tcp는 호스트의 모든 IP 주소의 3000번 포트가 컨테이너의 3000번 포트와 연결되었음을 의미한다.
    • NAMES: Docker가 자동으로 할당한 컨테이너 이름이다. (여기서는 compassionate_buck)

    5. 컨테이너 내부 접속 및 파일 확인

    실행 중인 컨테이너 내부로 접속하여 파일 시스템을 확인하거나 명령어를 실행할 수 있다.

    1. 컨테이너 내부 접속:

       C:\Users\dandycode\Documents\GitHub\docker-practice\my-nest-server>docker exec -it e3 bash
       root@e315d3069050:/app#
      • docker exec -it e3 bash 명령어를 사용하여 컨테이너 ID e3 (정확히는 e315d3069050)에 bash 셸로 접속한다.
      • -i 옵션은 상호작용 모드를 활성화하여 표준 입력을 열어두고, -t 옵션은 의사 터미널을 할당하여 터미널 환경처럼 사용할 수 있도록 한다.
    2. 컨테이너 내부 파일 확인:

      root@e315d3069050:/app# ls -al
      total 408
      drwxr-xr-x   1 root root    4096 Jul 18 09:03 .
      drwxr-xr-x   1 root root    4096 Jul 18 09:16 ..
      -rwxr-xr-x   1 root root      14 Jul 18 09:02 .dockerignore
      -rwxr-xr-x   1 root root     663 Jul 18 08:57 .eslintrc.js
      drwxr-xr-x   6 root root    4096 Jul 18 08:58 .git
      -rwxr-xr-x   1 root root     391 Jul 18 08:58 .gitignore
      -rwxr-xr-x   1 root root      51 Jul 18 08:57 .prettierrc
      -rwxr-xr-x   1 root root     133 Jul 18 09:02 Dockerfile
      -rwxr-xr-x   1 root root    3340 Jul 18 08:57 README.md
      drwxr-xr-x   2 root root    4096 Jul 18 09:03 dist
      -rwxr-xr-x   1 root root     171 Jul 18 08:57 nest-cli.json
      drwxr-xr-x 487 root root   20480 Jul 18 09:03 node_modules
      -rwxr-xr-x   1 root root  327035 Jul 18 09:03 package-lock.json
      -rwxr-xr-x   1 root root    1955 Jul 18 08:57 package.json
      drwxr-xr-x   2 root root    4096 Jul 18 08:57 src
      drwxr-xr-x   2 root root    4096 Jul 18 08:57 test
      -rwxr-xr-x   1 root root      97 Jul 18 08:57 tsconfig.build.json
      -rwxr-xr-x   1 root root     546 Jul 18 08:57 tsconfig.json
      • ls 명령어로 /app 디렉토리의 파일 목록을 확인한다. Dockerfile에서 COPY . . 명령어를 통해 복사된 Node.js 프로젝트 파일들이 모두 컨테이너 내부에 존재함을 알 수 있다.
      • ls -al 명령어로 자세한 파일 정보를 확인할 수 있다.
    3. 컨테이너 내부 종료:

      root@e315d3069050:/app# exit
      exit
      • exit 명령어를 입력하여 컨테이너 내부의 셸 세션을 종료하고 다시 호스트 터미널로 돌아간다.

    6. 컨테이너 종료 및 삭제

    더 이상 필요 없는 컨테이너는 종료하고 삭제할 수 있다.

    1. 실행 중인 컨테이너 확인:

      C:\Users\dandycode\Documents\GitHub\docker-practice\my-nest-server>docker ps
      CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
      e315d3069050        my-nest-server      "node dist/main.js" 13 minutes ago      Up 13 minutes       0.0.0.0:3000->3000/tcp   compassionate_buck
      • 컨테이너가 여전히 실행 중임을 확인한다.
    2. 컨테이너 강제 종료 및 삭제:

      C:\Users\dandycode\Documents\GitHub\docker-practice\my-nest-server>docker rm -f e3
      e3
      • docker rm -f e3 명령어를 사용하여 컨테이너 ID e3 (즉, e315d3069050) 컨테이너를 강제로 종료(-f)하고 삭제한다.
      • -f 옵션은 컨테이너가 실행 중일 때도 강제로 삭제할 수 있도록 한다. 만약 컨테이너가 정지된 상태라면 -f 옵션 없이 docker rm [CONTAINER ID]로 삭제할 수 있다.

    728x90
    반응형
    댓글