본문 바로가기
docker-kub

docker - 멀티스테이지 빌드

by 오우지 2023. 1. 15.

다양한 프론트엔드 프레임워크가 있지만 package.json 파일을 살펴보면

 

vue의 package.json

 

react의 package.json

빌드와 개발 환경의 명령어가 다른 것을 확인할 수 있다. react를 기준으로 이야기하자면 아래 사진의 명령어를 보면 react-script라는 서드파티 패키지를 이용한 컴파일이고 start는 개발 모드라고 보면 된다. 

 

개발 모드

- hot-module-replace가 동작해 수정과 동시에 화면이 변경된다.

- 에러가 있을시 브라우저에 메시지를 출력한다.

- 디버깅을 위한 무거운 서버가 제공된다.

- react 코드가 node 환경에 종속되는 것을 의미한다.

 

 

운영 모드

- build는 배포 환경에서 사용할 파일을 압축 형태로 만들어준다. 그러면 우리가 선택한 웹 서버의 도움을 받아 스스로 서비스를 제공할 수 있다.

- 파일만 있지 실제 서버는 만들어주지 않는다.

- 최적화된 javascript 코드가 만들어지기 때문에 node 환경에 종속되지는 않는다.

 

이런 다양한 환경을 위해 도커에는 멀티 스테이지 빌드가 존재한다.


멀티 스테이지 빌드

멀티스테이지 빌드란 파일 내부에 스테이지라고 하는 여러 빌드 단계를 정의해 결과물을 가져갈 수 있는 것으로 빌드 단계에서는 필요하지만 최종 단계에서는 필요하지 않은 모듈을 없애기 위해 사용된다.

 

FROM node:14-alpine as build

WORKDIR /app

COPY package.json .

RUN npm install

COPY . .

RUN npm run build

FROM nginx:stable-alpine
# node는 빌드 파일을 만들기 위해 필요하고 운영환경에선 필요하지 않기 때문에 운영 환경에서 사용할 서버로 베이스 이미지를 대체한다.
COPY --from=build /app/build /usr/share/nginx/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

FROM은 새로운 빌드 스테이지가 시작되었음을 나타내며 여기에 FROM을 하나 더 추가해서 test하는 과정을 껴 넣을 수도 있다.

 

첫 번째 FROM은 지금까지 봤던 자바스크립트 코드를 빌드하는 단계다.

 

두 번째 FROM은 새로운 스테이지를 의미하며 그 아래 COPY 명령어에서 --from=builder라는 옵션이 붙어있다. COPY 명령어를 도커 호스트가 아닌 build스테이지로부터 실행한다는 의미다.

 

--target 명령어를 통해서 특정 스테이지까지만 빌드 프로세스를 실행시킬 수도 있다. 위의 Dockerfile의 FROM절 첫 번째 까지 실행시키고 빌드 프로세스를 종료시키고 싶다면

docker build --target build -f frontend/Dockerfile.prod ./frontend

이렇게 작성해주면 된다.

 

이제 프론트엔드 코드를 보자.

기존 ECS나 동일 컨테이너 네트워크 상에서는 localhost로 접근하는게 맞지만 프론트앤드 코드는 빌드된 이후에 사용자 머신의 브라우저 내부에서 실행되게 된다. 여기서 localhost를 사용하게 된다면 해당 엔드포인트의 ip주소를 가리키게 될 것이다. 따라서 로컬과 빌드에서의 환경변수를 다르게 넣어줘야 한다.

 

const backendUrl = process.end.NODE_ENV === 'development' ? 'http://localhost' : 'goals-react-lb-430104102.us-east-2.elb.amazonaws.com'

여러 방법이 있겠지만 우선은 이렇게 넣어주자. 개발서버라면 localhost, 운영 서버라면 로드밸런서의 DNS url을 넣어줬다.

 

 

docker build -f frontend/Dockerfile.prod -t academind/goals-react ./frontend

도커를 빌드해주는데 -f 를 이용해 사용할 Dockerfile의 파일을 지정해주고 마지막에 빌드 한 이미지를 놓을 루트를 지정해준다.

 

이걸 ECS에 Task를 하나 더 추가해서 배포해주면 된다. 주의할점은 backend가 먼저 실행되게 순서를 정해야 한다는 것이다. 

 

 

 

출처:

https://lynlab.co.kr/blog/89

udemy docker-kubernetes

'docker-kub' 카테고리의 다른 글

MySQL SpringBoot docker-compose  (0) 2023.08.09
kubernetes - intro  (0) 2023.01.28
ECS를 이용한 배포  (0) 2023.01.02
docker - Docker Compose, utility container  (0) 2022.11.13
docker - 멀티 컨테이너 어플리케이션  (0) 2022.10.30