docker + ec2 로 react 프로젝트 배포하기

부지런한 배짱이🤟·2023년 2월 26일
3

🚀 배포할 프로젝트의 기술스택
🏁 react + node.js (express) + mongoDB 풀스택 프로젝트

🤔  EC2 + docker 로 배포 선정이유
⇒ ec2 터미널에서 프로젝트 환경을 설치-세팅해서 배포하기보단
docker 로 모든 환경을 구축해서 ec2 에서 가져오기만 하는 방식이 테스트하기도 좋고
AWS 과 docker 공식 문서에서 설명하는 비용절감과 편리한 코드전달 등의 이유로 docker를 사용해보기로 결정!

개발친구 구글링과 유투브 선생님들, 공식문서 참고해서 나름의 순서를 정리하고 시작했다.
docker + ec2 배포하기 단계

  • dockerfile 로 이미지파일 생성 ⇒ 컨테이너로 실행해보고 테스트하기
  • docker hub 에 이미지 올리기
  • ec2 에 docker 설치 및 로그인
  • ec2 에서 docker hub 에 있는 이미지를 pull 하여 컨테이너 실행하기
    정리하면 쉽지만 과정은 순탄지 않았다ㅎㅎ…ㅎㅎ

1️⃣ docker 이미지 생성, 컨테이너 실행

빌드에 앞서 docker 설치
https://goddaehee.tistory.com/312 ⇒ 참고하여 설치, 터미널에 sudo -v 했을때 버전 정보가 뜬다면 잘 설치되어있는 것

dockerfile 만들기

  • 내 프로젝트는 client/server 나뉘어져 있었고 각각의 폴더의 최상단 디렉토리에 dockerfile 을 만들어줬다
  • client 디렉토리에서는 추가적으로 nginx 설정 파일을 추가했다.
  • nginx 로 React 이미지 생성
    • client: dockerfile, nginx.conf 파일 추가하기
      FROM nginx
      
      # root 에 app 폴더를 생성
      RUN mkdir /app
      
      # work dir 고정
      WORKDIR /app
      
      # work dir 에 build 폴더 생성 /app/build
      RUN mkdir ./build
      
      # host pc의 현재경로의 build 폴더를 workdir 의 build 폴더로 복사
      ADD ./build ./build
      
      # nginx 의 default.conf 를 삭제
      RUN rm /etc/nginx/conf.d/default.conf
      
      # host pc 의 nginx.conf 를 아래 경로에 복사
      COPY ./nginx.conf /etc/nginx/conf.d
      
      # 80 포트 오픈
      EXPOSE 80
      
      # container 실행 시 자동으로 실행할 command. nginx 시작함
      CMD ["nginx", "-g", "daemon off;"]
      
      server {
          listen 80;
          location / {
              root    /app/build;
              index   index.html;
              try_files $uri $uri/ /index.html;
          }
      }
    • server : dockerfile 파일 추가하기
      # 가져올 이미지를 정의
      FROM node:16
      # 경로 설정하기
      WORKDIR /app
      # package.json 워킹 디렉토리에 복사 (.은 설정한 워킹 디렉토리를 뜻함)
      COPY package.json .
      # 명령어 실행 (의존성 설치)
      RUN npm install
      # 현재 디렉토리의 모든 파일을 도커 컨테이너의 워킹 디렉토리에 복사한다.
      COPY . .
      
      # 각각의 명령어들은 한줄 한줄씩 캐싱되어 실행된다.
      # package.json의 내용은 자주 바뀌진 않을 거지만
      # 소스 코드는 자주 바뀌는데
      # npm install과 COPY . . 를 동시에 수행하면
      # 소스 코드가 조금 달라질때도 항상 npm install을 수행해서 리소스가 낭비된다.
      
      # 3030번 포트 노출
      EXPOSE 3030:3306
      
      # npm start 스크립트 실행
      CMD ["npm", "start"]
      

Docker 이미지 빌드하기 ,컨테이너 실행하기

  • docker build 전 빌드하려는 디렉토리에 있는지 확인하는 것 필수
