멀티-스테이지 도커가 어떻게 구축되나요?

Multi-stage Docker 빌드는 Docker 17.05에서 소개된 기능으로, 단일 Dockerfile 내의 여러 ] 문헌을 사용할 수 있습니다. 각 ] 명령어는 새로운 단계로 시작되며, 자체 기본 이미지, 의존성 및 명령이 있습니다. Artifacts는 한 단계에서 다른 한 단계로 선택적으로 복사할 수 있으며, 최종 이미지는 애플리케이션을 실행하는데 필요한 것을 유지합니다. 이 접근법은 중간 크기 또는 폴더에 있는 파일 크기를 줄여서 생성하거나, 파일 크기를 크게 줄 수 있습니다.

핵심 아이디어는 실행 환경에서 빌드 환경을 분리하는 것입니다. 전형적인 단일 단계 구조에서 개발자는 생산에 사용되는 동일한 이미지에서 모든 빌드 도구 (예를들면 컴파일러, 패키지 관리자, 테스트 프레임 워크)를 설치합니다. 즉 이미지가 증가하고 공격 표면을 증가시킵니다. 멀티 스테이지 빌드는 컴파일을 위해 두꺼운, 기능 풍부한 이미지를 사용하여이 문제를 해결하고 결과를 복사 한 다음 최소 실행 이미지로 해석됩니다. [LT] 또는 [F]] [F] [F]] [F]] [F]]] [F]] [F]] [F]] [F]] [F]] [F]] [F]]] [F]] [F]]]] [F]] [F]]] [F]]] [F] [F]]] [F] [F] [F] [F] [F] [F] [F] [F] [F] [F] [F]]] [F] [F] [F] [F]]] [F] [F] [F] [F] [F] [F]]]] [F] [F]]]]]] [F]]]

Multi-Stage Builds의 장점

다단계 빌드를 채택하는 장점은 간단한 크기 축소를 넘어갑니다. 그들은 보안, 유지 보수성 및 배포 속도에 대한 엄청난 영향을 갖습니다.

1. 감소된 이미지 크기

빌드 타임 의존성을 디케이팅함으로써, 멀티 스테이지는 종종 이미지를 50%에서 90%로 축소합니다. 예를 들어, 전체 ] 이미지를 사용하여 구축된 Node.js 애플리케이션(300MB 이상)은 내장된 폴더를 Base로 복사하여 20MB 미만으로 단축할 수 있습니다. 이 저장은 빠른 풀 타임, 네트워크 대역폭 및 낮은 레지스트리 비용으로 직접 변환합니다.

2. 향상된 보안

컨테이너 이미지의 모든 설치 패키지 또는 도구는 잠재적 취약점입니다. 멀티 스테이지 빌드는 컴파일러, 디버거 및 최종 이미지에서 개발 라이브러리를 제외하고 공격 표면을 크게 줄입니다. ] 또는 ]와 같은 이미지를 사용할 수 있습니다. 실행 단계에 대한, 이는 응용 바이너리를 실행하기 위해 최소한의 벌거벗은을 포함.

3. 간소화된 빌드 프로세스

모든 빌드 단계는 단일 Dockerfile에서 정의되며, 프로세스 자체 유지 및 버전으로 쉽게 정의됩니다. CI/CD 파이프라인은 단일 항목 포인트 혜택을 제공합니다. Dockerfile. 별도의 빌드 스크립트 또는 수동 정리 단계를 유지해야 할 필요가 없습니다.

4. 강화된 재현성 및 일관성

전체 빌드는 하나의 Dockerfile에서 캡처되기 때문에 개발자 또는 시스템은 정확한 동일한 레이어를 재현할 수 있습니다. 기본 이미지에 대한 특정 버전 태그의 사용은 환경 전체에 일관성있는 빌드를 보장합니다.

Multi-Stage Dockerfile 구축: 단계별

이 워크스테이션은 Node.js 및 React 애플리케이션의 생산 읽은 멀티 단계 Dockerfile의 생성을 다룹니다. 동일한 원리는 컴파일된 언어에 적용됩니다.

1. 단계 계획

코드를 작성하기 전에, 필요한 단계를지도. 전형적인 멀티 단계 빌드는 적어도 두 단계가 있습니다.

  • Builder stage – 모든 빌드 도구를 설치하고, 의존성을 설치하고 빌드 명령을 실행합니다.
  • Runtime stage – 최소 기본 이미지를 사용하며, 빌더 스테이지에서 내장된 아트ifacts만 복사하고, 실행 동작을 정의합니다.

복잡한 프로젝트를 위해, 정적 분석, 또는 자산 압축을 위한 중간 단계를 추가할 수 있습니다.

2. Builder 단계 쓰기

필요한 툴체인을 포함하는 기본 이미지로 시작하십시오. ]named stages를 ]로 사용하여 나중에 참조하세요. Node.js:

FROM node:14-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

키 포인트:

  • ]를 사용하여, 더 빠른 신뢰성 설치를 위해.
  • ] 명령을 캐싱을 활용할 수 있을 때 별도 레이어로 유지하십시오.
  • 이 단계에서 빌드 도구 (TypeScript, webpack과 같은)를 설치하십시오.

3. 중간 시험 단계 (선택)를 추가하십시오

코드 품질을 시행하려면 테스트를 실행하는 단계를 추가하십시오. 이 단계는 빌더 이미지를 재사용하거나 추가 도구를 설치 할 수 있습니다. 최종 단계가 아니라 테스트 실패는 최종 이미지에서 제시되지 않습니다.

