AWS 1장 - EC2 (1)
포스트
취소

AWS 1장 - EC2 (1)

AWS

EC2

  • 쉽게 생각해서 컴퓨터를 한 대 빌리고, 우리의 프로젝트를 npm run start 등으로 시작하듯 프로젝트를 열어놓는 것이다.

23.09.13 추가

기본 설치

  1. 인스턴스를 생성하였으면 연결해주고 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash 명령어를 입력하여 우리가 사용한 nvm을 저장소에 받아준다.
    1. curl -sL https://deb.nodesource.com/setup_16.x | sudo bash -E - 명령어를 입력하여 설치하는 방법도 있는데 어떠한 에러가 뜰 것이다.
    2. 현재는 권장하지 않는 방법이라 nvm으로 설치해주어야 한다.
  2. . ~/.nvm/nvm.sh명령어를 입력하여 nvm을 활성화 시킨다.
  3. nvm install --lts으로 Node.js를 설치한다.
    1. nvm install 16, nvm install 18.17 등 원하는 버전으로 설치도 가능하다.
  4. node -v, npm -v로 설치된 버전을 확인할 수 있다.
  5. 이제 본인의 레포지토리에 있는 프로젝트를 git clone을 사용하여 가져온다.
  6. 백엔드 코드와 프론트 엔드 코드를 2개의 인스턴스로 나눠 열어도 되지만 비용 + @의 단점으로 하나의 터미널을 사용하는 것이 좋다.
    1. 하나의 터미널을 사용하기 위해서 설치하는 것이 pm2이다.
    2. sudo npm install pm2 -g로 pm2를 글로벌로 설치하고, pm2 start, pm2 list, pm2 monit 등의 명령어를 이용해서 여러 개의 터미널을 백그라운드에서 사용할 수 있다.

23.09.14 추가

mongoDB build 시 발생할 수 있는

  1. node 버전을 선택하여 설치했던 건 EC2에서 npm명령어를 사용하여 프로젝트를 시작하려고 할 때 에러가 발생해서 버전을 변경하려 했다.

    • node 버전 문제 때문에 에러가 뜨는 경우가 있다고 한다.
    • Nullish Coalescing Operator로 ECMAScript 2020부터 도입된 기능으로 node 버전이 12.인 환경에서 실행했기 때문에 18.버전으로 업그레이드 한 후 실행했다.
    • 그럼에도 똑같은 에러가 발생했다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    > backend@1.0.0 start
    > sudo node src/app.js
    
    /home/ubuntu/why-chat/backend/node_modules/mongodb/lib/operations/add_user.js:16
          this.options = options ?? {};
                                  ^
    
    SyntaxError: Unexpected token '?'
    
    • module 자체를 손 대는 건 좋지 않은 방식임을 알고 있음에도 node 버전 업그레이드 조차도 해결되지 않아 코드 자체를 변경해봤다.
    1
    
    this.options = options || {};
    
    • 그럼에도 비슷한 에러가 발생했는데 이렇게 직접 모듈을 손 보다가는 끝이 없을 것 같아 좀 더 근본적인 해결 방법을 찾기로 했다.
    1
    2
    3
    4
    5
    6
    7
    8
    
    > backend@1.0.0 start
    > sudo node src/app.js
    
    /home/ubuntu/why-chat/backend/node_modules/mongodb/lib/error.js:627
          this.code = reason.error?.code;
                                     ^
    
    SyntaxError: Unexpected token '.'
    
  2. 버전 업그레이드가 실패했으니 그 다음 방법은 babel을 사용하는 것이다.
  3. 바벨은 쉽게 말해 최신 문법인 ES6로 작성된 코드를 하위버전의 코드로 변환해주는 데, 최신 브라우저에서 동작하지 않는 코드들이 동작될 수 있도록 호환성을 높여주는 것을 말한다.
  4. 모듈에 대한 문법을 이해하지 못 했기 떄문에 발생하는 문제였기 때문에 node버전을 수정했지만 실패, 바벨을 사용해본다.
  5. npm install @babel/core @babel/preset-env @babel/node --save-dev로 바벨과 필요한 플러그인들을 설치한다.
  6. .babelrc 파일을 생성하여 프리셋을 설정한다.
    1
    2
    3
    4
    
    // 프리셋을 사용하여 현재 환경에서 지원되는 자바스크립트 기능만 트렌스파일
    {
      "presets": ["@babel/preset-env"]
    }
    
  7. 그럼에도 똑같은 에러가 발생했다.

    • 바벨은 프로젝트의 소스 코드만 트랜스파일하기 때문에 외부 라이브러리인 MongoDB 코드는 변환되지 않을 수 있다고 한다.
  8. 바벨을 사용해서 모듈 별 트랜스파일을 진행할 수 있도록 오류가 발생한 mongodb/lib로 이동한다.
  9. npx babel src --out-dir lib 를 입력하여 src 경로의 코드를 lib 폴더로 트랜스파일한다.
  10. 그리고 다시 프로젝트를 시작해보았지만 에러 발생

    1
    2
    3
    4
    5
    6
    7
    
    chat/backend/node_modules/mongoose/node_modules/mongodb$ npx babel src --out-dir lib
    Need to install the following packages:
    babel@6.23.0
    Ok to proceed? (y) y
    npm WARN deprecated babel@6.23.0: In 6.x, the babel package has been deprecated in favor of babel-cli. Check https://opencollective.com/babel to support the Babel maintainers
    You have mistakenly installed the `babel` package, which is a no-op in Babel 6.
    Babels CLI commands have been moved from the babel package to the babel-cli package.
    
  11. 에러 내용을 보면 babel이 아닌 bable-cli를 사용해야 된다고 나와있다.
  12. npm uninstall -g babel을 사용해서 바벨을 삭제 후 npm install --save-dev babel-cli로 패키지를 설치한다.
  13. 위의 8-9번 과정을 다시 실행
  14. 다시 에러 발생
