Dockerfile의 모든 것
· 약 7분
- FROM: 빌드하는 이미지의 기반 이미지 지정
- RUN: 이미지 빌드 시 컨테이너에서 실행할 명령어 정의
- COPY: 호스트에서 컨테이너로 파일 및 디렉토리 복사
- ADD: COPY + 압축 해제 + URL 다운로드
- 운영 체제를 담은 기반 이미지를 만드는 경우처럼 특수한 경우에만 사용하면 된다.
- 안정성 보장이 되지 않으므로 COPY 를 사용하자.
- CMD: 컨테이너에서 foreground로 실행할 명령어 정의
- ENTRYPOINT: 컨테이너를 실행 가능 파일로 사용할 때 정의하는 명령
- CMD 와 ENTRYPOINT 둘 다 사용 가능
- ARG: docker image build를 실행할 때 사용하는 변수
- ENV: 컨테이너 안의 환경변수 정의
- EXPOSE: 컨테이너가 노출하는 포트
- VOLUME: 호스트나 다른 컨테이너에서 마운트할 수 있는 포인트 생성
- LABEL: 이미지에 추가하는 메타데이터
- STOPSIGNAL: 컨테이너에 전달되면 컨테이너를 종료하는 시스템 시그널 설정
- HEALTHCHECK: 컨테이너 안에서 명령을 실행 후 결과를 헬스 체크에 사용
- USER: 컨테이너 실행 시 컨테이너 사용자
- 이미지 빌드시 USER 뒤에 나오는 RUN 인스트럭션도 해당 사용자의 권한으로 실행된다.
- WORKDIR: 컨테이너의 작업 디렉토리
- ONBUILD: 컨테이너 안에 서 실행되는 명령 정의, 이미지에서 실행되지 않는다.
- ONBUILD 를 정의한 이미지를 기반 이미지로 삼아 다른 이미지를 빌드할 때 실행된다.
이미지
린팅
hadolint 를 설치해 Dockerfile best practices 에 기반해 이미지를 생성했는지 검증하자.
기반 이미지
- scratch: 아무 것도 없는 이미지
- https 통신이 필요한 경우 cacert.pem 을 /etc/ssl/certs 에 추가해야한다.
- 디버깅도 힘들다
- busybox: 기본 유틸리티 (echo, ls 등) 이 있는 이미지
- 패키지 관리자가 없다.
- 디버깅은 좀 낫다.
- alpine: busybox 기반으로 4MB 지만
apk
패키지 매니저가 있다.glibc
대신musl
을 쓴다.apk add --no-cache package
apk add --no-cache --virtual=ailas package
&&apk del --no-cache ailas
멀티스테이지 빌드
golang과 같은 빌드가 필요한 이미지에서는 멀티스테이지 빌드를 이용해 빌드 환경과 프로덕션 환경을 다르게 가져갈 수 있다.
FROM golang:1.9 AS build
WORKDIR /
COPY . /go/src/github.com/...
RUN go get gokpg.in/gorp.v1
RUN cd /go/src/github.com/... && go build -o bin/start main.go
FROM alpine:3.7
COPY --from=build /go/src/.../bin/start /usr/local/bin/
CMD ["start"]
distroless 이미지
- 운영체제 기능은 없이 언어에 중점을 둔 이미지이다.
- distroless 에서 확인 가능하며 주로 구글이 배포한다.
- gcr.io/distroless/base 이미지는 glibc 기반이며 컴파일 애플리케이션을 실행하는 데에 적합하다. (Go)
- ca-certificates 및 TLS/SSL 관련 라이브러리 등 최소한의 라이브러리만 있다.
- CVE 취약점도 업데이트 된다고 한다.
FROM node:10.17.0 AS build-env
ADD . /app
WORKDIR /app
FROM gcr.io/distroless/nodejs
COPY --from=build-env /app /app
WORKDIR /app
CMD ["hello.js"]
chucksum 검증
ADD
인스트럭션으로 추가 된 파일은 해시기반 체크섬 검증을 해주는 것이 좋다.
ADD library.zip .
ADD library_SHA256 .
ADD library_SHA256.sig .
# Import PGP public key
RUN curl https://.../pgp_keys.asc | gpg --import
# 라이브러리 전자 서명 검증
RUN gpg --verify library_SHA256.sig library_SHA256
# Verify checksum
RUN cat library_SHA256 | grep linux_amd64 | sha256sum -cs
RUN unzip libary.zip
RUN mv library /usr/local/bin
# 실행
dockerigonore
- Dockerfile 빌드 시에 따라 들어가지 않게 된다.
- Dockerfile 과 같은 레벨 디렉토리에 있어야한다.
.dockerignore
.git
.idea
.vscode
.github
*.log