← 아티클 목록

도커 빌드 시크릿 누출 막기 — --secret 제대로 쓰기

2027-05-24#docker#보안#buildkit

비공개 패키지를 받으려고 토큰을 ARGENV로 넘기거나, .npmrcCOPY했다가 빌드 후 지우면 안전할 것 같지만 아닙니다. 도커 이미지는 레이어 단위로 쌓이고, 한 번 들어간 파일이나 빌드 인자는 뒤 레이어에서 지워도 앞 레이어에 그대로 남습니다. 누구나 docker history나 레이어 추출로 꺼내볼 수 있습니다.

왜 새는지 직접 확인

Docker
docker build --build-arg NPM_TOKEN=secret123 -t app .
docker history --no-trunc app | grep NPM_TOKEN

--build-arg로 넘긴 값은 history에 평문으로 보입니다. RUN rm .npmrc로 지워도 그 파일을 만든 앞 레이어가 살아 있어 docker save 후 tar를 풀면 그대로 나옵니다.

해결 — BuildKit --secret

BuildKit의 --secret은 시크릿을 특정 RUN 단계에만 메모리로 마운트하고, 최종 이미지나 레이어에 전혀 남기지 않습니다.

Dockerfile
# syntax=docker/dockerfile:1
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN --mount=type=secret,id=npmtoken \
    NPM_TOKEN=$(cat /run/secrets/npmtoken) npm ci
COPY . .

빌드 시 파일이나 환경변수에서 시크릿을 주입합니다.

Docker
# 파일에서
docker build --secret id=npmtoken,src=$HOME/.npm_token -t app .

# 환경변수에서
NPM_TOKEN=secret123 docker build --secret id=npmtoken,env=NPM_TOKEN -t app .

/run/secrets/npmtoken은 해당 RUN이 끝나면 사라지며, history에도 레이어에도 흔적이 없습니다.

방식별 비교

방식레이어에 남나평가
ENV TOKEN=...남음 (영구)절대 금지
ARG TOKEN + --build-arghistory에 평문금지
COPY .npmrcRUN rm앞 레이어에 남음금지
RUN --mount=type=secret안 남음권장

체크리스트

로컬 터미널
# BuildKit 활성화 (Docker 23+ 기본, 구버전은 명시)
export DOCKER_BUILDKIT=1

# 빌드 후 누출 점검 — 아무것도 안 나와야 정상
docker history --no-trunc app | grep -i -E 'token|secret|password'
docker save app -o app.tar    # tar 풀어서 .npmrc 등 잔존 확인

Dockerfile 첫 줄의 # syntax=docker/dockerfile:1을 빠뜨리면 --mount 문법이 인식되지 않으니 반드시 넣습니다.


레이어에 실제로 시크릿이 남는지 docker history로 확인하고 --secret으로 막아 보는 실습은 도커 트랙에서 회원가입 없이 무료로 할 수 있습니다.