AWS 배포하기

5o_hyun·2023년 8월 4일
0
post-thumbnail

[1] 원격으로아마존에있는컴터키기

1. aws로그인

2. 상단에 서울로 변경 (조금이라도 더 빨라지라고)

3. 모든 서비스보기 -> 컴퓨팅 -> EC2 -> 인스턴스시작


4. 인스턴스 설정

1) 애플리케이션 및 OS 이미지(Amazon Machine Image) : ' Ubuntu '

2) 네트워크 설정 : 'HTTP, HTTPS' 허용

*현재는 위치를 '무관'으로 했지만, 해커나 다른사람이 접속할수있기에 실배포시에는 내ip등으로 지정해주는게 좋다.

3) 키페어생성

현재 생성하고 있는 인스턴스를 원격으로 제어하기 위해서는 SSH 연결이 필요하고, 이떄 키페어가 사용된다.
키페어 생성을 누르고 이름입력후 생성버튼을 누르면 자동으로 키페어파일(.pem)이 다운로드 되어지는데, 이 다운로드 된것은 가지고있어야함 (나같은경우 플젝 루트에 넣어놨음, 원래는 깃에 절대 올리면 안됨)

4) 인스턴스 생성

5. 인스턴스 이름 front로 바꾸고, 동일하게 하나 더 만들어서 back 서버 배포할 인스턴스도 만들어준다.


6. 깃에 올려준다.

나는 프로젝트 루트에 키페어파일(.pem)을 올리고, .gitignore파일을 만들어서 깃에 업로드 되지 않도록 했다.


깃에 안올렸다면 올리는 방법이다. 나는 이미 이때까지 작업해논걸 올렸기때문에 이 밑부분은 필요없었다.
터미널에 해당 프로젝트 파일에 들어가 깃초기화를 해준다.git init
origin이라는 이름으로 원격저장소를 받아온다.git remote add origin https://github.com/5o-hyun/react-nodebird.git
그다음, 모든 파일을 올려주고git add .
커밋메시지와 함께 커밋 git commit -m "commit message"
커밋후엔 푸시 git push origin master

7. AWS와 연결

연결 -> SSH클라이언트 -> 예) 에있는 ssh -i "react-nodebird.pem" ubuntu@ec2-13-124-226-44.ap-northeast-2.compute.amazonaws.com 를 복사해서 터미널에 프로젝트 루트폴더에 있는곳에 입력하면 연결된다. (키가있는곳에서)

나는 이때 너무 공개적이여서 안된다는 오류가있어서 파란부분을 복사해서 입력했더니 해결됬다.
chmod 400 react-nodebird.pem


아마존쪽에있는 컴터를 원격으로 켰으면 초록글씨가 뜨고 이때 깃에 올렸던 코드를 연결해준다.git clone 깃헙주소

이제 연결이 다되었다.
명령어를 통해 프론트서버로 가주자.

ls 현재 있는곳에 있는 파일및폴더 ls -al 현재있는곳에 있는 파일및폴더 자세하게보기
pwd 현재있는곳
cd 파일이름 해당하는곳으로가기
cd .. 전으로 돌아가기

프론트서버 접속끝

같은 방법으로 백엔드서버도 열어주면된다.
->터미널하나더생성
->키체인이있는부분(프로젝트루트폴더)에서 ssh -i "react-nodebird.pem" ubuntu@ec2-13-125-252-33.ap-northeast-2.compute.amazonaws.com연결
->git clone 깃헙주소
->cd ... 로 백엔드플젝까지간다.

[2] Ubuntu에 node, MySQL 설치

프론트 컴터, 백엔드 컴터 둘다 node를 깔아준다.
맥과 윈도에서는 GUI로 쉽게 설치했지만, 리눅스에서는 보통 GUI를 사용하지 않으므로 콘솔을 통해 설치한다.

1. node 설치

$ sudo apt-get update
$ sudo apt-get install -y build-essential
$ sudo apt-get install -y curl
$ curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash --
$ sudo apt-get install -y nodejs

이거 다섯개를 다 터미널에 입력해주고 node -v npm -v 해서 버전이 나오면 잘 깔린것이다.

npm i로 받고,
npm run build로 빌드하고, (이때 백엔드db가없어서 오류난다. 밑에설명있음)
npm start로 실행

