1. 컨테이너 이미지 크기에 대한 고찰
1. 이미지는 레지스트리를 통해 공유될 수 있다
- 이미지는 공간을 차지
- 차지하는 공간이 크면 전송비용, 보관 비용이 증가
2. 이미지는 컨테이너로 전개될 수 있다
- 이미지를 전개하면 내용이 컨테이너 스토리지를 구성
- 이미지의 크기 == 컨테이너가 차지하는 공간의 크기
- 운영 시스템의 디스크 공간 비용 증가
- 컨테이너 전개 전환 시간 증가
3. 따라서 이미지는 가급적 작게
- 전송 비용, 보관 비용 절감
- 컨테이어 운영 비용 절감
- 빠른 컨테이너 전개 속도
2. 이미지 크기를 줄이는 방법
컨테이너 전개 후 동작에 필요한 것만 남기기
ex)
- man 문서
-> 쉘 사용자는 필요하지만 동작하는 애플리케이션은 필요로 하지 않음
1. Multi Stage Build 이전
Dockerfile로 이미지 생성시 리소스를 직접 정리
- 개발 버전과 프로덕션 버전을 나눠서 관리
- 프로덕션 버전에선는 가급적 레이어를 적게 생성
-> RUN 구문을 최대한 적게 사용
방법
- 첫번째 개발 단계 이미지를 빌드
- 아티팩트를 복사하기 위해 컨테이너를 생성
- 생성된 컨테이너에서 아티팩트를 추출해 두번째 프로덕션 단계 이미지를 빌드
예시
#!/bin/sh
echo Building alexellis2/href-counter:build
docker build -t alexellis2/href-counter:build . -f build.Dockerfile
docker container create --name extract alexellis2/href-counter:build
docker container cp extract:/go/src/github.com/alexellis/href-counter/app ./app
docker container rm -f extract
echo Building alexellis2/href-counter:latest
docker build --no-cache -t alexellis2/href-counter:latest .
rm ./app
2. Multi Stage Build
1. Multi Stage Build란?
하나의 Dockerfile에서 앞의 상황을 작성
- 각기 서로 다른 베이스 이미지를 사용하고
- 각 단계간 필요한 파일을 복사할 수 있음
2. Multi Stage Build 예시
FROM golang:1.16
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go ./
RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app ./
CMD ["./app"]
--from=0 은 FROM 구문을 기점으로 index를 나누어 지정하는 방식
- Dockerfile에 수정이 발생하면 index가 변경되거나 찾기 힘들다는 단점
-> From 구문에 이름을 주어 이를 해결
3. Multi Stage Build 각 단계에 이름 부여
FROM golang:1.16 AS builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go ./
RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app ./
CMD ["./app"]
FROM golang:1.16 AS builder
-> COPY --from=builder /go/src/github.com/alexellis/href-counter/app ./
4. 단계 이름을 사용해 특정 단계 까지만 진행
docker build --target builder -t w10sim/MultiStageBuild:latest
builder 단계까지만 진행
5. 이전 단계를 새 단계로 사용
FROM alpine:latest AS builder
RUN apk --no-cache add build-base
FROM builder AS build1
COPY source1.cpp source.cpp
RUN g++ -o /binary source.cpp
FROM builder AS build2
COPY source2.cpp source.cpp
RUN g++ -o /binary source.cpp
3. 새롭게 지원되는 Buildkit
1. 기존 builder와 buildkit의 차이점
기존의 Builder
- 어떤 단계를 지정하면 해당 단계에 선행한 모든 단계를 처리
- 불필요해도 선행해서 기술했다면 실행(의존관계 처리 안함)
Buildkit
- 의존관계 분석에 따라, 의존성이 있는 선행 단계만 처리
2. Buildkit 사용 방법
1. 예시
FROM ubuntu AS base
RUN echo "base"
FROM base AS stage1
RUN echo "stage1"
FROM base AS stage2
RUN echo "stage2"
2. Buildkit을 이용한 빌드
DOCKER_BUILDKIT=1 docker build --no-cache -f Dockerfile --target stage2
- DOCKER_BUILDKIT=1 : BUILDKIT 활성화

- stage 1은 실행이 되지 않는것을 알 수 있다
3. 직접 해보기
1. 예시 선택
Rhymond/product-compare-react
2. 예시 분석
- React + Redux + Bootstrap +SASS 사용
빌드 준비물
3. 직접 빌드 해보기
1. ubuntu 20.04 환경 사용
docker run -it --name product-compare-react-builder -p 8000:80 -p 3000:3000 ubuntu:20.04 /bin/bash

2. NodeJS 와 NPM 설치
apt update
apt install nodejs npm
node --version
npm --version

NodeJS의 버전이 너무 낮아 삭제후 재설치
apt purge --auto-remove nodejs npm
apt install -y curl
curl -sL https://deb.nodesource.com/setup_14.x | bash -
apt install -y nodejs
node --version
npm --version

3. Git Clone 해오기
apt install -y git
mkdir /app
cd /app
git clone https://github.com/Rhymond/product-compare-react.git
4. 빌드해보기
1. 필요한 의존성 준비
cd /app/product-compare-react
npm install
오류 발생

2. python2.x 설치 후 의존성 준비
apt install -y python2 build-essential
PYTHON=/usr/bin/python2 npm install
오류 발생

3. --no-fund 옵션 사용
npm install --no-fund
성공

4. 빌드
npm run build

5. 서비스 실행 해보기
npm start


4. 빌드 결과를 Nginx로 서비스 하기
- 빌드 결과물 위치: /app/product-compare-react/build
1. Nginx 설치하기
apt install -y nginx
2. Nginx 실행
service nginx start
3. 접속해보기

4. 빌드 내용 넣고 재접속
cp –R /app/product-compare-react/build/* /var/www/html/

4. Dockerfile로 해보기
1. 빌드 단계
1. Dockerfile
FROM node:14 as builder
RUN mkdir /app
WORKDIR /app
RUN git clone https://github.com/Rhymond/product-compare-react.git
WORKDIR /app/product-compare-react
RUN npm install && npm run build
2. 이미지 빌드
docker build .

3. 이미지 확인

2. 런타임 단계: Nginx
1. Dockerfile
FROM nginx:latest
COPY --from=builder /app/product-compare-react/build /usr/share/nginx/html
2. 이미지 빌드
docker build -t w10sim/react:example .
3. 이미지 확인

3. 실행해보기
docker run -p 8000:80 w10sim/react:example

4. Docker Compose Build and Deploy
1. Docker-compose.yml 작성
services:
webapp:
image: w10sim/react:example
build: .
ports:
- "8000:80"
2. Docker Compose 빌드 실행
1. 기존 cache 내용 지우기
docker system prune -af
2. docker compose 빌드
docker compose up
3. 실행해보기
localhost:8000
