[Docker(go, shell-scr)] Multi-stage Build 이미지 경량화

2024. 11. 4. 11:16·OS/Docker

Multi-stage build

애플리케이션 개발 시 개발 환경에서 사용한 라이브러리나 개발 지원 툴이 제품 환경에서 반드시 사용되는 것은 아니다. 제품 환경에서 애플리케이션을 실행하기 위해서 최소한으로 필요한 실행 모듈만 배치하는 것이 컴퓨터를 효율적으로 활용하는 데 도움이 된다. 

# Multi-stage build

여러번 빌드를 거쳐 도커 이미지의 용량을 최소화 하는 것. 컨테이너 이미지를 만들면서 빌드 등에는 필요하다. 하지만 최종 컨테이너 이미지에는 필요 없는 환경을 제거할 수 있로고 단계를 나우워 기반 이미지를 만드는 것이 좋다. 

 

멀티스테이지 빌드를 사용하게 되면 그림처럼 컨테이너 실행 시에는 빌드에 사용한 파일 및 디렉토리와 같은 의존 파일들이 모드 삭제된 상태로 컨테이너가 실행하게 되고, 좀 더 가벼운 크기의 컨테이너를 사용할 수 있다. 

 


 Multi-Stage Bild 실습


# 1. Docker GO  - Multi-Stage Build 

GO 애플리케이션을 Docker 컨테이너로 배포하기 위해 단일 단계 빌드 와 멀티 단계 빌드를 사용하여 멀티 단계와 단일 단계의 차이점을 이해하고 멀티 단계 빌드를 사용하여 컨테이너 이미지 크기를 줄여볼 것이다. 

 

# 단일 단계 빌드 Dockerfile 작성

ubuntu@docker:~/ch11/multi-stage$ vim dockerfile-go1

FROM golang:1.15-alpine3.12
WORKDIR /app
COPY gostart.go .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /app/gostart
ENTRYPOINT ["/app/gostart"]

 

# 멀티 단계 빌드 Dockerfile 작성

## stage1
FROM golang:1.15-alpine3.12 AS gobuilder-stage
MAINTAINER "jin <jin@sample.cloud>"
LABEL "purpose"="Application Deployment using Multi-stage builds."
WORKDIR /app/
COPY gostart.go /app/
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /app/gostart

## stage2
FROM scratch
COPY --from=gobuilder-stage /app/gostart /app/gostart
CMD ["/app/gostart"]

 

단일 단계와 달리 멀티 단계는 두 단계로 구성되어 있다. 첫번째 단계는 빌드 단계로 GO 애플리케이션을 빌드하고, 두 번째 단계에서는 최소한의 빈 이미지를 사용하여 최종적으로 이미지를 생성하고 첫 번째 단계에서 생성한 파일 /app/gostart 파일을 최종 이미지로 복사하여 실행하는 것이다.

 

 

# 이미지 비교

ubuntu@docker:~/multi-stage$ docker history goapp:1.0
ubuntu@docker:~/multi-stage$ docker history goapp:2.0

 

도커 이미지를 비교를 해보면 똑같은 일을 하는데도 용량차이가 많이 난다.  도커 이미지 크기를 줄여야 하는 이유는 도커 이미지 관리할 때 저장 장치(ex: 하드 디스크) 용량을 줄이기 위해 사용한다. 개발자가 아닌 운영팀 입장에서는 도커 이미지 크기를 줄이는 것이 중요한 일 중 하나이다. 애플리케이션 버전별로 도커 이미지를 관리해야 하기 때문이다. 

 

# 컨테이너 실행

ubuntu@docker:~/multi-stage$ docker run --name=goapp1 -p 9091:9090 -d -h goapp1 goapp:1.0
c13e4153bb06c4276b46c58cd1b2968f70e516a2dc13ad27679f5f32c76f87c0

ubuntu@docker:~/multi-stage$ docker run --name=goapp2 -p 9092:9090 -d -h goapp2 goapp:2.0
395bb3772fbc530a75f4fcee88453a5a0c0b6e71f552d58243453e13e12c2458

 

 


# 2. Docker shell-scripts - Multi-Stage Build

# 실행할 스크립트 작성

ubuntu@docker:~/multi-stage$ vi appstart.sh
#!/bin/bash
echo "Best image build, multi stage build!"

