Dockerfile
도커 컨테이너 이미지를 빌드하는데 필요한 모든 커맨드가 텍스트 형식으로 담긴 파일
Docker Image
도커 파일 명령어의 결과로 만들어진 읽기 전용의 레이어들로 구성됨
읽기 전용의 레이어이기 때문에 이전 레이어에서 변경된 내용이 있다면 다음 레이어가 되어 그 위에 쌓이게 된다
기본적인 가이드라인과 몇 가지 권고 사항들
- 일회용 한 컨테이너 만들기
Dockerfile에서 정의된 이미지는 가능한 가장 일회용(ephemeral)한 컨테이너를 생성해야한다
컨테이너가 일회성이라는 것은 컨테이너를 멈추고 삭제한 후 다시 빌드하고 최소한의 몇 가지 설정을 바꿔도 대체될 수 있어야 한다는 것이다
- 빌드 컨텍스트에 대해 이해하기
docker build 커맨드를 입력하면 현재 작업중인 디렉터리를 빌드 컨텍스트라고 부르게 된다
-f 플래그로 다른 위치를 지정해줄 수 있다
이미지를 빌드하는데 필요하지 않은 파일들을 추가하는 것은 빌드 컨텍스트와 이미지 크기를 키우게 된다
빌드 컨텍스트의 크기를 확인하려면 Dockerfile 빌드 시 표시되는 아래의 문구를 찾으면 된다
Sending build context to Docker daemon 187.8MB
- stdin으로 여러 Dockerfile 입력하기
Docker는 stdin 파이프를 통해 여러 Dockerfile을 처리할 수 있다
Dockerfile을 stdin으로 처리하면 디스크나 어느 곳에서든지 Dockerfile을 따로 작성하지 않아도 된다
docker build -t myimage:latest -<<EOF
FROM busybox
RUN echo "hello world"
EOF
- .dockerignoer로 파일 제외하기
빌드와 상관없는 파일을 .dockerignore을 통해 원본 레포지터리의 변경 없이 제외할 수 있다
- 멀티-스테이지 빌드 사용하기
멀티-스테이지는 중간 레이어나 파일을 줄이려고 아둥바둥 거리지 않아도 최종 이미지의 크기를 효과적으로 줄일 수 있게 해준다
이미지는 마지막 빌드 처리 과정에서 만들어지기 때문에 빌드 캐시의 이점을 활용해 이미지 레이어를 최소화 할 수 있다
만약 빌드가 여러 개의 레이어를 가지고 있을 때 수정 빈도가 낮은 레이어 부터 높은 순서로 빌드 캐시를 재사용할 수 있게 정렬할 수 있다
- 필요없는 패키지를 설치하지 않기
- 응용 프로그램 나누기
각각의 컨테이너들은 하나의 주제가 있어야 한다
응용 프로그램을 컨테이너로 나누는 것은 수평적인 구조를 만들기 쉽고 컨테이너를 재활용하기 쉽게 해준다
실제로 웹 응용 프로그램 스택은 각각 고유한 이미지를 가지고 웹, 데이터베이스, 캐시를 관리하는 세 가지 컨테이너로 나뉠 수 있다
각각의 컨테이너를 하나의 프로세스로 제한하는 것은 좋은 규칙이지만 견고하고 빠른 규칙은 아니다
컨테이너를 최대한 깨끗하고 모듈화된 구조를 유지할 수 있는 최고의 판단을 하라
- 레이어의 수 최소화하기
RUN, COPY, ADD의 세 가지 명령어는 레이어를 만든다
다른 명령어는 임시 중간 이미지를 만들고 빌드의 크기를 증가시키지 않는다
가능하면 멀티-스테이지 빌드를 사용하고 최종 이미지에서 하나의 복사만 하게하면 여러 중간 빌드 스테이지에 대한 디버그 정보를 최종 이미지 크기의 증가 없이 포함할 수 있다
- 여러줄의 인자를 정렬하기
가능하다면 여러줄의 인자들을 정렬하는 것이 좋다
정렬을 하게되면 중복 패키지를 피할 수 있고 리스트를 업데이트하기 쉽게 할 수 있다
RUN apt-get update && apt-get install -y \
bzr \
cvs \
git \
mercurial \
subversion
- 빌드 캐시의 영향력
이미지를 빌드할 때 Docker는 Dockerfile에 있는 명령어들을 하나씩 순서대로 실행시킨다
각각의 명령어들이 검사되기 때문에 Docker는 새로운 이미지를 만드는 대신 재사용 할 수 있는 캐시 이미지가 존재하는지 확인한다
모든 캐시의 사용을 원하지 않는다면 docker build --no-cache=true 옵션을 사용하라
> ADD, COPY 명령어에서 이미지의 파일들은 검사되고 각각의 파일마다 체크섬을 계산한다. 파일의 마지막 수정시간과 접근 시간은 체크섬에 고려되지 않는다
> ADD, COPY 명령어에서 캐시 체크는 컨테이너 안에 있는 파일은 비교해보지 않는다. RUN apt-fet -y update를 통해 컨테이너로 업데이트된 파일은 캐시가 존재하는지 결정할 때 고려할 대상이 아니다. 이러한 경우 커맨트 문자열만 비교한다
> 캐시가 제외되고 나면 Dockerfile의 모든 하위 명령어들은 새로운 이미지를 만들고 기존 캐시는 사용되지 않는다
권고하는 Dockerfile 명령어
- FROM
가능하면 기초 이미지는 현재 공식 이미지를 사용하라
alpine 이미지가 가장 강력하게 통제되면서 5MB 이하의 작은 크기를 갖고 있기 때문에 추천한다
- LABEL
이미지에 라벨을 추가하여 라이선스 정보를 기록하여 자동화에 도움이 될 수 있다
빈 칸을 가지고 있는 문자열은 반드시 따옴표로 묶거나 빈 칸을 탈문자 시켜야한다
- RUN
길고 복잡한 RUN 문장을 \을 이용해 여러 줄로 나누는 것은 Dockerfile을 읽기 쉽게 만들어준다
- RUN apt-get
RUN apt-get update는 apt-get install과 항상 같은 RUN 구문에서 사용해야한다
따로 쓸 경우 캐시 관련 문제를 만들고 하위 install 명령어가 실패할 수 있기 때문이다
RUN apt-get update && apt-get install -y \
aufs-tools \
automake \
build-essential \
curl \
dpkg-sig \
libcap-dev \
libsqlite3-dev
mercurial \
reprepro \
ruby1.9.1 \
ruby1.9.1-dev \
s3cmd=1.1.* \
&& rm -rf /var/lib/apt/lists/*
- 파이프 사용하기
몇몇 RUN 커맨드는 한 커맨드의 결과를 다른 커맨드의 입력으로 사용하는 파이프 기능에 의존하기도 한다
- ENV
ENV 명령어는 보통 버전 번호를 설정해 버전 충돌 관리에 자주 사용된다
- COPY
이미지 사이즈 측면에서 ADD는 추천하지 않는 방법이다
URL을 통해 원격 파일 저장소로부터 패키지를 받아와야한다면 ADD 대신 RUN에서 curl 등을 사용하도록 해라
- USER
만약 서비스가 권한 없이 실행될 수 있다면 USER를 통해 root이 아닌 일반 사용자로 변경해야한다
Dockerfile에서 사용자를 생성하고 그룹에 넣는 것은 다음과 가탇
RUN groupadd -r postgres && useradd --no-log-init -r -g postgres postgres
- OBBUILD
Dockerfile의 빌드가 끝난 후 실행하는 명령어
부모 Dockerfile이 자식 Dockerfile에게 준 명령어라 생각하면 된다
Reference
'Container > Docker' 카테고리의 다른 글
도커 환경에서 SSL 인증서 발급받기 (0) | 2024.06.26 |
---|---|
windows docker 설치 방법 (0) | 2024.05.22 |
도커 이미지를 stand alone 포터블 바이너리로 컴파일하는 도구 - dockerc (0) | 2024.03.16 |
/var/lib/docker/overlay2 가 용량을 많이 차지할때 (0) | 2023.08.25 |
도커 컨테이너 이미지 빌드 시 --build-args 를 .env 파일로 부터 읽어오기 (0) | 2023.08.25 |