시작으로


예전에 FastAPI 서버를 Docker에 배포한 경험이 있다. 하지만 Node.js 서버를 Docker에 다시 배포하려고 하니 기억이 가물가물 했다. 역시 정리하는 것보다 다시 찾는게 더 귀찮은 일이다…

그래서, 핵심만 정리하여 지식으로 남긴다.

사전 필수 준비물

  • 카카오 클라우드 ubuntu 18.04
  • docker 설치완료
  • 포트 포워딩 (외부->내부로 접속해야 하므로)
  • 배포 할 app

위의 필수 준비는 끝냈다는 가정하에 시작하겠다.


Dockerfile이란?


  • Dockerfiledocker 이미지를 생성하기 위한 설정 파일이다.
  • Dockerfile안에 작성된 명령어를 기반으로 빌드한다.
  • Dockerfile에 작성된 명령어들을 차례대로 수행하여 docker 이미지를 생성한다.
  • Dockerfile은 이미지가 어떻게 구성되어있는지 알 수 있다.


Dockerfile 왜 사용할까?


이미지가 어떻게 구성되어 있는지 알 수 있다.

완성된 도커 이미지를 가져다 쓰는 경우에는 알 필요가 없지만, 완성된 애플리케이션을 도커 이미지에 담기 위해서는 환경설정부터 디렉토리 구조 및 명령어들을 하나하나 신경써서 작성해야 한다. 도커 이미지라는게 결국 가상의 서버환경이다. 실제 서버에 배포해야 될 과정을 이미지에 담는 것이다. 이는, Dockerfile은 자동화된 스크립트 형태이기 때문이다.

배포가 용이하다

어떠한 이미지를 배포할 때, 몇 기가씩이나 되는 이미지 파일 자체를 배포하기보다는 그 이미지를 만들 수 있는 스크립트인 Dockerfile만을 배포한다면 매우 편리할 것이다. Dockerfile을 실행시키기만 하면 알아서 Dockerfile에 해당하는 이미지를 생성해준다.

컨테이너(이미지)가 특정 행동을 수행하도록 한다.

컨테이너 환경에서 애플리케이션을 개발하다 보면, 특정 행동을 취하도록 하는 컨테이너를(이미지를) 만들어야 할 때가 있다. 이를 Dockerfile로 작성하면 간단하게 작성할 수 있다.


Dockerfile 작성 방법


  • 파일명은 “Dockerfile”로 작성해야 한다.
  • Dockerfile 작성 내용이 아래와 같이 작성하겠다고 가정하자.
FROM node:16

WORKDIR /home/workspace

COPY . ./

RUN npm install

EXPOSE 3000
CMD ["npm", "run", "start"]
  • FROM: 베이스 이미지
    • 어느 이미지에서 시작할건지를 의미한다.
    • 기본 이미지를 node 16 버전을 사용한다는 의미이다.
  • WORKDIR: 컨테이너(이미지)의 작업 디렉토리를 지정한다.
    • 작업 디렉토리를 지정하면 그 이후 명령어는 해당 디렉토리를 기준으로 동작한다.
    • cd 명령어와 동일하다.
  • COPY/ADD: build 명령 중간에 호스트의 파일 또는 폴더를 이미지에 가져오는(복사하는) 것이다.
    • ADD 명령문은 좀 더 파워풀한 COPY 명령문이라고 생각할 수 있다.
    • ADD 명령문은 일반 파일 뿐만 아니라 압축 파일이나 네트워크 상의 파일도 사용할 수 있다.
    • 이렇게 특수한 파일을 다루는 게 아니라면 COPY 명령문을 사용하는 것이 권장된다.
  • RUN: 새로운 레이어에서 명령어를 실행하고, 새로운 이미지를 생성한다.
  • EXPOSE: Dockerfile의 빌드로 생성된 이미지에서 열어줄 포트를 의미한다.
    • 호스트 머신과 컨테이너의 포트 매핑시에 사용된다.
    • 컨테이너 생성 시 -p 옵션의 컨테이너 포트 값으로 EXPOSE 값을 적어야한다.
  • CMD: 컨테이너를 생성,실행 할 때 실행할 명령어
    • docker run 명령으로 컨테이너를 생성하거나, docker start 명령으로 정지된 컨테이너를 시작할 때 실행된다.
    • 보통 컨테이너 내부에서 항상 돌아가야하는 서버를 띄울 때 사용한다.


그럼 저 Dockerfile을 해석해보면 다음과 같다.

  • 기본이미지를 node 16 버전으로 사용하겠다.
    FROM node:16
    


  • 컨테이너 작업 디렉토리는 /home/workspace을 기준으로 하겠다.
    WORKDIR /home/workspace
    


  • Dockerfile이 있는 디렉토리의 모든 것을 복사하여 WORKDIR에 복사하겠다.
  • . 은 모든 것을 복사하겠다는 의미이다. 만약 특정 파일 및 디렉토리를 복사할꺼면 copy.js와 같이 명시해주면 된다.
    COPY . ./
    


  • 컨테이너 안에서 npm install 명령어를 실행하겠다.
    RUN npm install
    


  • 3000번 포트를 열어주겠다.
    EXPOSE 3000
    


  • 컨테이너가 실행될 때 npm run start명령어를 실행하겠다.
    CMD ["npm", "run", "start"]
    


Dockerfile을 이미지로 빌드하기


  • 빌드 명령어
     docker build -t [이미지 이름:이미지 버전] [Dockerfile의 경로]
    
    docker build -t node_app_from_docker .
    
  • 생성된 도커 이미지 확인
    docker images
    REPOSITORY             TAG                IMAGE ID       CREATED          SIZE
    node_app_from_docker   latest             4dbe1e4ed445   33 seconds ago   958MB
    


Container 생성


  • --name : 컨테이너 이름
  • -d : 백그라운드 모드로 실행
  • -p : [호스트포트][컨테이너포트] 포트연결(외부-내부)
  • 마지막은 생성했던 이미지 이름
    docker run --name=node_app_from_docker_container -d -p 8071:3000 node_app_from_docker
    
  • 컨테이너 확인
    docker ps -a
    CONTAINER ID   IMAGE                  COMMAND                  CREATED          STATUS          PORTS                                                                                      NA
    eab42d556f2b   node_app_from_docker   "docker-entrypoint.s…"   14 seconds ago   Up 13 seconds   0.0.0.0:8071->3000/tcp, :::8071->3000/tcp                                                  no
    


접속 확인


ip는 보안상 가렸다. 중요하건 컨테이너 생성시 설정했던 8071 -> 3000으로 접속된다는 사실이다.

잘 접속되는 것을 확인할 수 있다.

image