개요
웹 프론트엔드 개발자 설탕시럽입니다.
개발 기간이 예상보다 길어지고, 이래저래 수정사항이 많았지만 결국 QA 기간까지 왔습니다. QA 진행을 위해서는, 이제 로컬환경이 아닌 배포된 환경이 필요했고 AWS를 활용하여 배포하기로 했습니다. 어쩌다 보니 제가 aws를 활용하여 React 배포를 맡았지만, vercel, firebase hosting과 같이 쉽게 배포를 도와주는 툴이 아닌 aws를 통한 배포는 처음이었습니다. 처음 하는 김에 Docker를 활용해보고 싶은 호기심도 있어서, 우당탕탕 React + Vite + Nginx + Docker + AWS 환경에서 배포하는 과정에 대해 공유하려고 합니다
Docker
Docker란 무엇일까요? aws에서는 다음과 같이 설명하고 있습니다
Docker는 애플리케이션을 신속하게 구축, 테스트 및 배포할 수 있는 소프트웨어 플랫폼입니다. Docker는 소프트웨어를
컨테이너 라는 표준화된 유닛으로 패키징 하며, 이 컨테이너에는 라이브러리, 시스템 도구, 코드, 런타임 등 소프트웨어를 실행하는 데 필요한 모든 것이 포함되어 있습니다. Docker를 사용하면 환경에 구애받지 않고 애플리케이션을 신속하게 배포 및 확장할 수 있으며 코드가 문제없이 실행될 것임을 확신할 수 있습니다.
두 번째 줄, """소프트웨어를 실행하는 데 필요한 모든 것""" 이 컨테이너라고 정의하며, 소프트웨어가 실행될 수 있는 상태를 저장하여 압축한 것 을 Docker에서 이미지라고 하고, Docker의 핵심 기능이라고 볼 수 있습니다.
OS에서 실행중인 프로그램을 프로세스라고 한다면, 잘 동작중인 프로세스의 상태! 를 Docker에서는 이미지와 같은 형태로 저장하는 것이고, 컨테이너는 해당 이미지에 격리된 디스크 공간을 제공하여 실행되는 상태라고 이해했습니다.
Nginx
nginx는 정적 및 동적 웹 콘텐츠를 제공하는 웹 서버입니다. 클라이언트가 URL을 통해 페이지를 요청하면, 저희 서비스에서는 build 된 react 파일을 읽어와서, 사용자에게 전달하는 방식으로 활용했습니다.
nginx설정 파일과 dockerfile은 모두 local 에서 작성했습니다. local에서 실행할 수 있는 환경을 세팅하고, 테스트까지 마친 이미지를 docker hub를 통해서 aws ec2로 전달하게 끔 준비했습니다.
작성한 nginx 설정 파일은 아래와 같습니다
server {
#add_header Access-Control-Allow-Origin *;
listen 80;
listen [::]:80;
location / {
root /app/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
}
nginx에 대해서는 아직 자세하게 사용하지는 못하고, http만 개통하여 qa만 진행할 예정이어서 위와 같이 80 port로 index.html만 전달하는 설정을 했습니다.
Docker file
Docker image 를 생성하기 위해서는, Dockerfile이라는 설정 파일이 필요합니다. 앞서 말한 것처럼, Docker Image는 프로세스가 정상적으로 실행되는 상태를 갖고 있어야 하기 때문에, build 된 파일을 가지고 nginx로 배포하는 단계를 설정파일에 작성했습니다.
FROM nginx:latest
RUN mkdir /app
WORKDIR /app
RUN mkdir ./dist
ADD ./dist ./dist
COPY ./default.conf /etc/nginx/conf.d
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
이후 build 된 이미지를 build 하고 정상적으로 실행되는지 Local에서 아래 명령어를 통해 테스트를 진행했습니다.
//image build 명령어
docker build -t frontend .
//image 실행 명령어
docker run -d --name frontend_test -p 8300:80 frontend
정상적으로 동작되는 것을 확인한 후에, docker hub에 image를 push 하여 aws에서 이미지만 가져와서 사용할 수 있게끔 하고자 했습니다.
//docker 로그인
docker login
//docker hub에 image push
docker tag frontend {user_id}/frontend:{version}
docker push {user_id}/frontend:{version}
AWS EC2
배포를 위해 AWS의 EC2를 활용했습니다. EC2 선정에는 큰 의미는 없었고, 간단하게 서버 컴퓨터 한 대정도를 이용할 수 있다고 생각했고, Docker와 AWS 두 분야 모두 이번에 처음 해보지만, 그나마? 만져본 적은 있는 EC2를 선택했습니다. EC2의 인스턴스 생성 및 실행 절차는 다음과 같습니다.
1. EC2 인스턴스 시작
2. Amazon Linux 선택 - t2.micro ( 현재로서는 프리티어를 사용할 예정입니다 )
3. 키페어 생성 ->. pem 형식으로 프라이빗 키 파일 받기
pem 형식으로 생성한 프라이빗 키 파일을 통해 ec2에 ssh 방식으로 접속합니다! ( 파일 위치를 수정하는 등 잘 관리해 주세요 )
4. 실행 중인 인스턴스 선택 - 우 상단 연결 버튼 클릭 - SSH 클라이언트 탭 - pem이 다운로드되어있는 폴더에서 명령을 하나씩 실행
5. 인스턴스 연결 성공!
보안 규칙 수정
인스턴스에 연결에 성공했다면, 저희 인스턴스의 보안 규칙을 수정해야 합니다. 보안 규칙 중 저희가 수정해야 하는 내용은 인바운드 규칙( 인스턴스로 요청이 들어오는 부분 제어)에서 배포 때 사용할 포트를 열어 주셔야 합니다. ( 저희는 http 80 포트를 열어 줬습니다 )
1. 보안 그룹 - 속한 보안 그룹 클릭
2. 인바운드 규칙 편집
3. 유형 지정 ( HTTP의 경우는 존재) - 0.0.0.0/0 ( 모든 HTTP 요청을 허용 )
탄력적 IP 할당
보안 그룹 설정이 완료되었다면, 탄력적 IP도 할당해 줘야 합니다. 탄력적 IP를 할당해 주지 않는 다면? 인스턴스가 재시작할 때마다, IP가 변경되고 이상하지만,,,? 저의 경우에는 HTTP로 접속도 잘 되지 않았습니다. 따라서 우측 탭에서 탄력적 IP도 설정해 주시면 됩니다
1. 탄력적 IP - 탄력적 IP 주소 할당
2. 탄력적 IP 주소 연결 - 생성한 인스턴스 선택 - 연결
EC2 설정
이제 ec2에 접속해서 docker관련 설정 및 이미지를 받아와서 실행할 준비를 해야 합니다.
우선 docker 설치 명령입니다.
sudo yum install docker
sudo service docker start
docker 설치가 완료되었다면, docker hub에서 push 한 이미지를 받아와야 합니다.
// docker login
sudo docker login
// docker hub의 이미지 가져오기
sudo docker pull {user_id}/frontend:{version}
// docker run
sudo docker run -d --name frontend -p 80:80 {user_id}/frontend:{version}
이렇게 EC2에서 React Docker로 실행하기! 완료했습니다.
실패...
이렇게 성공할 줄 알았으나,,, 실패했습니다
Docker Image의 빌드 호환성 문제가 발생했습니다. 제가 이미지를 build 한 환경은 macbook인데 EC2의 플랫폼과 맞지 않아서 이미지를 실행할 수 없는 문제에 발생했습니다.
그래서..
위의 이미지를 build 하는 과정을 local에서 안 하고 EC2에서 직접 했습니다! EC2에 Git과 React를 실행하기 위한 Node을 설치하고 저희 repo를 pull해와서 build -> 이미지 생성을 하는 과정을 거쳤습니다.
마무리하며...
이렇게 EC2를 활용하여 배포를 진행해 보았습니다. 현재는 고정된 IP를 통해서만 접근이 가능하여 QA에서 내부적으로만 사용 가능하지만, 추후 외부적으로 사용하기 위해 Domain을 연결하고 HTTPS를 다루는 과정 또한 블로그에 남겨보려고 합니다. 또, Github Action을 활용하여 CI/CD 설정되는 내용까지 가능하다면 정리해 보겠습니다
'React' 카테고리의 다른 글
[React] 웹뷰로 연결된 Android Stuiod / IOS 에 데이터 주고받기 ( 브릿지 통신 ) (0) | 2024.11.11 |
---|---|
[AWS] Sub Domain 연결하기 (5) | 2024.10.31 |
[React, Typescript] Intersection Observer를 활용하여, 사용자 화면에 맞게 변화하는 컴포넌트 만들기 (1) | 2024.05.14 |
useState 딥다이브 (0) | 2023.06.04 |
JSX (0) | 2023.05.17 |