1
2
3
4
5
6
7
8
> backend@1.0.0 start
> npx babel-node src/app.js

node:events:492
      throw er; // Unhandled 'error' event
      ^

Error: listen EACCES: permission denied 0.0.0.0:80
  1. 80번 포트에서의 접근 권한 부족으로 발생한 에러였는데, 기본 포트인 80번이 아닌 8080이나 3000번 등으로 접근해보라는 해결책이 있었다.
  2. 왜 인지는 모르겠지만 정상적으로 실행이 됐다.
  3. 프론트 코드 또한 build와 start로 실행 완료.

23.09.15

기본 패키지 설치 EC2 확인 방법

  1. pm2가 정상적으로 실행 중인데 ip 접근이 되지 않아 새로운 인스턴스로 실험을 해보기로 했다.
  2. 우선 기본적인 세팅 방법으로 sudo apt update로 패키지의 업데이트가 가능한 목록을 업데이트 해준다.
  3. 13일 기준 세팅 방법으로 npm과 node.js 설치를 한다.
  4. npm init -y를 통해 기본적인 패키지 세팅을 완료한다.
  5. touch index.js로 기본적으로 접속해줄 파일을 생성한다.
  6. express를 설치한다.
  7. vim index.js로 서버 코드에서 사용할 express의 기본 코드를 작성한다.

    express 기본 코드

    1
    2
    3
    4
    5
    6
    7
    8
    
    const express = require("express");
    const app = express();
    
    app.get("/", function (req, res) {
      res.send("Hello World");
    });
    
    app.listen(3000);
    
  8. i를 눌러 INSERT 모드에서 코드를 붙여넣기 해주고 ESC => : => wq! 순으로 작성 후 저장 종료를 한다.
  9. cat index.js로 작성된 코드 확인.
  10. 자꾸 왜 안 들어가지나 했더니, 개방 주소에 접속 포트 번호를 작성하지 않았다.
    • xx.xxx.xxx.xxx:8080 으로 접속 가능 확인
    • 근데 왜 기본 프로젝트는 안 되지…

23.09.16

배포 시 메모리 이슈로 인한 EC2 멈춤 현상

  • 어이없는 실수를 한 김에 추가
  • 우선 pm2 list에서 자꾸 에러가 떴기에 local 환경에서 build와 start과정을 거쳐서 수정을 마쳤다.
  • 코드를 올린 후 다시 EC2에서 사용을 했는데 어처구니 없는 짓을 반복하고 있었다.
  • 퍼블릭 IP로 접근을 했을 때 Cannot /GET이라는 메시지만 나와있었는데, 서버는 정상적으로 실행되고 있었고 도저히 원인을 찾을 수 없었다.
  • express를 사용해서인가 무언가 설정을 잘못했나 이와 관련된 에러들을 몇 시간동안 찾아봤지만 해결책을 찾을 수 없었다.
  • 결론만 말하자면 서버는 정상적으로 실행되고 있는 게 맞았는데, URL이 잘못돼있었다.
  • 서버는 8080포트를 사용하고 있고 로컬에서는 프론트와 서버를 따로 들어갈 일이 없기 떄문에 기본 주소인 /에 대한 어떠한 설정도 하지 않았고, 그렇기에 어떠한 반환값도 받을 수 없었다.
    • 그래서 서버가 제대로 실행되고 있다고 생각을 못함…
  • 프론트에서 각 페이지마다 api요청을 자동적으로 해주고 있기 때문에 3000번 포트로 접근을 했어야 했는데 퍼블릭 IP 뒤에 서버 포트로 접근을 하려하니 아무런 반환값이 없을 수 밖에…
  • 어찌됐든 해결…이런 실수는 다시는 반복하지 않아야지…그리고 환경변수로 개발환경과 배포환경에서의 api주소만 바꿔주면 되겠다.

  • 프리티어로 설정 시 메모리가 부족하여 npm run build시 인스턴스가 뻗는 경우가 자주 발생한다고 한다.
