오빠 오빠 오빠 돈 많아?

peterTheAnteater·2024년 9월 4일
42

데브옵스

목록 보기
4/11
post-thumbnail

이 글은 짧고 간단하게 하나 갑자기 생각나서 올립니다. 비교적 진지하게 썼습니다. 제목 어그로는 못참겠습니다

도커로 프로젝트 관리를 하다보면 여러가지에 도커 이미지들을 가지고 도커파일을 작성 하게 됩니다.

그리고 도커파일을 작성하다보면 도커 허브에서 이미지들을 찾아보는데..
꼭 보면 아주 다양한 이미지 태그들이 존재합니다.

위는 Node 도커 이미지들입니다

뭐 bullseye, alpine, bookworm.. 등등 아주 다양한 태그들이 존재 합니다.

그럼 저희는 보통 뭘 사용 해야될까요?

이 글을 쓰게 된 동기

도커 이미지를 사용할때 초보분들, 아니면 도커를 잘 모르시는 분들은 어떤 이미지를 어떻게 사용 해야되는지 모르시는 분들이 많습니다.

솔직히 대부분 그냥 블로그에 올라온 도커파일 복붙 하시지 않습니까?

하지만 꼭 블로그에 올라온 이미지가 자기 프로젝트에 맞는거인지는 장담을 못합니다. 특히 대부분은 최적화가 안되어있는 경우가 많고요.

그래서 이번 글에서는 도커 이미지 종류와 프로젝트 도커파일 최적화에 대해서 알아보려고 합니다.

도커 이미지 종류와 차이점

latest

보통 latest 는 우분투 기반 풀 이미지를 사용합니다. 대부분 사이즈가 제일 크고 설치되어있는 패키지들이 많죠. 노드를 예시를 들면 사이즈
가 300메가 중반쯤 되죠. 호환성이 좋지만 이미지가 많이 무겁다는게 단점입니다.

bookworm & bullseye

bookwormbullseye 는 데비안 리눅스 os 기반으로 만든 이미지들입니다. 특히 저 둘은 Debian OS의 특정 Release (release이름들이 bookworm 과 bullseye입니다) 를 기반으로 만든 이미지들입니다. 둘이 어떤 차이가 있는지는 따로 찾아보시면 좋습니다.

slim

슬림은 latest (ubunut), bookworm, bullseye 모두 존재를 하는 경우가 많습니다. 기본 리눅스 패키지에서 구동하는데 불피요한 요소들을 조금 빼서 경량화 한 이미지들이죠. 사람들이 애용하는 이미지들입니다.

alpine

알파인은 Alpine Linux를 기반으로 만든 이미지입니다. 알파인 리눅스는 원래부터 가볍고 필요한 부분만 있는 리눅스 distro 입니다. 그래서 대부분 slim이미지 보다도 가볍고 작습니다.

그래서 뭘 사용하면 되나요?

사실 어디에 사용하는지 따라서 다르지만 가능하면 가벼운 이미지를 사용할수록 유리합니다. 이미지가 가벼울수록 빌드 시간, 구동 시간, 보안, 호스트 머신 디스크, 등등 대부분 유리합니다. 물론 필요한 기능이 특정 리눅스 버젼과 이미지에서만 존재를 한다면 어쩔수 없이 풀 패키지를 쓰거나 해야되는 경우가 많죠.

만약에 무거운 이미지 들만 사용하다가는 비싼 클라우드에서 용량이 꽉 찼다고 알림이 날아올는 불상사를 겪을수도 있습니다...

도커파일 최적화

아무리 이미지를 가벼운거를 사용해도 그 이후에 뭘 하는지에 따라서 많이 바뀝니다.

예를 들어 제가 Node로 서비스를 하나 만든다고 합시다. (nest.js)

보통 도커파일을 쓰면 이렇게 쓰게 되겠죠?

# 빌드 스테이지
FROM node:18-alpine

WORKDIR /app

# Dependency 설치
COPY package*.json ./

RUN npm install

# 소스코드 복사
COPY . .

# 빌드
RUN npm run build

