Dockerfile 지시어 레퍼런스

Dockerfile 지시어 레퍼런스

Docker 이미지를 만들 때 빌드 절차를 Dockerfile에 적어 두면, 같은 이미지를 재현 가능한 상태로 반복해서 만들 수 있어요. 그런데 Dockerfile을 처음 보면 지시어가 많아서 어느 것이 어떤 역할인지 헷갈리기 마련이죠. 이 페이지에서는 자주 쓰는 Dockerfile 지시어를 하나씩 정리해 볼게요.

Dockerfile은 맨 위부터 한 줄씩 실행되면서 이미지를 만들어요. 각 지시어가 레이어 하나씩을 만들고, 유효한 Dockerfile은 반드시 FROM 지시어로 시작해야 해요. 지시어마다 옵션과 동작이 다르니, 상황에 맞게 쓰는 게 핵심이에요.

출처: Dockerfile reference — Docker Docs

주요 지시어 한눈에

| 지시어 | 역할 | | ADD | 로컬·원격 파일과 디렉토리를 추가해요. | | ARG | 빌드 시점 변수를 사용해요. | | CMD | 기본 실행 명령을 지정해요. | | COPY | 파일과 디렉토리를 복사해요. | | FROM | 베이스 이미지에서 새 빌드 스테이지를 만들고, 이후 지시어의 기반이 돼요. | | STOPSIGNAL | 컨테이너가 종료될 때 쓸 시스템 콜 시그널을 지정해요. |

FROM

FROM 지시어는 새 빌드 스테이지를 초기화하고, 이후 지시어들이 쓸 베이스 이미지를 정해요. 유효한 Dockerfile은 반드시 FROM으로 시작해야 해요. 이미지는 어떤 유효한 이미지든 될 수 있어요.

RUN

RUN은 빌드 중에 명령을 실행해요. BuildKit에서는 마운트 옵션도 지원해요.

| 타입 | 설명 | | bind (기본) | 컨텍스트 디렉토리를 읽기 전용으로 바인드 마운트해요. | | secret | 개인 키 같은 보안 파일을 이미지나 빌드 캐시에 박지 않고 빌드 컨테이너가 접근하게 해줘요. |

캐시 마운트(RUN --mount=type=cache)를 쓰면 캐시 디렉토리 내용이 빌더 호출 사이에도 유지되면서 지시어 캐시는 무효화되지 않아요. 캐시 마운트는 성능 향상을 위해서만 써야 해요. 다른 빌드가 파일을 덮어쓰거나 저장 공간이 부족해 GC가 정리할 수도 있으니, 빌드는 캐시 내용과 무관하게 동작해야 합니다.

캐시 마운트의 옵션 중 id는 서로 다른 캐시를 구분하는 선택적 ID고 기본값은 target 값이에요. target, dst, destination은 마운트 경로이고, from은 캐시 마운트의 기반이 될 빌드 스테이지·컨텍스트·이미지 이름이에요(기본은 빈 디렉토리).

LABEL

멀티스테이지 빌드에서 중간 스테이지의 라벨은, 최종 스테이지가 그 스테이지를 직접·간접적으로 기반으로 삼았을(FROM으로) 때만 최종 이미지에 남아요. COPY --from이나 RUN --mount=from=으로만 참조하는 스테이지의 라벨은 출력 이미지에 포함되지 않아요.

ENV

한 스테이지는 부모 스테이지나 조상 스테이지가 ENV로 설정한 환경변수를 물려받아요. 멀티스테이지 빌드에서의 동작은 매뉴얼의 해당 섹션을 참고하면 돼요.

ADD

ADD는 로컬·원격 파일이나 디렉토리를 이미지에 추가해요. 로컬 tar 아카이브를 추가하면 디렉토리를 풀 때 tar -x와 같은 동작을 해요. 결과는 (1) 대상 경로에 있던 것과 (2) 추가되는 소스 트리의 내용을 파일 단위로 합친 것인데, 충돌은 추가되는 내용 우선으로 해결돼요.

대상 경로가 /로 시작하면 절대 경로로 해석돼서, 현재 빌드 스테이지의 루트를 기준으로 지정한 위치에 복사돼요.

# create /abs/test.txt
ADD test.txt /abs/

원격 Git 저장소를 소스로 쓸 때 BuildKit은 기본적으로 .git 디렉토리를 제외하고 저장소 내용을 이미지에 추가해요. ADD --keep-git-dir=true 플래그를 주면 .git 디렉토리를 보존하죠.

체크섬 검증도 가능해요. Git 소스의 체크섬은 커밋 SHA이고, 전체 또는 접두부(1글자 이상)로 매칭돼요. HTTP 소스의 체크섬은 sha256:<hash> 형식의 SHA-256 콘텐츠 다이제스트예요. SHA-256만 지원해요.

COPY

COPY<src>의 새 파일·디렉토리를 이미지 파일시스템의 <dest> 경로에 복사해요. 파일·디렉토리는 빌드 컨텍스트, 빌드 스테이지, 이름 있는 컨텍스트 또는 이미지에서 가져올 수 있어요.

빌드 컨텍스트에서 복사할 때, 소스가 디렉토리면 그 내용이 파일시스템 메타데이터를 포함해 복사돼요. 디렉토리 자체는 복사되지 않고 내용만 복사되며, 하위 디렉토리도 함께 복사되고 대상의 기존 디렉토리와 병합돼요. 충돌은 추가되는 내용 우선으로 해결돼요.

대상 경로가 /로 시작하면 절대 경로로 해석돼요.

# create /abs/test.txt
COPY test.txt /abs/

COPY --from

기본으로 COPY는 빌드 컨텍스트에서 복사하지만, COPY --from 플래그를 쓰면 이미지·빌드 스테이지·이름 있는 컨텍스트에서 복사할 수 있어요.

COPY [--from=<image|stage|context>] <src> ... <dest>

멀티스테이지 빌드에서 특정 스테이지에서 복사하려면, FROM 지시어의 AS 키워드로 정한 스테이지 이름을 지정해요.

COPY --link를 쓰면 이전 레이어가 바뀌어도, --cache-from으로 --link로 빌드한 레이어를 이후 빌드에서 재사용할 수 있어요. 특히 멀티스테이지 빌드에서 COPY --from 문이 같은 스테이지의 앞선 명령 변경으로 무효화되던 문제를 피하는 데 중요해요.

히어독(Here-Documents)

빌드 컨텍스트에 파일을 두지 않고 Dockerfile 안에 여러 줄을 직접 적고 싶을 때 히어독을 써요.

여러 줄 스크립트 실행하기

# syntax=docker/dockerfile:1
FROM debian
RUN <<EOT bash
  set -ex
  apt-get update
  apt-get install -y vim
EOT

명령이 히어독만으로 이뤄지면 그 내용은 기본 셸로 평가돼요.

인라인 파일 만들기

# syntax=docker/dockerfile:1
FROM debian
COPY <<EOF greeting.txt
hello world
EOF

COPY 지시어에서 소스 자리에 히어독 표시를 쓰면 히어독 내용이 그대로 파일로 기록돼요.

더 알아보기