이때 벡엔드에서는 db도 깔아줘야한다. 왜냐면 프론트 빌드할때 db없어서 에러뜸. db가 없으므로 mysql을 깔자.
(원래는 다른서버에다 하지만 3개서버돌리기엔 프리티어라 그냥 백엔서버에깔겠음)

2. MySQL 설치

// 깔때 y/n 나오면 다 y해줬다.

1) MySQL 리포지토리 활성화

$ wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.11-1_all.deb

2) MySQL 리포지토리 설치

$ sudo dpkg -i mysql-apt-config_0.8.11-1_all.deb

3) 리포지토리 새로 고침

$ sudo apt-get update

4) MySQL 설치

$ sudo apt-get install mysql-server

5) MySQL 보안 설정

$ sudo mysql_secure_installation

6) MySQL 실행

$ sudo mysql -u root -p
비밀번호 설정을 딱히 하지 않았다면 기본비밀번호는 'root'

자. 이제 mysql을 설치했다면 npm start
(그러나 나는 백엔드 start를 넣어놓지않았어서, 백엔드에 package.json을 가서 "start" : "node app" 을 추가하고 푸시한다음, 우분투컴 백엔드폴더에서 git pull로 받고 npm start)

에러발생

ConnectionError [SequelizeConnectionError]: Access denied for user 'root'@'localhost'

해결방법 1) .env생성

내가 .env에 db비밀번호가있는데 이를 깃허브에 안올려서 우분투컴에는 db비밀번호가 없기때문에 뜨는 에러이다.
따라서 우분투컴에도 vim .env로 만들어준다. (a를 누르면 입력할수있고 다입력하면 esc 후 저장하고나가기 :wq)

해결방법 2) mysql 비밀번호를 바꿔준다.

sudo mysql -uroot -p
ALTER USER 'root'@'loaclhost' IDENTIFIED WITH mysql_native_password BY '00000000'
00000000은 아마존컴에깐 mysql비밀번호와 같아야한다. 뚫려있어도 오류가 난다.
exit;로 나와서 다시접속할떄 바꾼비번인 00000000은 치면 잘 접속된다.
나와서 백엔드폴더있는 경로에서 sudo npx sequlize db:create
npm start

드디어된다.

aws인스턴스에서 포트번호 3065는 안되기떄문에 80으로 바꿔준다.
vim app.js

다시 npm start 를 하려는데 다음과같은 에러가떴다.

Error: listen EACCES: permission denied 0.0.0.0:80
해석해보면 80번 포트에 대한 접근권한이 없다는 의미이다.
리눅스에서 1024이하의 well known port를 사용하려면 root 권한이 필요

npm start앞에 sudo를 붙여 슈퍼유저 권한으로 서버를 실행시킨다.sudo npm start
잘나온다 hello express!! 반가웡 ㅠ.ㅠ

[3] pm2 사용하기

노드는 터미널을 끄면 원격으로 접속된 컴퓨터도 같이 꺼진다. 하지만 우리가 터미널을 계속 켜놓고 살수는 없기때문에 터미널을꺼도 안꺼지는 background process 방법을 이용해보자.

  • foreground process : 터미널끄면 같이꺼짐 (node app)
  • background process : 터미널꺼도 안꺼짐

pm2 실행하기

$ npm i pm2 pm2를 설치하고,
$ vim package.json을 들어가서, start 부분을 pm2 start app.js로 바꿔준다 :wq
$ sudo npm start로 실행하고 ip로 들어가보면 실행된다.
이렇게 한번 pm2 실행에놓으면 터미널을 꺼도 해당ip:80을 들어가면 계속 켜져있는것을 확인할 수 있다.

이외에 pm2 명령어
sudo npm start : 실행 (위에서한거)
npx pm2 list : 리스트보기
npx pm2 kill : pm2 끄기
sudo npx pm2 reload all : 모든 파일 리로드

*AWS는 탄력적 IP라 ssh접근하는 코드도 계속 달라진다. 실제 운영하는 서비스는 고정IP로 해놓는다고한다.
고정IP로 해놓으면 좋지만 돈이 들기때문에, 연습용으로는 탄력적IP를 사용하고있다.


개발용과 배포용의 배포를 다르게 실행하도록 바꿔보자.

