[Docker] Dockerfile로 이미지 생성하기

2022. 11. 15. 00:34Backend/Docker

728x90
반응형

도커는 개발한 애플리케이션을 컨테이너화하는 일련의 과정(컨테이너 생성, 환경 설치, 소스코드 추가, 이미지로 커밋 등)을
손쉽게 기록하고 수행할 수 있는 빌드(build) 명령어를 제공한다.

1. Dockerfile

  • 이미지를 생성하기 위해 컨테이너에 설치해야 하는 패키지, 추가해야 하는 소스코드, 실행해야 하는 명령어와 셸 스크립트 등을 하나의 파일에 기록해 두면 도커는 이 파일을 읽어 컨테이너에서 작업을 수행한 뒤 이미지로 만들어낸다.
    👉🏻 이러한 작업을 기록한 파일의 이름을 Dockerfile이라고 부른다.
  • 빌드 명령어는 Dockerfile을 읽어 이미지를 생성한다.
  • Dockerfile을 사용하면 직접 컨테이너를 생성하고 이미지로 커밋해야 하는 번거로움을 덜 수 있다.
  • 생성한 이미지를 도커 허브 등을 통해 배포할 때 이미지 자체를 배포하는 대신 이미지를 생성하는 방법을 기록해 놓은 Dockerfile을 배포할 수도 있다.
  • 애플리케이션을 컨테이너화하기 위한 장기적인 시점에서 보면 Dockerfile을 작성하는 것은 이미지를 생성하는 방법을 기록하는 것뿐만 아니라 이미지의 빌드, 배포 측면에서도 유리하다.
    • 애플리케이션에 필요한 패키지 설치 등을 명확히 할 수 있다.
    • 이미지 생성을 자동화할 수 있으며 쉽게 배포할 수 있다.

 

1-1. Dockerfile 작성하기

  • 한 줄이 하나의 명령어가 된다.
  • 명령어는 소문자로 표기해도 상관없지만 일반적으로 대문자로 표기한다.
FROM node:16
# 베이스가 될 이미지

MAINTAINER juhee
# 이미지를 생성한 개발자의 정보
# 도커 1.13.0 버전 이후로는 사용하지 않는다.(LAVEL로 표현)

LABEL "purpose"="practice"
# 이미지에 메타데이터를 "키:값" 형태로 추가한다.
# 이미지뿐만 아니라 컨테이너, 엔진 등에도 이용할 수 있다.
# 원하는 조건의 컨테이너, 이미지 등을 쉽게 찾을 수 있도록 도와준다.

WORKDIR /class_build/
# 명령어를 실행할 디렉터리. 배시 셸의 cd와 동일하다.

RUN yarn install
RUN yarn build
# 컨테이너 내부에서 실행할 명령어

ADD test.html /var/www/html
COPY . /class_build/
# 이미지에 파일을 추가한다.

EXPOSE 80
# 빌드로 생성된 이미지에서 노출할 포트를 설정한다.
# 이 포트가 호스트의 포트와 바인딩 되는 것은 아님. 나타내는 것뿐!
# 이미지가 실제로 사용될 때 어떤 포트가 사용돼야 하는지 명시할 수 있으며,
# 사용하는 입장에서는 컨테이너의 애플리케이션이 컨테이너 내부에서 어떤 포트를 사용하는지 알 수 있다.

CMD yarn start
# 컨테이너가 시작될 때마다 실행할 명령어(커맨드)

 

2. 이미지 생성하기

2-1. Dokckerfile 빌드

docker build -t mybuild:0.0 ./
  • -t 생성될 이미지의 이름을 설정한다.
  • ./ build 명령어의 끝에는 Dockerfile이 저장된 경로를 입력한다.

 

2-2. 생성된 이미지로 컨테이너 실행

docker run -d -P --name myserver mybuild:0.0
  • -P EXPOSE로 노출된 포트를 호스트에서 사용 가능한 포트에 차례로 연결한다.

 

3. 빌드 과정 살펴보기

3-1. 빌드 컨텍스트

  • 이미지 빌드를 시작하면 도커는 가장 먼저 빌드 컨텍스트를 읽는다.
  • 빌드 컨텍스트는 이미지를 생성하는 데 필요한 각종 파일, 소스 코드, 메타데이터 등을 담고 있는 디렉터리를 의미하며, Dockerfile이 위치한 디렉터리가 빌드 컨텍스트가 된다.
  • 빌드 컨텍스트는 Dockerfile에서 빌드될 이미지에 파일을 추가할 때 사용된다.
  • ADD, COPY 등 이미지에 파일을 추가하는 명령어들은 빌드 컨텍스트의 파일을 이미지에 추가한다.

위치

  • 컨텍스트는 build 명령어의 맨 마지막에 지정된 위치에 있는 파일을 전부 포함한다.
  • Dockerfile이 위치한 곳에는 이미지 빌드에 필요한 파일만 있는 것이 바람직하다.
  • 루트 디렉터리(/)와 같은 곳에서 이미지를 빌드하지 않도록 주의해야 한다.
    👉🏻 단순 파일뿐 아니라 하위 디렉터리도 전부 포함하게 되므로 빌드에 불필요한 파일이 포함된다면, 빌드 속도가 느려질뿐더러 호스트의 메모리를 지나치게 점유할 수도 있다.

.dockerignore

  • 이 파일에 명시된 이름의 파일을 컨텍스트에서 제외한다.
  • 제외할 파일의 경로를 Dockerfile이 존재하는 경로를 기준으로 작성한다.
  • Dockerfile이 위치한 경로와 같은 곳에 위치해야 한다. ( = 컨텍스트의 최상위 경로 = build 명령어에서 맨 마지막에 오는 경로)

 

3-2. Dockerfile을 이용한 컨테이너 생성과 커밋

  • build 명령어로 이미지를 만드는 과정은 하나의 컨테이너에서 일어나는 것이 아니다. ❌
  • Dockerfile에서 명령어 한 줄이 실행될 때마다 이전 Step에서 생성된 이미지에 의해 새로운 컨테이너가 생성되며, Dockerfile에 적힌 명령어를 수행하고 다시 새로운 이미지 레이어로 저장된다.
    (각 Step은 Dockerfile에 기록된 명령어)
  • 이미지의 빌드가 완료되면 Dockerfile의 명령어 줄 수만큼의 레이어가 존재하게 되며, 중간에 컨테이너도 같은 수만큼 생성되고 삭제된다.
  • 이미지 빌드 중 오류가 발생했을 때는 build 명령어가 중지되며, 이미지 레이어 생성을 위해 마지막으로 생성된 임시 컨테이너가 삭제되지 않은 채로 남는다.

 

3-3. 캐시를 이용한 이미지 빌드

  • 한 번 이미지 빌드를 마치고 난 뒤 다시 같은 빌드를 진행하면 이전의 이미지 빌드에서 사용했던 캐시를 사용한다.
  • 캐시를 사용하지 않으려면 build 명령어에 --no-cache 옵션을 추가한다.
728x90
반응형