COPY --link 얘기는 한 2년 전부터 컨퍼런스마다 단골 메뉴였다. "그냥 다 붙여라, 캐시 효율이 미친다"는 식의 글도 많고. 우리 팀도 어느 순간부터 거의 자동 반사처럼 모든 COPY 앞에 --link를 박아 넣고 있었다. 근데 최근에 좀 다른 얘기가 돌더라.
올해 2월에 Depot 블로그에서 "왜 COPY --link 쓰지 말아야 하는지"라는 글이 올라와서 한 번 더 시끌시끌했다. 한 줄로 요약하면 "BuildKit이 --link 레이어를 다루는 방식 때문에 오히려 빌드가 느려지는 케이스가 꽤 있다"는 거. 우리 팀에서도 비슷한 케이스를 한 번 만난 적이 있어서 정리해둔다.
--link가 손해 보는 케이스
가장 흔한 패턴이 이거다.
FROM node:20-alpine AS build
WORKDIR /app
COPY --link package.json package-lock.json ./
RUN npm ci
COPY --link . .
RUN npm run build
별생각 없이 보면 멀쩡해 보인다. 근데 COPY --link . . 한 줄이 문제다. .dockerignore가 헐겁거나 모노레포 루트에서 빌드하면 수천 개 파일이 통째로 새 레이어로 잡힌다. --link는 이걸 별도 스냅샷으로 만들어서 머지하는데, 파일 수가 많을수록 머지 자체가 비싸진다. 우리 빌드는 이 한 줄에서 60초 가까이 더 걸리고 있었다. --link 떼니까 35초로 떨어졌다.
또 하나, --link는 destination path에 심볼릭 링크가 있으면 따라가지 않는다. 베이스 이미지가 /var/log 같은 걸 symlink로 묶어둔 경우 의도와 다르게 동작한다. 디버깅하다가 "어 이거 왜 비어 있지" 하는 순간이 온다.
그래서 언제 쓰면 좋냐
멀티 스테이지에서 빌드 산출물만 골라서 복사할 때는 여전히 --link가 최고다. 이런 거.
FROM build AS final
COPY --link --from=build /app/dist /app/dist
COPY --link --from=build /app/node_modules /app/node_modules
이 패턴은 dist만 바뀌어도 node_modules 레이어가 그대로 재사용된다. 캐시 히트율이 눈에 띄게 올라간다. 반대로 "프로젝트 루트 전체"를 --link로 복사하는 건 거의 항상 손해다.
결론 같지 않은 결론: COPY --link는 만능 키가 아니라 도구다. 우리 팀 기준은 "산출물 단위 복사면 --link, 소스 트리 통째면 빼고"로 정리됐다. 혹시 다른 기준으로 쓰시는 분 있으면 댓글 남겨주세요.
'IT > 컨테이너' 카테고리의 다른 글
| containerd config_path, 이거 모르는 분 꽤 많더라 (0) | 2026.06.21 |
|---|---|
| BuildKit cache mount으로 CI 빌드 시간 7분 -> 40초 만든 가이드 (0) | 2026.06.21 |
| containerd NRI, 사실 내부적으로는 이렇게 돌아간다 (1) | 2026.06.11 |
| BuildKit cache mount 제대로 쓰는 법 — Rust/Node CI 빌드 시간을 절반으로 (0) | 2026.06.08 |
| cgroup v2 전환 후 OOMKill 동작이 바뀐 이유 (0) | 2026.06.04 |