Docker Multistage를 사용하여 작은 이미지를 만드는 방법(TS 및 Golang)
11328 단어 typescriptdockergo
이미지를 쉽게 최적화할 수 있다는 것을 알고 계셨습니까?
We're not much language-related in this article, and reading all examples can be beneficial.
TS 예
예를 들어 Typescript 프로젝트를 빌드하고 실행하기 위해 항상 이런 종류의 Dockerfile을 사용했을 수 있습니다.
FROM node:18-alpine3.15
WORKDIR /usr/app
COPY package.json .
RUN npm install --include=dev
COPY tsconfig.json .
COPY src src
RUN ["npm", "run", "build"]
CMD ["npm", "run", "start"]
간단하지만 중요한 것을 잃지 않고 더 작게 만들 수 있으며,
때문에, 라인에
RUN ["npm", "run", "build"]
일부 도구(개발 종속성)를 사용하여 일부 TS 코드를 JS 코드로 변환하고 있습니다.
변환 후 해당 도구를 제거하면 어떻게 됩니까? 아무것도 아님!
아래 그림을 보세요. 한 단계가 아닌 세 단계로 이미지를 구축했으며 공간을 35% 절약했습니다!
아래 코드 사용:
FROM node:18-alpine3.15 as ts-compiler
WORKDIR /usr/app
COPY package*.json ./
COPY tsconfig.json ./
RUN npm install --include=dev
COPY src src
# Build the project (TS to JS conversion)
RUN ["npm", "run", "build"]
FROM node:18-alpine3.15 as ts-remover
WORKDIR /usr/app
# We need package.json again
COPY --from=ts-compiler /usr/app/package*.json ./
# Move built codes from last stage here
COPY --from=ts-compiler /usr/app/build ./
# We don't need dev dependencies anymore
RUN npm install --omit=dev
# Using google optimized containers can make it even smaller
FROM gcr.io/distroless/nodejs:18
WORKDIR /usr/app
COPY --from=ts-remover /usr/app ./
USER 1000
CMD ["index.js"]
환경 변수에 주의
예를 들어 Puppeteer와 같은 특수 패키지를 사용한다고 상상해 보십시오.
Puppeteer는 설치 시 크롬 브라우저를 다운로드하지만 원하는 경우 ENV를 설정하여 비활성화할 수 있습니다.
마지막 코드의 1단계에서 변경한 사항을 살펴보십시오.
FROM node:18-alpine3.15 as ts-compiler
WORKDIR /usr/app
COPY package.json .
# This line is added 👇🏻
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
RUN npm install --include=dev
COPY tsconfig.json .
COPY src src
RUN ["npm", "run", "build"]
따라서 다단계 빌드를 다시 실행하면 엄청나게 증가하는 것을 볼 수 있습니다 😳
무슨 일이야?
사실은 단계별로 ENV 및 ARG 명령을 사용해야 합니다. 우리는 두 단계에서 종속 항목을 두 번 설치하므로 크롬 설치를 두 번 건너뛰어야 합니다!
코드 조각보다 더 많은 것을 말하는 것은 없습니다 😄:
FROM node:18-alpine3.15 as ts-compiler
WORKDIR /usr/app
COPY package.json .
# Define ENV once here
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
RUN npm install --include=dev
COPY tsconfig.json .
COPY src src
RUN ["npm", "run", "build"]
FROM node:18-alpine3.15 as ts-remover
WORKDIR /usr/app
COPY --from=ts-compiler /usr/app/package.json .
COPY --from=ts-compiler /usr/app/build .
# Define ENV once again!
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
RUN npm install --omit=dev
# We don't need that ENV in this stage,
# because we're not installing anything more.
FROM gcr.io/distroless/nodejs:18
WORKDIR /usr/app
COPY --from=ts-remover /usr/app ./
USER 1000
CMD ["index.js"]
예를 들어
Go 컨테이너(및 기타 컴파일 언어)는 훨씬 더 최적화할 수 있습니다. (훨씬 더 😄)
런타임이 연결되어 있기 때문에 Nodejs와 같은 것을 설치할 필요가 없으며 두 번째 단계에서 컴파일러 자체를 삭제하고 바이너리 실행 파일을 사용할 수 있습니다.
FROM golang:1.18-alpine3.15 AS builder
WORKDIR /app
# Copy go.mod and go.sum first, because of caching reasons.
COPY go.mod go.sum ./
RUN go mod download
COPY . ./
# Compile project
RUN CGO_ENABLED=0 GOOS=linux go build -a -o main .
# Use another clean image without Golang compiler.
FROM alpine:3.15 AS production
COPY --from=builder /app/main .
CMD ["./main"]
맞아! 공간의 약 96%를 절약했습니다!
첫 번째 결과는 다단계 기술 없이,
두 번째는 알파인-3.15를 프로덕션으로 사용하는 것입니다.
세 번째는 가장 작은 이미지인 gcr.io/distroless/static-debian11을 사용하는 것입니다.
UI 포함
다른 단계에서 Dockerfile에 UI를 추가할 수도 있습니다!
이 경우 내 프로젝트(ui 폴더) 옆에 Svelte SPA 프로젝트가 있고 Go Backend에서 제공하고 있습니다.
FROM golang:1.18-alpine3.15 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . ./
RUN CGO_ENABLED=0 GOOS=linux go build -a -o main .
# This stage convert svelte project to vanilla HTML, CSS, JS.
FROM node:18-alpine3.15 AS frontend
WORKDIR /ui
COPY ui .
RUN npm install
RUN npm run build
FROM alpine:3.15 AS production
COPY --from=builder /app/main .
COPY --from=frontend /ui/public /ui
CMD ["./main"]
이 코드는 Blogo 프로젝트의 일부입니다.
https://github.com/arshamalh/blogo
나는 당신이 여기에서 나에게서 뭔가를 배웠기를 바랍니다. 😃✌🏻
어떤 제안이나 수정도 환영합니다.
Reference
이 문제에 관하여(Docker Multistage를 사용하여 작은 이미지를 만드는 방법(TS 및 Golang)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/arshamalh/how-to-use-docker-multistage-to-make-tiny-images-ts-and-golang-g4j텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)