1
2
3
sudo dd if=/dev/zero of=/mnt/swapfile bs=1M count=2048
sudo mkswap /mnt/swapfile
sudo swapon /mnt/swapfile
  • 위 명령어들을 사용하여 메모리의 부족한 부분을 디스크의 일부를 사용하여 대신 사용할 수 있게 해주는 기능이다.
  • 메모리에 비해 디스크 속도가 느리기 때문에 스왑 사용 시 속도가 느려진다는 단점이 있다.
  • 가상 메모리를 사용하면 퍼포먼스의 문제가 발생하기 떄문에 임시 방편으로 사용하는 것이 좋다.
  • 아래는 스왑 메모리 해제 명령어이다.
1
2
sudo swapoff -v /mnt/swapfile
sudo rm /mnt/swapfile

23.09.17

이미 실행 중인 포트 종료

  • 프로젝트 실행 시 분명 터미널을 종료했는데도 포트가 실행 중인 에러가 발생할 때가 있다.
  • 이 때 포트 번호를 바꿔 사용하거나 이미 실행 중인 포트를 죽이는 방법이 있다.
  • 아래와 같이 실행 중인 포트 번호를 입력하여 포트의 ID를 알아내고, 포트 ID를 kill 명령어를 사용하여 종료시킬 수 있다.
1
2
3
4
5
6
7
lsof -i :포트번호

lsof -i :8000
COMMAND  PID     USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
node    1234 shaking   15u  IPv4 0x1f23462a48d69d65      0t0  TCP localhost:cslistener (LISTEN)

kill -9 1234

배포 시 에러

  • EC2로 배포할 시 자꾸 한 사람이 사이트에 접속하면 다음 사람이 접속을 시도했을 때 막히는 문제가 발생했다.
  • 간혹 Next.js는 SSR 방식이기 때문에 사용자가 접속 했을 때 html, js 등 다시 사용자에게 보내줘야 하기 떄문에 서버 부하가 올 수 있다고 한다.
  • 하지만 트래픽을 많이 잡아먹는 것도 아니었는데 근본적인 원인이 해결이 안 됐다.
  • 하여 Vercel로 배포해보기로 했고, frontend에 관한 디렉토리를 선택하여 배포를 시도했다.
  • build 시 에러가 뜨지 않았으며, 언어 선택과 루트 폴더를 정확하게 설정을 했는데도 404 not found라는 에러가 발생했다.
  • 콘솔이나 network부분에 어떠한 에러 메시지도 주지 않았다.
  • 해외 커뮤니티에 나와있는 질의들도 많았는데 이렇다 할 해결방법이 없이 계속 시도만 하다가 흐지부지된 것처럼 보였다.
  • nelify로도 시도해보았으나 같은 에러가 발생…마지막으로 frontend에 관한 파일들을 새로운 레포지토리에 옮겨주었고 성공…
  • 어떠한 코드 변경도 없이 파일만 옮겨서 배포를 한 것뿐인데 이상없이 동작했다.
  • 이를 보면 루트 폴더 설정을 잘못했기에 발생한 에러가 아닐까 추측만 될 뿐 확신은 못 하겠다.

23.09.18

  • 인스턴스의 IP는 계속 변하는 동적 IP 성격을 지녔기 떄문에 이를 고정시켜줘야 한다.
  • EC2 => 네트워크 및 보안 => 탄력적 IP에서 탄력적 IP 생성 후 이를 연결할 인스턴스를 선택한다.
  • 그럼 탄력적 IP가 생성되는데, 이를 선택 후 우측 상단의 작업에서 탄력적 IP 연결을 선택하여 사용하고자 하는 인스턴스를 선택 후, 인스턴스의 퍼블릭 IP를 입력해준다.
  • 마찬가지로 탄력적 IP를 삭제하고 싶으면 작업에서 릴리스를 선택하면 삭제된다.
  • 탄력적 IP는 연결된 인스턴스 없이 유지할 경우 비용이 발생하는데, 인스턴스를 연결하면 비용이 발생하지 않으니 유의하자.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

React 52장 - Eslint 오류

AWS 2장 - EC2 https 연결 (ACM, Route 53, Load Balance) (2)