코드 작성 후 서비스가 원활하게 돌아가게 하기 위해 인프라를 구축한다. 인프라에는 클라우드와 하드웨어 인프라가 있다. 이 중에서 AWS를 사용해 '배포'를 진행해보자.
먼저, AWS를 사용하기 전에 알고 있으면 좋을 개념들을 짚고 넘어가자.
네트워크는 여러 디바이스들이 연결을 유지하는 공간이다. 라우터들이 모여서 거대한 인터넷 공간을 만들고, 라우터에는 컴퓨터들이 붙어 있다. 하나하나의 디바이스들은 Mac, IP, Port를 통해 구별된다. 전기적 신호를 사용해 빛의 속도로 통신하여 연결되지만, 대역폭이 정해져 있어 속도감이 다르게 느껴진다. 하나의 컴퓨터는 서버가 될 수도 있고 클라이언트가 될 수도 있다. 스마트폰도 하나의 라우터가 될 수 있다. 핫스팟이라는 기능으로 스마트폰 하나가 라우터가 되어 하위 디바이스에 대한 네트워크를 구성해주기 때문이다. 가까이에 있는 네트워크, 쉽게 생각하자..!
L | Layer |
---|---|
L4 | 응용 계층(Application Layer) |
L3 | 전송 계층(Transport Layer) |
L2 | 인터넷 계층(Internet Layer) |
L1 | 네트워크 엑세스(Network Access Layer) |
이렇게 레이어를 나누어 놓은면 유지 보수 측면에서 유리하다. 관심사의 분리를 통해 어떤 레이어에 문제가 있는지 살펴보고 문제를 보완하면 되기 때문이다.
[이미지 출처] https://www.avg.com/en/signal/public-vs-private-ip-address
IP를 도로명 주소라고 생각했을 때, -시 -구 -로 까지는 공인 IP, 1동 1호가 사설 IP라고 이해하자.
<ip or dnsname>:port
로 접속인프라는 IT 서비스가 배포되어 유저가 서비스에 접속할 수 있게 만드는 공간이다. 인프라를 관리하는 영역을 DevOps라고 말하며, 물리적인 장비를 의미하는 온 프레미스(On-premise, On-site라고도 함) 인프라와 물리적 장비가 필요 없는 클라우드 인프라로 나뉜다.
Amazon Web Service의 약자로, 아마존에서 운영하는 클라우드 서비스다. 저렴한 비용, 민첩성, 즉각적 탄력성, 개방성, 유연성, 보안 등의 장점이 있다.
Virtual Private Cloud의 약자로 AWS의 인프라 중에 하나의 공간을 설정할 수 있다. 거대한 AWS 인프라에서 구역을 임대하는 개념이라고 생각하면 된다.
VPC 내부에서 하나의 공간을 설정하는 부분이다. Inbound의 정책을 선택해 Public Subnet이나 Private Subnet을 결정할 수 있다.
Elastic Compute의 약자로 가상화된 컴퓨팅 자원을 할당 받을 수 있는 서비스다. scale이 조정 가능하기 때문에 CPU, RAM, OS 등 사양 및 환경에 맞춰 구성이 가능하다.
Relational Database Service의 약자로 관계형 데이터베이스를 제공해주는 서비스다. 백업, 복제, 보안 등 운영에 필요한 환경을 제공하기 때문에 인프라적인 관리가 불필요하다.
보안그룹이라고 하며 서비스들의 방화벽이 되어주는 서비스다. 어떤 IP를 허용할 것인가 하는 문제를 다룬다. Inbound와 Outbound는 보안그룹에서 설정하며 이 보안그룹은 VPC에 종속된다.
Simple Storage Service의 약자로 정적인 파일(바뀌지 않는 파일)을 관리하기 위한 서비스다. VPC에 속하지 않고 리전(국가?지역?)에 속해 VPC의 보안그룹이 적용되지 않는다. 파일 단위를 객체라고 부른다.
[이미지 출처] https://towardsdatascience.com/vpc-subnet-and-router-in-aws-cloud-17c8f421af21
Internet Gateway는 VPC 내부에서 외부로 통신가능하게 해주는 서비스다. Subnet이 Internet Gateway로 연결되어 있어 인터넷 연결이 들어올 수 있으므로 Public Subnet이 된다.
위의 개념이 이해되었다면, 인프라를 생성해보자.
VPC를 검색해 VPC 대쉬보드로 들어가고, VPC 생성버튼을 눌러준다.
VPC 생성을 누르고, 다음으로 Subnet 생성 버튼을 누른다.
서브넷을 생성하고, 인터넷 게이트웨이 생성 버튼을 누른다.
생성 버튼을 누르고 오른쪽 작업 토클 버튼을 클릭해 'VPC에 연결'을 누르고, 생성해둔 VPC로 설정하고 저장을 한다.
기존 설정은 VPC 내부에서만 통신할 수 있도록 설정이 되어 있기 때문에 외부와 통신할 수 있는 라우팅 테이블을 생성한다. 라우팅 테이블 생성 버튼을 누른다.
5-1. 라우팅 편집 버튼을 눌러 인터넷 게이트웨이를 설정해준다.
5-2. 라우팅테이블에서 서브넷 연결을 해준다. 서브넷 연결 편집을 클릭해 서브넷을 선택하고 변경사항을 저장해준다.
서브넷을 하나 더 생성한다.
라우팅 테이블에 새로 생성한 서브넷을 연결한다.
VPC로 이동해서 오른쪽 작업 버튼을 클릭하고 'DNS 호스트 이름 편짐'에 들어가 활성화에 체크하고 변경사항을 저장한다.
subnet-public-1에 rds를, subnet-public-2에 ec2를 생성해보자. 서브넷 1과 2는 IP 대역만 다를 뿐이다.
이제 RDS를 설정해보자.
deploy전에 해주어야할 두 가지가 있다.
chmod 400 <key파일이름>.pem 으로 권한 변경하고 진행해야 한다. 다운로드시 key가 너무 공개되어 있어 발생하는 문제 때문이라고 한다.
[참고링크] https://github.com/rangyu/TIL/blob/master/ubuntu/SSH-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%A0%91%EC%86%8D-%EC%8B%9C-%ED%8D%BC%EB%AF%B8%EC%85%98-%EB%AC%B8%EC%A0%9C-UNPROTECTED-PRIVATE-KEY-FILE.md
프론트엔드 fetch 코드를 수정해 merge를 하여 최신상태로 clone 받을 수 있도록 한다. 프론트엔드 src 폴더 내에 api.js파일을 만들어준다. 배포했을 때, 배포를 하지 않았을 때 endpoint를 다르게 해야 한다. 따라서 작성해주어야 할 코드는 아래와 같다.
const host = process.env.REACT_APP_API_ENDPOINT || 'localhost';
const port = 8000; //백엔드에 설정해놓은 port
const API_ENDPOINT = `http://${host}:${port}`;
export { API_ENDPOINT };
fetch 요청하는 곳의 endpoint를 모두 수정해준다.
import { API_ENDPOINT } from '../../../api';
fetch(`${API_ENDPOINT}/product/${id}/info`)
.then(res => res.json())
위의 두 가지 과정을 거쳤다면 다시 deploy를 해보자.
cd Desktop //파일이 있는 위치로 이동
ssh -i Dasinco2.pem ec2-user@복사한퍼블릭IPv4주소
sudo yum update
sudo yum install git
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
. ~/.nvm/nvm.sh
nvm install 14.18.1
//프론트 npm run build시 node-sass error
npm rebuild node-sass
git clone 프론트 주소
git clone 백엔드 주소
npm i -g pm2
cd 프론트엔드 폴더
npm i
//우리 팀의 경우 package-lock.json에 문제가 있어 삭제 후 npm i를 했다.
//rm package-lock.json => npm i
//프론트엔드 코드 수정이 된 경우
git pull merge main
vi .env
REACT_APP_API_ENDPOINT='ec2 endpoint 복붙!'
:wq
pm2 serve -h // serve option 확인
npm run build //프론트엔드 코드 빌드
pm2 serve --name 'dasinco-front' --spa ./build //배포
cd ..
cd 백엔드 폴더
npm i
vi .env //기존 .env 파일을 배포 상황에 맞게 수정
DATABASE_URL="mysql://마스터id:비밀번호@rds엔드포인트:3306/dasinco"
PORT = 8000
secret="시크릿키입력"
:wq //저장하고 나가기
//새로운 터미널 창을 열어 rds에 dasinco 데이터베이스를 만들어준다.
mysql.server start
mysql -h rds데이터베이스endpoint -u 마스터id -p
CREATE DATABASE dasinco;
//기존 터미널 창으로 돌아가서
npx prisma db push
pm2 start --name 'dasinco-back' -i max npm -- run start
//서버 정상 작동 확인하기
pm2 list
데이터베이스에 csv file Import
https://aws.amazon.com/ko/premiumsupport/knowledge-center/connect-rds-mysql-workbench/
위의 링크를 참고해 mysql workbench와 aws rds를 연결한다.
연결 => schema 우클릭 => table data import wizard 클릭 => 파일 경로 넣기(참조값이 없는 테이블 부터 넣기)
[error]
이 때 Unhandled exception: ‘ascii’ codec can’t decode byte 0xeb in position 15: ordinal not in range(128) 라는 에러가 났다. 파일 경로에 한글이 없었기 때문에 mysql workbench 버전 문제라고 판단해 삭제 후 8.0.22ver.으로 설치하니 정상적으로 csv 파일이 import 되었다.
ec2 endpoint와 port를 주소창에 입력하면 누구나 접근할 수 있게 배포되어 있는 것을 확인할 수 있다.
Free-tier로 배포를 진행했고, 보안상의 이슈를 해결하기 위해서는 다른 옵션들을 적용해야 한다.
이걸 다 정리하시다니 대단하십니다~!