리액트 APP을 쉽고 빠르게 배포하기 위해서는 heroku와 같은 웹 서비스를 이용해볼 수 있다. 이러한 서비스들은 빠르고 쉽지만 애플리케이션을 자유롭게 커스터마이징하는 것은 힘들고 비용 또한 변동성이 크다는 단점이 있따.
과거에는 웹 애플리케이션을 배포하기 위해서는 장비준비,파일설치,소스설치,배포 등등을 직접 했었다고 한다. 하지만 요즘은 애플리케이션을 하나의 컨테이너로 만들어서 배포하는 것이 일반적이다.
이 컨테이너를 만드는 게 바로 도커이다. 도커 홈페이지에서는 도커를 아래와 같이 소개하고 있다.
도커는 개발자가 모던 애플리케이션을 구축, 공유, 실행하는 것을 도와줄 수 있도록 설계된 플랫폼이다. 도커는 지루한 설정 과정을 대신해줘 개발자가 코드 작성에 집중할 수 있게 해준다.
이 지루한 설정 과정은 뭘까? 웹 애플리케이션을 배포하기 위해서는 앞서 말한듯이 컴퓨팅 리소스확보 , 라이브러리 설치 , 외부 네트워크로 애플리케이션 개방 등 정말 많은 일이 필요하다. 즉 리소스 확보 -> 운영체제 설치 -> Node.js설치 -> 빌드 이 과정을 직접 해줘야 하는데 도커는 이 과정을 대신 해준다.
이제 CRA와 CNA를 통해 만든 프로젝트를 도커를 활용하여 컨테이너 단위로 패키징해보자.
도커 용어
이미지 : 컨테이너를 만드는데 사용되는 템플릿, Dockerfile 파일을 빌드하여 만든다.
컨테이너 : 도커의 이미지를 실행한 상태, 이미지가 목표하는 운영체제, 파일 시스템, 네트워크 등이 할당된다.
Dockerfile : 어떤 이미지 파일을 만들지 정의하는 파일
태그 : 이미지를 식별할 수 있는 레이블 값, 이름:태그명 형태로 구성된다.
리포지터리 : 이미지를 모아두는 저장소
레지스트리 : 리포지터리에 접근할 수 있게 해주는 서비스로 대표적으로 도커 허브가 있다.
도커 CLI 명령어(자주쓰는 것)
docker build : Dockerfile을 기준으로 이미지를 빌드
docker push : 이미지나 리포지터리를 레지스트리에 업로드하는 과정
docker tag : 이미지에 태그를 생성하는 명령어
docker inspect : 이미지나 컨테이너의 세부 정보를 출력하는 명령어
docker run : 이미지를 기반으로 새로운 컨테이너를 생성하는 명령어
docker ps : 현재 가동중인 컨테이너 목록을 확인할 수 있는 명령어
docker rm : 컨테이너를 삭제하는 명령어
자, 이제 직접 도커를 만들어보자.
먼저 도커를 설치해주자.
각자 운영체제에 맞게 도커를 설치해주자.
도커가 잘 설치되었는지 위 명령어를 활용하여 확인해볼 수 있다.
프로젝트를 만들기 전에 도커 이미지에서 해야하는 작업을 간단하게 알아보자.
1. 운영체제 설정
2. Node.js 설치
3. npm ci
4. npm run build
5. 실행
npx create-react-app docker-run
먼저 CRA을 통해서 프로젝트를 하나 만들어주고 Dockerfile이라는 이름의 파일을 하나 만들고 아래와 같이 내용을 작성해주자
FROM node:18.12.0-alpine3.16 as build
# 이미지가 어떤 베이스 이미지에서 실행될지 결정, alpine리눅스는 일반 리눅스보다 가볍고 깔끔한 리눅스이다.
# 이미지는 도커 허브에서 가져오게 된다. 즉 이 한줄로 운영체제 설치없이 사용이 가능하다.
WORKDIR /app
# 작업을 수행하고자 하는 기본 디렉터리
COPY package.json ./package.json
COPY package-lock.json ./package-lock.json
# package.json 을 ./package.json으로 복사
# 복사하는 위치는 기본디렉터리 즉 /app이 된다.
RUN npm ci
# RUN으로 컨테이너에서 명령을 실행할 수 있다.
COPY . ./
# 의존성을 설치했으니 빌드를 해야한다. src,node_modules등 대부분 리소스가 필요하므로
# . ./명령어로 모든 리소스를 복사한다.
RUN npm run build
# 명령을 통해 애플리케이션을 빌드한다.
이제 만든 도커 이미지를 빌드해보자.
docker build . -t cra:docker-run
이미지 빌드가 완료되면 도커 데스크톱에서도 확인해볼 수 있다.
보면 아무런 코드를 작성하지 않았음에도 도커 파일이 생각보다 크다. 대부분은 Node.js, node_modules가 차지하고 있다.
이미지를 한번 실행해보자. 이미지를 누르고 Run을 누르면된다.
우리가 원하는 것은 애플리케이션 빌드뿐 아니라 실행까지이므로 아래와 같은 작업을 추가해주자.
1. 빌드된 웹 애플리케이션을 NGINX가 서비스할 수 있도록 설정
2. 이미지가 실행되었을 때 해당 웹페이지에 접근할 수 있어야 함
3. 웹페이지 접근에 필요한 빌드 파일만 남겨두고 용량을 최소화함
FROM node:18.12.0-alpine3.16 as build
# 이미지가 어떤 베이스 이미지에서 실행될지 결정, alpine리눅스는 일반 리눅스보다 가볍고 깔끔한 리눅스이다.
# 이미지는 도커 허브에서 가져오게 된다. 즉 이 한줄로 운영체제 설치없이 사용이 가능하다.
WORKDIR /app
# 작업을 수행하고자 하는 기본 디렉터리
COPY package.json ./package.json
COPY package-lock.json ./package-lock.json
# package.json 을 ./package.json으로 복사
# 복사하는 위치는 기본디렉터리 즉 /app이 된다.
RUN npm ci
# RUN으로 컨테이너에서 명령을 실행할 수 있다.
COPY . ./
# 의존성을 설치했으니 빌드를 해야한다. src,node_modules등 대부분 리소스가 필요하므로
# . ./명령어로 모든 리소스를 복사한다.
RUN npm run build
# 명령을 통해 애플리케이션을 빌드한다.
FROM nginx:1.23.2-alpine as start
#빌드된 정적 파일을 서스 하 위 NGINX가 설치된 리눅스를 설치
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
COPY --from=build /app/build /usr/share/nginx/html
# build라는 단계에서 파일을 복사해옴, 빌드에서 필수족인 리소스만 가져와 start에서 사용한다.
EXPOSE 3000
#3000포트를 열어준다.
ENTRYPOINT ["nginx","-g","daemon off;"]
# 컨테이너가 시작되었을 때 어떤 명령을 실행할지 결정
해당 도커를 다시 빌드해보자... 를 했는데 자꾸 에러가 나왔다.
말그대로 nginx.conf파일이 없어서 생긴 문제이니 해당 파일을 만들어주자.
nginx.conf는 아주 간단하게 아래처럼 적어주자.
events{
}
http {
server {
listen 3000;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
}
아까빌드한 파일보다 파일 크기가 많이 줄어든 것을 알 수 있다. 해당 이미지를 실행하기 위해서는 EXPOSE로 명시했던 포트를 열어줘야 한다.
이후 localhost:3000에 접속하면 CRA페이지가 뜨고 아래와 같이 Logs가 뜨게 된다.
'FrontEnd > Deep Dive' 카테고리의 다른 글
[React] Deep Dive 모던 리액트(26) 리액트 18 추가된 훅 (1) | 2024.02.07 |
---|---|
[React] Deep Dive 모던 리액트(25) 리액트 17 변경점 (2) | 2024.02.06 |
[React] Deep Dive 모던 리액트(23) gitHub Action CI (0) | 2024.02.03 |
[React] Deep Dive 모던 리액트(22) Next.js 개발환경 구축 (0) | 2024.02.02 |
[React] Deep Dive 모던 리액트(21) 테스트 (0) | 2024.01.17 |