# 클라이언트단 빌드
sudo docker build -t 이미지이름 .
sudo docker run -d --name 컨테이너이름 -p 8300:80 이미지이름
# run : 실행
# -d : 백그라운드 모드
# -p 8300:80 : 포트 연결 외부노출포트:내부포트
# 컨테이너에서 사용할 이미지 이름은 위의 명령어에서 만들어준 이미지 이름과 동일해야한다. 
  • 빌드한 이미지로 컨테이너 실행을 했다면 docker 창에서 생성된 컨테이너를 확인할 수 있음
    - sudo docker ps 명령어로 현재 실행중인 컨테이너 목록을 확인할 수 있음
    - localhost://8300 으로 들어가서 잘뜬다면 성공
    - 동일하게 server 단 코드도 이미지 빌드해주고 컨테이너 실행후 테스트 해본다!

Docker hub 에 push

  • 생성한 이미지로 실행한 컨테이너가 잘 작동한다면 이제 docker hub에 만든 이미지를 공유해보기
sudo docker tag nginx-react zeeyoon/nginx-react:latest
# 연결하기! 생성해둔이미지이름 레파지토리에올릴이름:버전
sudo docker push zeeyoon/nginx-react:latest
# push 하기 

docker hub 에 올라와있는 것을 확인할 수 있음

2️⃣ AWS ec2 인스턴스 생성하기!

  • 프리티어로 인스턴스를 생성해준다.

  • 키 페어를 생성해주고 권한 설정 해주기

  1. 프라이빗 키(.pem)를 보안된 위치인 .ssh 하위 디렉터리에 저장
mv ~/Downloads/키페어파일 ~/.ssh/키페어파일
  1. 프라이빗 키(.pem)의 권한 설정
chmod 400 ~/.ssh/키페어파일
  • 인스턴스 연결하기
    - 나는 추가적으로 탄련적 IP 를 만들어서 고정 ip 를 생성했다.
    - 탄련적 IP 발급받고 연결을 안하면 요금이 부과될수 있다고 하니 주의하자!

인바운드 규칙 추가해주기

  • EC2 > 보안그룹 > 인바운드편집 에서 규칙 추가해주기
  • 클라이언트 포트는 8300 , 서버포트는 3030을 사용하도록 나누었고 인바운드 규칙에 추가해줬다.
    • ec2 에서 pull 받은 이미지로 컨테이너를 실행할때 해당 포트로 연결해줘야한다!
    • nginx 는 8300 으로, server 는 3030 으로 연결
  • 터미널에서 ec2 접속해주기
  ssh -i 생선한키파일.pem 사용자이름@발급받은퍼블릭ip주소
  • 아래처럼 뜨면 접속성공!

docker 가져오기

  • docker 를 사용하지 않았을때, node 설치, git 설치 및 가져올 코드 클론, nginx 설정 등등 을 여기서 해야하지만 나는 모든 환경세팅과 코드가 있는 도커 이미지가 있기 때문에 docker 를 설치해주고 docker hub 에 있는 이미지를 가져오면 된다.

EC2 에서 docker 설치하기

sudo yum install docker -y
# 설치해주기
sudo docker login
# 로그인해주기 
sudo service docker start
# docker 시작하기

docker 이미지 pull 하고 컨테이너 실행하기

  • client, server 단 이미지 2개 모두 pull 하고 컨테이너를 실행해준다.
sudo docker pull zeeyoon/nginx-react:latest
# 도커가 로그인 되어있다는 가정하에!
# 내가 만든 레파지토리를 Pull 해오기
sudo docker run -d --name my-react-app -p 8300:80 zeeyoon/nginx-react:latest
# 가져온 이미지를 컨테이너를 만들면서 실행시킨다. 

# 서버단 이미지도 똑같이 pull 받고 실행해준다. 
sudo docker run -t -i -p 3040:3307 zeeyoon/tdz-node
  • 퍼블릭 주소로 접속해보니 api 연결도 잘되고 배포도 잘되었다…😭😭😭😭

프론트엔드 개발자 취업을 하는데 내 프로젝트를 눈으로 확인할 배포사이트 하나 없는게 계속 마음에 걸려 그냥 내가 배포해버리자..^^..! 라는 가벼운 마음으로 시작했지만 역시 어려웠다.
(AWS 도 제대로 모르는데 docker 까지 하려니 중간에 다놔버리고 싶었지만ㅎㅎ 어찌저찌 배포했다.)

다하고 보니 사람들이 왜 배포자동화 ci/cd 에 대해 이야기하는지 필요성을 알게되었다.
코드 바뀔때마다 이 과정들을 다시 반복하는것은 너무 비효율적인것 같고 추가적으로 공부해서 적용해봐야겠다🤔

🚩참고한 자료

profile
UX에 관심많은 프론트 엔드 개발자입니다:)

0개의 댓글