Dockerfile은 애플리케이션을 위한 build step을 명시한 텍스트 문서
Dockerfile syntax에 맞춰 작성
# Comment
INSTRUCTION arguments
INSTRUCTION은 대소문자 구분을 하지 않지만 가급적 대문자로 표기
Docker는 instruction들을 순서대로 실행
Dockerfile은 반드시 FROM
명령어로 시작해야 함
FROM
은 빌드하고자 하는 parent image를 지정한다
# syntax=docker/dockerfile:1
: optional. Dockerfile parser directives로 Dockerfile syntax의 버전을 명시한다. dockerfile:1
문법은 최신 버전의 Docker build features를 보장한다
FROM
: base image로부터 새로운 build stage를 생성
WORKDIR
: 작업 디렉토리 변경
COPY
: build context로부터 작업 디렉토리로 파일과 디렉토리 복사
RUN
: build 커맨드 실행
ENTRYPOINT
: 컨테이너 시작 시 실행할 명령어들 명시
ARG
: build-time 변수 정의
ENV
: 환경변수 정의
Dockerfile은 docker build
명령어를 통해 이미지를 생성 가능
$ docker build --tag=buildme .
tag이름(이미지 이름)을 buildme
로 하는 이미지를 현재 작업 디렉토리에 생성
build한 이미지로 container를 실행하려면 docker run
명령어를 사용한다
$ docker run --name=buildme --rm --detach buildme
buildme 이미지를 통해 컨테이너 실행
--name
: 컨테이너명을 buildme로 설정
--rm
: 실행 종료 시 자동으로 컨테이너 삭제
--detach
: 백그라운드에서 실행
테스트가 끝나면 컨테이너 중지
$ docker stop buildme
--rm
옵션에 의해 자동으로 컨테이너가 삭제된다
Docker build는 순서가 있는 build 명령어로 구성된다
Dockerfile의 각 명령어는 위와 같이 image layer로 translate된다
builder는 이미지의 layer가 바뀌지 않았다면 build cache로부터 layer를 재사용한다
layer가 바뀌었다면 해당 layer와 해당 layer의 뒤에 있는 모든 layer는 rebuild된다
위 이미지의 모든 프로젝트 파일을 컨테이너로 복사하는 COPY . .
명령어에서, 프로젝트 파일이 수정되었다면 COPY
layer의 cache는 invalid가 된다. 그로 인해 해당 layer 뒤에 모든 layer 또한 invalid가 된다
위와 같은 명령어들의 순서 때문에 필요없는 명령어들도 rebuild될 수 있다
예를들어 위 예제에서 go 모듈이 바뀌지 않았음에도 다시 다운로드 해야 한다. 때문에 명령어들의 실행 순서를 잘 고려할 필요가 있다
위와 같이 명령어의 순서를 바꿔주면 같은 go 모듈을 다시 다운로드 하지 않을 수 있다
참고자료:
https://docs.docker.com/build/guide/intro/
https://docs.docker.com/engine/reference/builder/