-
1월 14~16일 - 웹 사이트 만들기(10) - elastic beanstalk에 배포하기공부/웹 사이트 개발(끝) 2021. 1. 14. 19:19
그냥 오늘 뜬금없이 든 생각이... 지금은 프론트, 백 둘 다 조금씩 하고 있지만 나중에 규모가 조금이라도 있는 회사를 가면 분명 둘 중 하나에만 집중하게 될텐데 프론트,백을 둘다 하게 되는 사이드프로젝트 보다는 백엔드 쪽에 좀 더 집중한 사이드프로젝트를 진행하는 게 낫지 않을까 생각이 든다. 흠.,., 근데 백엔드에 집중된 사이드프로젝트란 뭘까...? 일단은 프로젝트 한바퀴 돌리고나서 더 생각해보자.
일단 배포 수단은 aws eb를 쓰려고 한다. 전체적인 그림을 보고싶어서 배포를 해보려는 것인데, EC2를 사용하면 난이도때문에 너무 오래 걸릴 거 같고, lightsail은 뭔가... 실제를 쓰는 곳이 별로 없을 것 같은 느낌적인 느낌
EB에 프론트엔드 배포
1. eb에 환경 생성하기
elastic beanstalk -> 새 환경 생성 -> 웹 서버 환경 선택 후 아래 스샷대로 진행
이렇게 하면 기본 샘플코드가 올라간 eb 배포를 완료할 수 있다. 이제 내가 만든 앱을 올려보자.
더보기만약 AWS 계정을 여러 개 이용하고 있다면?(회사랑, 개인 계정이라든지...)
터미널에서 아래 명령어를 통해 파일을 수정한다.
vi ~/.aws/credentials
파일이 열리면 아래와같이 파일을 설정해 준다.
[default]
aws_access_key_id = "액세스 키"
aws_secret_access_key = "시크릿 액세스키'
[유저이름]
aws_access_key_id = "액세스 키"
aws_secret_access_key = "시크릿 액세스키'
나는 회사계정이 default 값이라 yatyat라는 이름으로 유저를 추가했다.
참고로 이 유저를 추가하고, 키를 받는 것은 aws IAM에서 할 수 있다.
이렇게 설정을 끝냈으면 각종 aws관련 명령어를 사용할 때 아래와 같이 옵션을 지정하면 된다.
eb deploy user-dev --profile yatyat
// elastic beanstalk에 있는 user-dev라는 환경에 새로운 버전의 배포를 할 것이고, yatyat이라는 aws 계정 정보를 사용할 것이다라는 의미
2. eb cli 설치하기
설치는 이 링크보면 쉽게할 수 있다.
docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/eb-cli3-install.html
3. eb cli를 통해서 배포하기
아래 명령어를 배포하고자 하는 폴더의 root에서 실행한다.
eb init --profile yatyat
실행 후에는 아래 스샷을 참고하여 진행하면 된다.
(do you wish to continue with codecommit은 뭘 의미하는지 모르겠다. 다만 y를 했을 때 뭐 커밋이 안되어 있다고 계속 그래서 n을 선택했다.)
이렇게하고 끝
이었으면 좋겠지만 어림도 없지 502 에러가 발생한다.
왜 안되는지 확인해 보자.
4. cloud watch를 활용해서 로그 확인하기.
생성한 eb 환경에 들어간다 -> 구성 -> 카테고리 소프트웨어 편집 -> 인스턴스 로그를 cloud watch logs로 스트리밍 활성화 -> 보관일, 수명 주기는 알아서 하시길
다시 aws 메인으로 돌아가서 cloudWatch 클릭 -> 로그-로그 그룹 클릭 -> /aws/elasticbeanstalk/환경이름/var/log/web.stdout.log 클릭 -> 아래에 로그 기록이 뜬다.
너 타입스크립트 설치 안되어있는데? 라고 에러가 발생한다.
에러의 원인은 eb의 경우 배포를 할 때 node_moduels에 있는 것을 같이 올려주는데 나같은 경우 gitignore 때문에 해당 파일이 올라가지 않았다. 그럼 node_modeuls을 git에 올려야 한다는 말인가 싶었지만, ebignore를 사용하면 git에는 안 올라가지만 eb에는 올라갈 수 있도록 만들 수 있다고 한다. 자세한 내용은 아래 참고
그리고 이방법 뿐만 아니라 환경변수 값을 설정하면 dev 디펜던시를 알아서 설치하도록 할 수 있다고 한다. 참고로 eb를 활용해 배포할 때는 eb에서 기본적으로 npm install를 행한다고 한다.
뇌피셜을 섞자면... 빌드를 하고 node_modules과 함께 배포하는 방법과 환경변수 설정을 통해 알아서 배포가 되는 이렇게 두 가지 방법이 있는 듯 하다.
자세한 내용은 아래글 참고
그리고 이 문제 뿐만 아니라 포트넘버가 틀린 것도 있다. next.js는 기본적으로 3000번 포트를 쓰는데, eb에서는... 아래 글 참고... 하면 포트를 아무튼 8080을 쓴다고 한다. (참고로 이는 환경변수를 통해 포트번호를 변경할 수 있는듯 하다.)
docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/nodejs-platform-proxy.html
이렇게 하면 또... 에러가 발생하는데 에러 내용은 아래와 같다.
'ZIP does not support timestamps before 1980'
검색을 해보니 해결방법을 찾았다. 아래글 참고
github.com/aws/aws-cli/issues/2639
이렇게하면 진짜 배포가 끝나는가 싶었는데 또 어림없어다.
next build를 하니 에러가 발생했고(빌드한 파일을 올리기위해서), 원인을 알아보니 next.js는 뭐 글로벌로 설치된 next를 사용하는데 그렇기 떄문에 react, react-dom도 global로 설치된 놈을 찾으려고 하기 때문인거 같다 라고 생각하는 사람이 있다. 자세한 것은 아래글 참고
이제 진짜 아래 명령어를 실행하면 끝난다.
npm run build
eb deploy PlannerrpgUser-env
완료하고 나면 plannerrpg.ap-northeast-2.elasticbeanstalk.com/ 이 링크를 통해서 그 허접한 페이지에 접속할 수 있다. 하지만 api요청을 할 수 있지는 않다. api server에 요청할 때 로컬에서 사용하던 엔드포인트인 http://localhost:4000/graphql에 요청하고 있기 때문이다.
RDS에 DB 생성
(이건... 따라하지 말것... eb에 자체적으로 DB 생성하는 기능이 있다는 것을 아래에서 알게 되었음...)
RDS -> 데이베이스 생성 후 아래 항목 선택
VPC 같은 경우 개인에게 논리적으로 분리된 네트워크를 제공하는 기능이다. 원래는 선택 사항이었으나, 필수로 바뀌었으며 필수로 바뀌면서 default VPC를 제공하도록 바뀌었다고 한다. (VPN과 기능은 동일하지만 aws에서 제공을 하고 그게 클라우드에서 작용하기 때문에 VPC라고 하나본데?)
자세한 건 아래 글 참고
이렇게 하고나서 mysql 워크벤치를 활용해서 rds에 접속해보자.
hostname은 rds에 생성된 db의 엔드포인트이다. rds -> 인스턴스 -> 생성된 DB를 클릭하면 쉽게 확인할 수 있다.
port는 mysql의 경우 기본적으로 3306이라 건들 필요가 없으면 username과 비밀번호는 위에서 설정한 것과 같다.
이렇게 설정을 마치고 들어가려고 하면 될 줄 알았지만 아직 설정이 남아있다.
다시 만든 DB의 페이지를 들어가 연결 & 보안 페이지로 가보자.
그럼 VPC와 VPC 보안 그룹을 확인할 수 있는데, VPC는 가상 네트워크이고 VPC 보안 그룹은 이 VPC에 적용된 보안 설정을 의미하는듯 하다. (뭔가 맞는 거 같은데 정확한 정의를 못 찾음...)
여기서 보안 그룹에 들어가면 인바운드 규칙과 아웃바운드 규칙이라는 것이 있다.
참고로 인바운드와 아웃바운드에 대한 정의는 아래 글에서 정확히 알 수 있다.
나는 워크벤치를 통해 RDS에 있는 DB를 확인하고 싶은 것이기 때문에 인바운드 규칙을 수정해야 한다.
인바운드 규칙에 들어가보면 아래같은 규칙이 이미 있는데 소스에 vpc가 설정되어 있는데, 결국 이 규칙은 같은 vpc라면 모든 유형의 트래픽, 전체 프로토콜, 전체 포트범위로 오는 접근을 가능하게 하겠다는 말인 듯한다.
그렇기 때문에 내 개인 노트북은 저 vpc에 속하지 않으며, 접속을 하기 위해서 db를 생성할 때 퍼블릭 접근을 허용했고, 여기에 mysql 워크벤치를 사용해서 접근을 하려고 하기 때문에 아래처럼 설정을 하면 RDS DB에 접근할 수 있다.
EB에 백엔드(api server) 배포
일단 프론트엔드 배포할 때와 동일하게 샘플 코드를 통해 환경을 만든다.
(그리고... 지금 알게 되었는데 elastic beanstalk에 자체적으로? 데이터베이스를 생성하는 기능이 있다.인바운드 아웃바운드는 그래도 알 필요 있었으니 이득 ㅎㅎ..)
만든 환경의 구성에 들어가 보면 가장 아래 쪽에 데이터페이스 편집이 있다. 여기에 들어가서 mysql db를 만들어 주면 된다.
생성된 DB는 RDS에서 확인할 수 있다. 위와 동일하게 인바운드 설정을 하고 워크벤치로 접속을 확인할 수 있다.
1. eb init
위 과정과 동일하게 진행했고, package.json에 아래 스크립트를 추가했다.
"scripts": { "dev": "tsc && node ./src/app.js", "start": "tsc && node ./src/app.js" },
당연히? 한번에 될리가 없었고, 일단 cloudWatch를 사용해서 로그를 확인해 봤다.
2. 에러를 찾자
일단 포트는 8080으로 수정했다.
그리고 로그를 확인해 보니... 연결이 안 된다는 것인데, 당연히 DB 연결이 로컬 설정으로 되어있기 때문에 이 코드 부분을 수정해 줘야 한다.
요 코드 내용을 RDS 인스턴스에 맞게 수정해 준다.(이 값은 나중에 환경변수를 통해 로컬에서의 설정과 실제 배포상황에서의 설정을 다르게 할 수 있다.) database 값의 경우 해당 RDS에 create database 디비이름; 명령어를 통해 생성해 줘야 한다.
이 값을 수정하니 서버는 정상적으로 배포가 됐다.
그러나 여전히 에러가 존재했는데, 전에 JWT 토큰 관련 코드에서 미들웨어를 등록할 때 이 서버에 대한 모든 요청에 대해서 토큰을 검사했는데 이것때문에 에러가 발생한 듯하다. (split 어쩌구 저쩌구 에러가 발생했는데, 이는 요청 시 헤더에 authorization이 없기 때문에 발생하는 에러기 때문이다.)
그래서 그 미들웨어가 그래프큐엘 요청을 할 때만 토큰을 검사하도록 수정했다.
짜잔! 헬로우 월드!!!!
4. 그럼 마지막으로 프론트엔드에서 백엔드로 요청을 보내보자
아직 RDS DB에는 User 테이블이 없기 때문에 테이블을 만들어주자.
RDS에 연결된 워크벤치에서 테이블을 만들어주고....
use plannerRPG; create table User ( id char(36), email VARCHAR(255), nickName VARCHAR(255), password VARCHAR(255), createdAt DATETIME, updatedAt DATETIME, deletedAt DATETIME );
기존에 배포한 프론트 엔드 코드에서 graphql 요청하는 코드의 엔드포인트를 바꿔준다. signup 함수도 아래와 동일하게 엔드포인트를 바꿔준다.
그리고 게스트 토큰 개념을 만들지 않았기 때문에... 회원가입하는 페이지에 그냥 임시로 토큰을 쿠키에 저장하는 코드를 추가했따.
import Cookies from "universal-cookie"; render(){ . . . const cookies = new Cookies(); cookies.set( "plannerRPG", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiJhc2QiLCJ1c2VyRW1haWwiOiJhc2QiLCJpYXQiOjE2MTA3ODgwNTksImV4cCI6MTYxMTM5Mjg1OX0.R6y7CQ1dbqiN682ycDr68HhIoBwYWX92MQm5GlKotzQ", { maxAge: 1000 * 60 * 100, }, ); . . . }
backend 쪽 시퀄라이즈 init 하는 코드에서도 localhost를 엔드포인트로 바꿔줘야함..
const sequelize = new Sequelize( `mysql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}`, );
이렇게 했더니 인썸니아로 요청은 되는데, 계속 웹 사이트에서는 안 됐었다... 뭔가 보안 그룹 문제인가 싶었으나, 로그를 살펴보니 헤더에 토큰이 없다는 에러가 계속 발생했고, 알고보니 signup 함수에서 회원가입 api를 요청할 때 헤더를 안 넣어줬다 ㅠㅠ.....
함수만 수정하니 요청이 된다!!!!!!!!
진짜... ... 내 인생 역대급 성취감이다....
다음 주에 뭐할지는 또 정해봐야징
'공부 > 웹 사이트 개발(끝)' 카테고리의 다른 글
1월 18일 - 웹 사이트 만들기(12) - 백엔드 .js 파일 안 보이게 하기 (0) 2021.01.18 1월 17일 - 웹 사이트 만들기(11) - 환경변수 사용해서 로컬, 프로덕션 설정 다르게 하기/주요 값을 코드에서 관리하지 않기 (0) 2021.01.17 1월 11~12일 - 웹 사이트 만들기(9) - reactstrap, graphql 요청, jwt 토큰 (1) 2021.01.11 1월 10일 - 웹 사이트 만들기(8) - 회원가입 관련 테이블 만들기, sequelize, GraphQL 코드 모듈화 (0) 2021.01.10 1월 9일 - 웹 사이트 만들기(7) - 1월 첫째 주 결산 (0) 2021.01.10