엘리스 AI트랙 4기/프로젝트

AWS EC2에 프로젝트 배포하기_1탄

남쪽마을밤송이 2022. 5. 30. 06:00

 [01  AWS EC2란? ] 

  • EC2는 간단하게 AWS에서 제공하는 클라우드 컴퓨팅 서비스.
  • 쉽게 말해, 아마존으로 부터 한 대의 컴퓨터를 임대하는 것이다.
  • 프로젝트가 끝나고 나서는 엘리스가 제공하는 VM을 더이상 사용하지 못하기 때문에 배포 서버를 옮겨야 하는데, AWS와 Heroku를 고민했었다. 구글링으로 서치해 비교해본 결과 Heroku는 배포가 쉬운 대신 느리고, AWS에 비해 인스턴스 제어(로드 밸런싱, 방화벽 설정 등)가 제한적인 것 같았다. 그리고 어쨌든 AWS를 훨씬 더 많이 쓰니까, 이번 기회에 공부해서 배포해 보기로 했다.
  • 결론적으로는 6시간만에 배포에 성공했고, 나중에 다른 프로젝트를 배포하게 될 때를 대비해서 시행착오를 겪은 과정과 해결 과정을 남기려고 한다.

 [02 EC2 사용 준비 ] 

 (1) EC2 인스턴스 생성 

  • 구글의 많은 블로그들을 참고하여 AWS 회원가입을 하고 기본 설정으로 EC2 인스턴스를 생성했다.
    • OS(AMI)는  ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-20220420 로 설정했다.
    • 처음에 키페어를 생성하지 않고 넘어가려 했는데 경고창이 떴었다. 밑에 SSH 연결할 때도 필요하니 생성하고 파일을 다운로드 받아서 잘 관리하자.
    • 리전을 서울로 설정해야 빠르게 동작하는데 회원가입은 서울로 해놓고 리전이 캘리포니아로 되어 있는 것을 한참 뒤에 확인했다... 심하게 느린게 프리티어라서 그런줄 알았는데 분명히 머나먼 리전도 영향이 있었을 것😂 나중에 서울로 옮길 것이다.

 (2) SSH로 VM 연결 

  • 윈도우의 경우 powershell이나 cmd를 사용해도 되지만 나는 편하게 MobaXterm을 사용했다.
  • 아래와 같이 public IP, username, X11-Forwading 체크 해제, key pair 파일 경로를 설정하고 연결해주면 된다.
    • 주의할 점은 나는 다른 블로그를 따라하며 username을 무작정 ec2-user로 했더니 연결이 되지 않았다.
    • 알고보니 OS별로 기본 생성되는 username이 달랐던 것! 여기를 확인하고 알 수 있었다.

 [03 VM 환경 세팅 ] 

 (1) 필요한 서비스들 설치 

  • 먼저 보안을 위해 root 계정 비밀번호를 설정해준다. 이후 편의를 위해 대부분의 작업을 root 계정으로 진행했다.

  • 그리고  sudo apt update 를 실행해준 뒤 필요한 서비스들을 하나씩 설치했다.
    • 나는 nginx, nodejs, npm, redis를 설치했다.
    • 참고로 npm은 nodejs의 LTS 버전을 설치하면 함께 설치된다고 한다.

 (2) 프로젝트 소스 코드 세팅 

  • git은 기본적으로 깔려있었어서 git clone으로 우리 팀이 작업한 프로젝트를 가져왔다.

  • 이후 front와 back의  .env  파일을 만들어서 내용을 넣어주고 각각  npm i 로 필요한 모듈들을 설치해주었다.

  • 그리고 이제  npm run build 으로 react를 빌드하려는데 어쩐지 순조롭다 했지... 아래 두 가지 오류가 번갈아가면서 나타났다.
    1. Reached heap limit Allocation failed - JavaScript heap out of memory
    2. Creating an optimized production build...에서 그냥 몇 십분이고 멈춰있음
  • 원인은 프리티어 OS이다보니 t2.micro 사양을 사용하게 되는데 그러면 램이 1기가밖에 되지 않아서 규모가 큰 React를 build할 때 메모리 초과가 나는 것이었다.
  • 보통 한 두 가지 방법으로 해결된 사람들이 많았는데 나는 그래도 안돼서 아래 세 가지 방법을 모두 적용해 메모리를 조금이나마 늘려 문제를 해결할 수 있었다. (참고1, 참고2)
    1. 메모리 스왑을 통한 메모리 늘려주기
       free 
        - Swap 메모리 없는 것 확인

       sudo dd if=/dev/zero of=/mnt/swapfile bs=1M count=2048 
       sudo mkswap /mnt/swapfile 
       sudo swapon /mnt/swapfile 

       free 
        - Swap 메모리로 약 2기가 할당
        - 이처럼 가상메모리를 사용하면 퍼포먼스의 문제가 생기므로 임시적으로 사용하고 다시 되돌려놔야 함
    2. heap 메모리 부족 현상 해결
       "start" : "react-scripts --max_old_space_size=4096 start", 
       "build" : "react-scripts --max_old_space_size=4096 build" 
        - front의 package.json 파일에서 스크립트 명령어 변경
    3. build 시 GENERATE_SOURCEMAP 옵션 꺼주기
       GENERATE_SOURCEMAP=false 
        - front의 .env 파일에서 추가, build 용량을 줄이고 노출되지 않아야 하는 코드들을 보호해주는 역할도 함
       NODE_OPTIONS="--max-old-space-size=4096" 
        - 확실하게 2번 방법도 추가
  • 위의 방법들로 우여곡절 끝에 build 성공!!!

  • 빌드에 성공했으면 할당했던 스왑 메모리를 다시 해제한다.
     sudo swapoff -v /mnt/swapfile 
     sudo rm /mnt/swapfile 
  • 진짜 이도저도 죽어도 안되면 로컬에서 빌드한 폴더를 push하고 vm에서 pull해와 배포하는 방법도 있다. 그러나 절차가 추가되기 때문에 vm에서 바로 빌드하는게 편하긴 하다...ㅎㅎ

 (3) nginx 설정 파일 변경 

  • nginx 설정파일을 편집기로 열어 root 경로는 build 폴더 경로로, server_name은 사용할 도메인으로 변경해준다.
    • 참고로 React는 SPA (Single Page Applications) 방식이기 때문에 일반적으로 웹 브라우저에서 액세스 할 수 있는 하나의 색인 파일(index.html)만 사용한다.
    • 이로 인해 사용자가 새로 고침 버튼을 누르거나 방문 페이지 이외의 페이지에 직접 액세스하면 웹 서버가 색인 파일을 무시하여 이 위치에서 파일을 찾을 때 문제가 발생하고 404 에러를 반환한다.
    • 따라서 이를 방지하려면  location / 의 경로를  /index.html 로 변경해줘야 한다.

  • 여기까지 했으면 front 부분의 배포는 끝났다! 다음 편에는 back 부분의 배포와 EC2 방화벽 설정에 대해 마저 포스팅할 것이다.