>> 결과 확인
ubuntu@docker:~/multi-stage$ sh appstart.sh
Best image build, multi stage build!

 

# 스크립트 실행 권한 부여(퍼미션 변경)

>> 퍼미션 변경전
ubuntu@docker:~/multi-stage$ ll
-rw-rw-r--  1 ubuntu ubuntu   57 11월  4 11:17 appstart.sh

>> 퍼미션 변경 후
ubuntu@docker:~/multi-stage$ chmod +x appstart.sh
ubuntu@docker:~/multi-stage$ ll
-rwxrwxr-x  1 ubuntu ubuntu   57 11월  4 11:17 appstart.sh*

 

# 단일 / 멀티 단계 빌드 과정

>>> 단일 단계
ubuntu@docker:~/multi-stage$ vi dockerfile-app1
FROM ubuntu:14.04
RUN apt-get update -y && apt-get install nginx -y
COPY appstart.sh /
RUN useradd user01
USER user01
ENTRYPOINT ["/appstart.sh"]

========================================

>> 멀티 단계
ubuntu@docker:~/multi-stage$ vi dockerfile-app2
FROM ubuntu:14.04 as v1-stage
RUN apt-get update && apt-get install nginx -y
WORKDIR /app
COPY appstart.sh /app

FROM alpine:3.12.1
RUN addgroup -S appgroup && adduser -S user01 -G appgroup -h /home/user01
COPY --from=v1-stage /app /home/user01
USER user01
ENTRYPOINT ["sh","/home/user01/appstart.sh"]

 

셀 스크립트는 리눅스 명령어니까 bash가 실행된다. bash를 실행하려면 리눅스가 있어야한다.(bash는 독립할 수 없기 때문) 

 

#이미지 빌드(크기 보고 싶으면  --no-cache 제외)

ubuntu@docker:~/multi-stage$ docker build -t webapp:1.0 -f dockerfile-app1 --no-cache .
ubuntu@docker:~/multi-stage$ docker build -t webapp:2.0 -f dockerfile-app2 --no-cache .


>>설치 후 용량 확인
ubuntu@docker:~/multi-stage$ docker history webapp:1.0, 2.0

 

 

저작자표시 비영리 변경금지 (새창열림)

'OS > Docker' 카테고리의 다른 글

[Docker] Docker Compose  (0) 2024.11.04
[Docker] Python Flask 웹 서비스 배포  (1) 2024.11.04
[Docker] 데이터 지속성을 위한 Volume 구성  (0) 2024.10.30
[Docker] scratch 이미지 경량화  (3) 2024.10.28
[Docker] 이미지 경량화  (1) 2024.10.28
'OS/Docker' 카테고리의 다른 글
  • [Docker] Docker Compose
  • [Docker] Python Flask 웹 서비스 배포
  • [Docker] 데이터 지속성을 위한 Volume 구성
  • [Docker] scratch 이미지 경량화
Kouji
Kouji
Journey to Becoming a Data & Server Engineer
  • Kouji
    Kouji's Data & Server Journey
    Kouji
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Programming
        • Python
        • SQL
      • Data & AI
        • Data Analysis
        • Ai
      • Cloud(AWS)
      • OS
        • Linux
        • Docker
        • Jenkins
        • Ubuntu
        • Window
        • Kubernates
        • Ansible
      • Network
        • NVIDIA
        • Network[이론]
        • Network[GNS3, Packet]
        • Network[On-Premise]
        • Network [L2, L3]
      • 트러블 슈팅
      • Life
        • My Career Stories
        • Personal
      • 개발 + OS 지식 함양
  • 블로그 메뉴

    • 홈
    • 관리 페이지
    • 글쓰기
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    네트워크
    ubuntu
    네트워크관리사
    AWS
    CISCO
    서버
    IT
    인프라엔지니어
    네트워크엔지니어
    스위치
    인프라
    서버엔지니어
    리눅스
    Linux
    웹
    화이팅
    dns
    클라우드엔지니어
    보안
    네트워크엔지니어링
    도커
    L3
    docker
    시스템엔지니어
    OS
    오블완
    VMware
    알고리즘
    티스토리챌린지
    라우팅
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Kouji
[Docker(go, shell-scr)] Multi-stage Build 이미지 경량화
상단으로

티스토리툴바