올바른 Dockerfile 작성을 위한 가이드라인

​ ​

Docker가 처음이라면, 이전 포스팅을 참고하시기 바랍니다.

Dockerfile

Dockerfile은 일종의 이미지 설정파일입니다. 생긴 모양새는 쉘 스크립트와 유사하지만 자체의 문법을 가지고 있습니다. 이렇게 작성된 Dockerfile은 build 명령어를 통해 이미지를 생성할 수 있습니다.

이 포스팅에서는 Dockerfile 레퍼런스에 나와 있는 가이드라인을 정리해보도록 하겠습니다. https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/에 자세한 내용이 설명되어 있습니다.

컨테이너는 일시적이어야 한다

일시적이라는 말은 가능한 최소한의 설정 및 구성으로 이루어져있어야 한다는 것을 의미합니다. 이에 대한 내용은 Twelve Factors Application을 참고하시면 좋습니다.

​ ​

.dockerignore을 활용하자

대부분의 경우 각 Docker 파일을 빈 디렉토리에 저장하는 것이 가장 좋습니다. 그런 다음 Dockerfile을 빌드하는 데 필요한 파일만 해당 디렉토리에 추가하시면 됩니다. 빌드의 성능을 높이려면 해당 디렉토리에 .dockerignore 파일을 추가하여 파일 및 디렉토리를 제외 할 수 있습니다. .dockerignore 파일은 .gitignore 파일과 유사하게 동작한다고 보시면 됩니다.

*.md
!README.md

위와 같은 .dockerignore 파일은 README.md 파일을 제외한 모든 마크다운 파일을 제외시킵니다. 이런식으로 원하지 않는 파일 및 디렉토리를 제외시켜 이미지의 용량을 줄일 수 있습니다.

불필요한 패키지를 설치하지 말자

복잡성, 의존성, 파일 크기 및 빌드 시간을 줄이기 위해서는 불필요한 패키지를 설치하지 말아야 합니다. 예를 들어, 데이터베이스 이미지에 텍스트 편집기를 포함시킨다거나 하는 일은 없어야 합니다.

컨테이너는 오직 하나의 관심사만 갖는다

애플리케이션을 여러 컨테이너로 분리하면 컨테이너를 확장하고 재사용하는 것이 훨씬 쉬워집니다. 예를 들어, 일반적인 어플리케이션은 웹 어플리케이션, 데이터베이스, 인메모리-캐시와 같이 세 개의 컨테이너로 구성 될 수 있습니다.

컨테이너 당 하나의 프로세스 가 있어야한다는 말을 들어 보셨을 겁니다. 하지만, 언제나 컨테이너 당 하나의 운영 체제 프로세스만 있어야 하는 것은 아닙니다. 컨테이너가 init 프로세스로 생성 될 수 있다는 사실 외에도 일부 프로그램은 자체적으로 추가 프로세스를 생성 할 수 있습니다. 예를 들어 Celery는 여러 작업자 프로세스를 생성하거나 Apache 스스로 요청에 따른 프로세스를 생성 할 수 있습니다. 컨테이너를 깔끔한 모듈 형식으로 유지하기 위해 신중히 선택해야 합니다. 컨테이너에 서로 의존성이 생기는 경우 Docker 컨테이너 네트워크를 사용하여 서로 통신 할 수 있습니다.

레이어의 수를 최소화하자

사용하는 레이어의 수에 대해 전략적이고 신중해야합니다. 장기적인 관점에서 보았을 때 유지보수를 위해서는 레이어의 수를 최소화하는 것이 현명한 선택이 될 수 있습니다.

줄바꿈을 사용하여 정렬하자

RUN apt-get update && apt-get install -y \
  bzr \
  cvs \
  git

위와 같이 줄바꿈을 사용하면, 패키지의 중복을 피하고 목록을 훨씬 쉽게 업데이트 할 수 있습니다. 백 슬래시 (\) 앞에 공백을 추가하면 가독성을 높이는 데에 도움이됩니다.

캐시를 활용하여 빌드하자

이미지를 작성하는 과정에서 Docker는 지정한 순서대로 Dockerfile을 단계 별로 실행합니다. 각 명령을 실행할 때 Docker는 매번 새로운 이미지를 만드는 대신 캐시에서 기존 이미지를 찾아 재사용 할 수 있습니다. 캐시를 전혀 사용하지 않으려는 경우 docker 빌드 명령에서 --no-cache = true 옵션을 사용하시면 됩니다.

Docker가 캐시를 사용하게하려면 일치하는 이미지를 찾을 때와 그렇지 않을 때를 이해하는 것이 매우 중요합니다. Docker cache의 기본 규칙은 다음과 같습니다.

  • 이미 캐시에 있는 기본 이미지로 시작하여 다음 명령어가 해당 기본 이미지에서 파생된 모든 하위 이미지와 비교되어 그 중 하나가 정확히 동일한 명령어를 사용하여 빌드되었는지 확인합니다. 그렇지 않으면 캐시가 무효화됩니다.

  • ADD, COPY 명령을 제외하고 캐시 검사는 컨테이너의 파일을보고 캐시 일치를 판별하지 않습니다. 예를 들어 RUN apt-get -y update 명령을 처리 할 때 컨테이너에서 업데이트 된 파일은 캐시 히트가 있는지 여부를 확인하기 위해 검사되지 않습니다. 이 경우 명령 문자열 자체만 일치하는지 확인합니다.

  • 캐시가 무효화되면 이후의 모든 Dockerfile 명령은 새로운 이미지를 생성하고 캐시는 사용되지 않습니다.

​ ​