우선 다시 내 로컬의 백엔드 터미널에 접속해서 npm i pm2 cross-env helmet app 깔아주고,
app.js파일에 morgan은 개발,배포용으로 나누고,, 배포시 hpp,helmet을 써준다.

const hpp = require("hpp");
const helmet = require("helmet");


if (process.env.NODE_ENV === "production") {
  // 배포모드
  app.use(morgan("combined")); // combined를 쓰면 사용자의ip라던지 추적이 가능함 (더 자세함)
  	// 이거 두개는 보안상 넣어주자. npm i pm2 cross-env helmet app
  app.use(hpp());
  app.use(helmet({ contentSecurityPolicy: false }));
} else {
  // 개발모드
  app.use(morgan("dev"));
}

app.js파일에 origin부분에서 실서버에 배포될 url도 써주게 수정한다. (origin으로 검색)

app.use(
  cors({ origin: ["http://localhost:3000", "nodebird.com"], credentials: true })
);

package.json파일에 start를 하면 배포용으로 실행하게끔 수정해준다.

"scripts": {
    "dev": "nodemon app",
    "start": "cross-env NODE_ENV=production pm2 start app.js" // 이부분 바꿔준다. 
  },

위의 내용을 다 수정했으면 커밋푸시.
그리고 변경된 사항을 우분투 백엔드 터미널에서 $ sudo git pull로 받는다.

이때 에러가떴는데 Aborting이 나오면 $ git reset --hard로 수정했던걸 다 되돌려준후 $ sudo git pull로 받으면 받아진다.

$ vim app.js 다 받으면 아까 수정한 app.js 부분이 설정한대로 바뀌었는지 한번봐주고,
$ sudo npx pm2 list 로 pm2확인

새로 개발한걸 받아서 실행해야하기떄문에, 실행중인 pm2가 있으면 꺼주고 다시 실행해줘야한다.
$ sudo lsof -i tcp:80
포트번호를 다 입력해봤더니 나는 :80에 실행되고있는것을 확인했다.
$ sudo npx pm2 kill
pm2 실행하고 있는것을 죽이고,
$ sudo npm i
helmet, hpp등을 깔았으므로 우분투 컴터에도 똑같이 깔아준다음
$ sudo npm start

[4] 프론트서버 배포하기

나같은경우 배포전에 에러날거같은 부분은 변경해줬다.
프론트에 있는 백엔드기본주소를 변경하고 http://localhost:3065 -> http://13.124.161.161
프론트 package.json에서 start에 포트번호를 백엔드와 맞춰준다. "start": "cross-env NODE_ENV=production next start -p 80"
변경한 후엔 우분투 프론트서버에서 git pull로 받아줬다.

프론트와 백서버 둘다 pm2를 깔아준다. npm i pm2
프론트 코드가 바뀌었으므로 빌드를 다시 해주고 npm run build
프론트 start에 pm2가 없기때문에 실행은 다음과같이 해준다. sudo npx pm2 start npm -- start

프론트ip로 사이트를 열어보니 db연결이안되서 500에러가뜬다.
해결1)
이럴땐 백엔드ip로 사이트를열어 실행되는지 확인해보고, 된다면 루트계정으로 mysql table을 본다.
sudo su -> mysql -uroot -p -> db비번입력 -> use react-nodebird를 입력해 리액트노드버드프로젝트로 들어간다음 -> use react-nodebird; use 프로젝트명 ->show tables;
아 근데 테이블도 잘들어감 뭘까 ㅅㅂ

해결2)
mysql native-password로 죄다 바꿔봤다.
https://bscnote.tistory.com/77

시퀄라이즈 에러는 없어졌는데 아직도 안열린다.

해결3)
테이블을 지우고 다시 생성하자.

DROP DATABASE `react-nodebird`; // 테이블지움
exit; // 으로 우분투로 돌아가서
npx sequelize db:create // 테이블 다시 생성
sudo npx pm2 reload all // pm2 재시작
sudo su
mysql -uroot -p
use react-nodebird;
show tables; //재시작후 다시 mysql 들어가보면 테이블이 다시 나옴
profile
학생 점심 좀 차려

2개의 댓글

comment-user-thumbnail
2023년 8월 4일

유익한 자료 감사합니다.

1개의 답글