FROM builder AS test
RUN npm run test

CI 파이프라인에서 이 단계를 실행할 수 있습니다 ] 전체 최종 이미지를 구축하지 않고 실패를 잡기 위해.

4. Runtime Stage를 정의하십시오.

React 애플리케이션의 경우, 실행시간 이미지는 Nginx 서버일 수 있습니다. 백엔드 API의 경우, 디트로이 없는 기본 이미지 또는 Node.js 실행 시간으로 최소 알파인이 될 수 있습니다. 를 사용하여 필수 아트ifacts만 복사합니다.

FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Node.js runtime이 필요한 경우, builder에서 ] 복사를 피하십시오. 대신 runtime Stage에서 생산 의존성을 다시 설치하십시오.

FROM node:14-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/server.js"]

5. 이미지를 구축하고 테스트

표준 명령을 사용하여 최종 이미지를 만듭니다.

docker build -t myapp:latest .

크기를 확인하려면 을 실행하고 단일 단계 빌드에 대한 비교. 컨테이너를 실행하고 응용 프로그램을 올바르게 응답 확인:

docker run -d -p 8080:80 myapp:latest
curl http://localhost:8080

Multi-Stage Builds에 대한 모범 사례

  • 특수 기본 이미지 태그 - ]]를 피하고 놀랍도록 합니다. 또는 .
  • 레이어 캐싱 – 복사 ] 과 ] 소스 코드의 나머지 앞에 레이어는 종속성 변경시에만 유효하지 않습니다.
  • Leverage buildKit – BuildKit with 를 사용하여 빠른 빌드, 인라인 캐싱 및 더 나은 병렬.
  • 다른 환경]을 위한 여러 최종 단계의 구성 – 예를 들어, 디버깅 도구와 생산 단계의 개발 단계는 경화된 기본 이미지로.
  • ]]] 개발을 위한 ] – 개발에서 당신은 ] 단계에 살고 재부하와 소스 맵을 얻을 수 있습니다, 다음 생산에 대한 와 재건.
  • Keep은 이미지에서 비밀 – 빌드 중에 credentials를 통과해야 하는 경우 Docker BuildKit의 플래그를 사용합니다. 최종 이미지에는 포함되지 않습니다.

일반적인 패턴 및 사용 사례

언어 (Go, Rust, C++)

정적 배양을 위해, 런타임 스테이지는 ] (비교 기본 이미지)를 사용할 수 있습니다. 이진만과 아마도 구성 파일이 복사됩니다. Go의 예:

FROM golang:1.20-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o myapp .

FROM scratch
COPY --from=builder /app/myapp /myapp
ENTRYPOINT ["/myapp"]

Python 응용

]를 사용하여 임의의의를 설치하고 C 확장을 컴파일하고, 설치된 패키지만 실행할 수 있습니다.

FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
COPY . .

FROM python:3.11-slim
COPY --from=builder /root/.local /root/.local
COPY --from=builder /app /app
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]

API Server로 프론트엔드

한 Dockerfile에서 frontend와 backend를 모두 빌드합니다. 각을 위한 별도의 Builder 스테이지를 사용하여 단일 실행 이미지로 artifacts를 복사합니다.

FROM node:14-alpine AS frontend-builder
WORKDIR /app
COPY frontend/package*.json ./
RUN npm ci
COPY frontend/ .
RUN npm run build

FROM node:14-alpine AS api-builder
WORKDIR /app
COPY api/package*.json ./
RUN npm ci
COPY api/ .
RUN npm run build

FROM node:14-alpine
WORKDIR /app
COPY --from=frontend-builder /app/build ./public
COPY --from=api-builder /app/dist ./dist
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/server.js"]

문제 해결 멀티 단계 구축

  • Layer caching not working – ]] 소스 코드 앞에 명령의 의존도를 보장한다. ]를 사용하여 불필요한 파일을 제외합니다.
  • Artifact not found – ] 문에 있는 경로 확인. 빌더 스테이지는 지정된 위치에 출력을 생성해야 합니다. 를 디버그로 사용합니다.
  • Secret Leak - ] 또는 를 포함할 수 있는 전체 감독을 복사하지 마십시오. Explicitly 복사는 필요한 파일만 복사합니다.
  • ]다단계 – 실수로 복사하는 경우 ] 또는 전체 소스. 층 크기를 볼 를 사용 .

관련 기사

Multi-stage Docker 빌드는 현대 컨테이너화의 코너스톤입니다. 단일 Dockerfile에서 빌드 프로세스를 간단하고 문서화하면서 린, 보안 이미지를 발송할 수 있습니다. 빌드와 실행 시간 간의 문제를 분리함으로써 이미지 크기를 크게 줄일 수 있으며 보안 및 스트림 라인 CI/CD 파이프라인을 향상시킵니다. 이 기법은 Node.js, Go, Python, Java, 또는 frontend 애플리케이션을 구축하는 거의 모든 스택에 적용되며, 기존의 워크플로우를 구축하여 기존의 워크플로우를 구축하고, 기존의 워크플로우를 구축하고, 기존의 워크플로우를 구축하고, 기존의 워크플로우를 구축하고, 기존의 워크플로우를 구축하고, 기존의 워크플로우를 구축할 수 있습니다.

자세한 내용은 official Docker 멀티 스테이지 빌드 문서Dockerfile 모범 사례 가이드를 참조하세요. Real-world 예제는 ]Docker Library 문서에서 확인할 수 있습니다.