컨테이너 용어 사전
빌드FROM · COPY vs ADD · syntax 지시자

Dockerfile

이미지를 만드는 명령서. 명령어 18개 중 절반이 비슷한 것끼리 짝을 이뤄 사고를 만든다.

이미지를 만드는 명령서. 명령어는 18개뿐인데, 그중 절반이 비슷해 보이는 것끼리 짝을 이룬다.

FROM · RUN · CMD · LABEL · EXPOSE · ENV · ADD · COPY · ENTRYPOINT VOLUME · USER · WORKDIR · ARG · ONBUILD · STOPSIGNAL · HEALTHCHECK · SHELL MAINTAINER (폐기 — LABEL maintainer 를 쓴다)

  • 레이어를 만드는 것 — RUN · COPY · ADD
  • 메타데이터만 바꾸는 것 — 나머지 전부

문법 버전을 고정한다

# syntax=docker/dockerfile:1
파서 지시자다 — BuildKit 이 어떤 Dockerfile 문법을 쓸지 정한다
기능마다 요구 버전이 다르다
  1.2   RUN --mount=type=cache
  1.4   COPY --link · 히어독
  1.8   # check= 지시자 (빌드 검사)

없으면 데몬에 내장된 낡은 문법으로 파싱돼 "문법 오류" 가 난다

COPY vs ADD

COPY app.jar /app/          # 기본. 파일·디렉터리 복사
ADD  https://x/y.tar.gz /   # 원격 URL 다운로드
ADD  archive.tar.gz /app/   # tar 자동 압축 해제

공식 권장 — 기본은 COPY 를 쓴다

ADD 가 위험한 이유

  • tar 를 '자동으로 푼다' — 의도치 않게 파일이 흩어진다
  • 원격 URL 은 캐시 판정이 애매하고 검증이 없다
  • 무엇을 할지 파일 확장자에 따라 달라진다 (예측 불가)

원격 파일이 필요하면 RUN 안에서 받고 체크섬을 검증한다

ENV vs ARG

ARG NODE_VERSION=22          # 빌드 시점에만 존재
ENV NODE_ENV=production      # 이미지에 남아 런타임에도 보인다

둘 다 비밀을 담으면 안 된다 ARG 로 넘긴 값도 docker history 에 남는다 ENV 는 docker inspect 로 그대로 보인다

빌드 비밀은 시크릿 마운트로

  • RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci
  • 빌드 중에만 파일로 존재하고 레이어에 남지 않는다

.dockerignore

docker build . 의 '.' 이 빌드 컨텍스트다 — 이 디렉터리 전체가 전송된다

.git · node_modules · 빌드 산출물이 통째로 넘어가면

  • 전송이 느려진다
  • COPY . . 로 이미지에 딸려 들어간다 (비밀 유출)

이미지에 .git 이 통째로 들어가 있는 경우가 의외로 흔하다 커밋 히스토리에 남은 비밀까지 함께 나간다

자주 틀리는 것

  • EXPOSE — 문서일 뿐이다. 실제 공개는 docker run -p 가 한다
  • WORKDIR — RUN cd 는 다음 RUN 에서 원위치로 돌아간다. WORKDIR 을 쓴다
  • VOLUME — 이미지에 넣으면 익명 볼륨이 자동 생성돼 통제가 어렵다
    • 실행 시 -v 로 지정하는 편이 낫다

빌드 검사

# syntax=docker/dockerfile:1
# check=error=true

BuildKit 이 흔한 실수를 잡아 준다

  • 정의하지 않은 ARG 사용
  • JSON 이 아닌 CMD/ENTRYPOINT (shell form 경고)
  • 대소문자 불일치 (from → FROM)
  • 중복 스테이지 이름

Dockerfile v1.8.0+ 에서 쓸 수 있다 CI 에 넣으면 리뷰에서 반복 지적하던 것들이 자동으로 걸린다 hadolint 같은 외부 린터를 함께 쓰기도 한다

자주 쓰는 골격

# syntax=docker/dockerfile:1
FROM node:22-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
COPY . .
RUN npm run build

FROM nginx:1.27-alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
USER 101:101

면접 함정

  • "ADD가 COPY의 상위 호환" → 자동 압축 해제 때문에 예측이 어렵다. 기본은 COPY다.
  • "EXPOSE하면 포트가 열린다" → 문서일 뿐이다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — Dockerfile — 명령어와 그 함정