종속성
잠금 파일이란?
잠금 파일은 패키지 관리자가 해석한 모든 종속성(직접 및 전이적 종속성)의 정확한 버전을 기록해, 다음 설치에서도 같은 트리를 얻도록 합니다. 빌드를 위한 가장 좋은 계획이지만, 빌드가 실제로 사용한 내용의 기록은 아닙니다.
업데이트
잠금 파일에 기록되는 내용
package.json이나 pyproject.toml 같은 매니페스트에는 의존하는 패키지와 허용하는 버전 범위가
나열됩니다. 패키지 관리자는 이 범위를 전이적 종속성을 포함한 전체 트리의
정확한 버전으로 바꾸고, 그 결과를 잠금 파일에 씁니다. npm 문서는 package-lock.json이 "생성된 정확한
트리를 기술하여 이후 설치에서 동일한 트리를 생성할 수 있게 한다"고 설명합니다.
package-lock.json의 항목 하나는 다음과 같습니다.
"node_modules/raw-body": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
"integrity": "sha512-...",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.6.3",
"unpipe": "1.0.0"
}
}
- version은 선택된 정확한 버전입니다.
- resolved는 패키지를 가져온 위치로, 레지스트리 tarball URL 또는 커밋이 포함된 git URL입니다.
- integrity는 tarball의 Subresource Integrity 해시로, 변조된 다운로드는 실패합니다.
- dependencies는 해당 패키지 자체의 종속성이며, 이를 통해 트리, 즉 종속성 그래프가 연결됩니다.
패키지 관리자별 잠금 파일
| 패키지 관리자 | 잠금 파일 | 변경 없이 설치 |
|---|---|---|
| npm | package-lock.json | npm ci |
| Yarn (Berry) | yarn.lock | yarn install --immutable |
| pnpm | pnpm-lock.yaml | pnpm install --frozen-lockfile |
| uv | uv.lock | uv sync --locked |
| Poetry | poetry.lock | poetry install |
| Cargo | Cargo.lock | cargo build --locked |
| Bundler | Gemfile.lock | bundle config set frozen true |
| Go modules | go.mod 버전과 go.sum 체크섬 |
빌드 명령은 기본적으로 go.mod를 업데이트하지 않음 |
일반 pip에서는 정확한 버전을 적은 requirements.txt가 흔히 대신 쓰입니다. 나열된 항목은 고정되지만,
나열되지 않은 항목은 설치할 때마다 다시 해석됩니다.
CI에서는 고정 설치 사용
잠금 파일은 빌드가 그 파일로 설치할 때만 효과가 있습니다. 일반 npm install은
package-lock.json이 package.json과 더 이상 일치하지 않으면 잠금 파일을 업데이트할 수
있으므로, 빌드가 조용히 새 트리를 해석하게 됩니다. npm ci는 자동화 환경을 위해 만들어졌습니다.
package-lock.json또는npm-shrinkwrap.json이 필요합니다.- 잠금 파일과
package.json이 일치하지 않으면 잠금 파일을 업데이트하는 대신 오류로 종료합니다. - 기존
node_modules를 먼저 삭제합니다. package.json이나 잠금 파일에 절대 쓰지 않습니다.
위 표의 다른 명령도 각 패키지 관리자에서 같은 역할을 합니다.
애플리케이션과 라이브러리
애플리케이션과 배포하는 모든 것에는 잠금 파일을 커밋하세요. 라이브러리의 경우 잠금 파일은 자체 개발과 CI만
고정합니다. npm은 package-lock.json을 절대 게시하지 않으며 루트 프로젝트 외에서는 이를 무시합니다.
라이브러리를 설치하는 애플리케이션은 지정된 버전 범위 내에서 그 종속성을 직접 해석합니다. npm의 유일한 예외는
npm-shrinkwrap.json으로, 게시되며 우선 적용되지만 대부분의 라이브러리는 사용하지 않는 것이 좋습니다.
잠금 파일이 출시된 내용의 기록이 아닌 이유
잠금 파일은 한 프로젝트의 한 패키지 관리자를 위한 계획입니다. 릴리스를 만든 빌드는 그 계획을 따르는 것 이상의 일을 했습니다.
- 잠금 파일을 사용하지 않았을 수 있습니다. 고정되지 않은 설치, 누락된 잠금 파일, 모노레포의 두 번째 잠금 파일이 있다면 지금 보고 있는 파일과 다르게 트리가 해석된 것입니다.
- 캐시. CI 캐시에서 복원된 패키지는 가져오는 과정 없이 설치되며, 부분 키로 복원된 캐시는 현재 잠금 파일보다 오래되었을 수 있습니다. GitHub Actions 캐시가 숨기는 것을 참조하세요.
- 빌드 도구. 설정 액션, 컴파일러, 린터, 코드 생성기는 다른 경로로 들어오며 각자의 종속성 트리를 가집니다.
-
다운로드와 설치 스크립트. 빌드 단계의
curl이나 패키지의 설치 스크립트는 어떤 잠금 파일에도 없는 코드를 가져옵니다. 이것이 숨은 종속성입니다. - 베이스 이미지. 컨테이너 빌드는 모든 언어 잠금 파일 바깥에 있는 이미지와 운영체제 패키지를 가져옵니다.
무결성 해시는 이 중 어느 것에도 도움이 되지 않습니다. 해시는 잠금 파일의 패키지가 변조되지 않았음을 증명할 뿐, 빌드가 그 바깥에서 가져온 것에 대해서는 아무것도 말해 주지 않습니다. 잠금 파일을 SBOM으로 바꾸는 SCA 도구도 같은 사각지대를 그대로 물려받습니다.
빌드를 기록하고, 잠금 파일은 유지하세요
잠금 파일은 계속 커밋하고 고정 설치로 설치하세요. 빌드를 반복 가능하게 만들어 주지만, 그것만으로 재현 가능한 빌드가 되지는 않습니다. 릴리스에 무엇이 들어 있는지에 대한 기록을 위해 CRACI는 빌드 자체를 기록합니다. CRACI의 GitHub Actions 러너에 있는 패키지를 인식하는 프록시가 각 작업이 가져오는 모든 패키지를 CI 캐시에서 복원된 패키지까지 포함해 기록하며, 각 작업의 SBOM은 자체 완전성을 명시합니다. 이 기록은 잠금 파일 스캔보다 사용 중인 종속성을 더 완전하게 보여 줍니다. 빌드 시점 SBOM을 참조하거나, 데모를 예약해 자사 빌드 하나에서 두 방식을 비교해 보세요.
잠금 파일: 자주 묻는 질문
잠금 파일이란 무엇입니까?
잠금 파일은 패키지 관리자가 해석한 모든 종속성(직접 및 전이적 종속성)의 정확한 버전을 출처 및 체크섬과 함께 기록하는 파일입니다. 이후 설치에서는 버전 범위를 다시 해석하는 대신 이 파일을 읽어 같은 트리를 재현합니다.
잠금 파일을 커밋해야 합니까?
예, 애플리케이션과 배포하는 모든 것에는 커밋해야 합니다. 커밋된 잠금 파일이 없으면 새로 설치할 때마다 버전 범위가 다시 해석되어 새로운 전이적 버전이 들어올 수 있습니다. 잠금 파일을 커밋하고 CI에서는 npm ci 같은 고정 설치로 설치하세요.
잠금 파일은 전이적 종속성도 고정합니까?
예. 그것이 잠금 파일의 주된 역할입니다. 매니페스트에는 직접 종속성과 허용 범위만 나열되며, 잠금 파일은 트리에 있는 모든 패키지에 대해 선택된 정확한 버전을 기록합니다.
게시하는 라이브러리에도 잠금 파일이 적용됩니까?
사용자에게는 적용되지 않습니다. 예를 들어 npm은 package-lock.json을 절대 게시하지 않으며 루트 프로젝트 외에서는 이를 무시합니다. 라이브러리를 설치하는 애플리케이션은 package.json이 허용하는 범위 내에서 그 종속성을 직접 해석합니다.
package-lock.json의 integrity 필드는 어떤 역할을 합니까?
패키지 tarball의 Subresource Integrity 해시(보통 sha512)를 담고 있습니다. npm은 다운로드한 패키지를 이 해시와 대조하므로, 잠긴 버전의 변조된 tarball은 설치에 실패합니다. 이는 잠금 파일의 패키지를 보호할 뿐, 빌드가 그 바깥에서 가져오는 것은 보호하지 않습니다.
잠금 파일과 SBOM은 같은 것입니까?
아닙니다. 잠금 파일은 입력, 즉 패키지 관리자가 한 프로젝트에서 따르는 계획입니다. SBOM은 릴리스의 인벤토리입니다. SCA 도구는 흔히 잠금 파일을 SBOM으로 바꾸는데, 이는 빌드가 정확히 잠금 파일대로만 설치하고 그 밖에는 아무것도 설치하지 않았을 때 유효합니다.