# 실행
CMD ["npm", "run", "start"]

위 도커파일을 가지고 이미지 생성을 했더니
docker build -t velog/nest:not-optimized -f Dockerfile .

대충 600메가 정도의 이미지가 나왔습니다.

보시는거처럼 알파인 이미지를 사용해서 경량화를 조금 했지만 600메가는 작은 사이즈가 아닙니다. 물론 latest를 사용한거보다는 훨신 작습니다

만약에 알파인이 아닌 latest로 사용하면 아래와 같이 나옵니다
1.6기가,,,,미친 용량

빌드가 되는 언어들이나 노드같은 빌드를 실행하면 필드 폴더가 생성되는 프로젝트들은 한가지 치트키가 있습니다.

바로 빌드 스테이지와 실행 스테이지를 분리 함으로서 소스 코드를 빼는 겁니다.

이걸 적용하면 대충 아래와 같은 도커파일이 나옵니다

# 빌드할때만 사용하는 스테이지
FROM node:18-alpine AS builder

WORKDIR /app

# Dependency 설치
COPY package*.json ./

RUN npm install

# 소스코드 복사
COPY . .

# 빌드
RUN npm run build

####### 새로운 시작 #######

# 실행용 새로운 이미지
FROM node:18-alpine

WORKDIR /app

COPY --from=builder /app/package*.json ./ #복사해오기

RUN npm install

# 빌드된 파일들만 복사
COPY --from=builder /app/dist ./dist 

# 포트
EXPOSE 8000

# 실행
CMD ["npm", "run", "start"]

제가 노드 전문가가 아니라 노드 도커파일 작성이 서툽니다. 틀린 부분이나 최적화가 더 가능한 부분이 존재할 가능성이 높습니다.

달라진점은 builder라는걸 만들고 거기서 빌드된 파일과 필요한 부분만 복사 해온다는점입니다.

즉 저희는 npm run build를 했을때 나오는 빌드된 dist 폴더를 복사해와서 실행을 해주는거로 바꾼겁니다.

이렇게 되면 네스트가 실행이 되지만 소스 코드 자체는 이미지에 더이상 남아있지 않기에 훨신 가벼워 지죠.

그래서 이렇게 만든 결과는

더 작아졌습니다.

결론

위 예시에서는 극단적인 차이가 없었지만 Go, C++, Java 등등 컴파일 언어일수록 더 극단적인 차이가 생깁니다. 컴파일 언어는 Binary파일 하나만 남기고 다 날릴수 있으니까요. 진짜 가벼워집니다

물론 위 최적화는 돈이 많으면 상관이 없습니다. 오빠 오빠 오빠 돈 많아?
그래서 제가 제목을 저렇게 지은거고요.

하지만 대부분의 개발자들, 특히 학생이나 취준생들은 프로젝트에 돈을 많이 쓰기 어렵습니다. 저만 해도 개발자로서 돈은 벌지만 프로젝트만 하게 되면 짠돌이가 되거든요.

그래서 모두의 지갑을 지켜드리기 위해, 그리고 많은 분들이 간과하시는거 같은 도커파일 최적화의 대해서 좀 알아봤습니다.

읽어주셔서 감사합니다

profile
소프트웨어 개발과 밀당하는 개발자

5개의 댓글

comment-user-thumbnail
2024년 9월 4일

잘 보고 있습니다 ^^

1개의 답글
comment-user-thumbnail
2024년 9월 8일

잘 보고 갑니다!

답글 달기
comment-user-thumbnail
2024년 9월 12일

노드모듈 너무무거워서 .. 노드쓰는 프로젝트는 멀티스테이지 빌드 확실히 필요한 것 같읍니다

답글 달기
comment-user-thumbnail
2024년 9월 16일

Hello

It is often better to use a lighter image in terms of build time, security, and resource utilization. Notwithstanding the possibility of higher cloud storage expenses, you might have to use a heavier image if certain functionalities are only available in it.

Regards
Nisha Marshall
Prestige Evergreen
https://www.prestigesevergreen.info/

답글 달기