앱 배포하는 방법
이번에 사용해 볼 배포 방법
URL : https://aws.amazon.com/ko/
- AWS 회원가입
- 루트 사용자 로 회원가입을 하고 로그인을 한다.
- 검색창에 EC2 를 검색한다.
- 인스턴스 시작을 눌러준다.
- 애플리케이션 및 OS 이미지(Amazon Machine Image) 는 Quick Start 에서 가장 많이 사용하는
Ubuntu
를 서택한다
- 인스턴스 유형 (1년 미만 가입자이기에 프리티어 사용)
- 키 페어(로그인) 란은 새로운 키 페어 생성을 눌러준다.
- 키 페어 이름을 작성하고 유형은 기본값으로 두고 생성하면 파일이 하나 다운로드 되는데 이건 보관한다. (터미널로 접근할 때 필요함)
- 해당 IP 접근을 위해 방화벽 설정이다. 브라우저 -> 프론트엔드 80번 , 백엔드에서 4000번 , 데이터베이스 5432번 포트도 뚫어줘야하는데 조금 있다가 다시 한다. (일단 기본값으로 둔다)
- 인스턴스시작 버튼을 누른다.
- 인스턴스 메뉴에서 만든걸 확인한다. (인스턴스 상태는 실행 중)
- 체크박스 체크하고 오른쪽 상단 연결 버튼을 누른다.
보통은 SSH 클라이언트로 많이 하는데, EC2 인스턴스로 배포를 할 거기 때문에 EC2 인스턴스 연결을 눌러준다.
- 이런화면이 뜨는데 이제 여기서 필요한 모듈을 설치하고 설정한다.
URL : https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-22-04
Ubuntu
22버전에 맞는 docker
인스톨 방법
이렇게 위 URL에 설치방법이 나오는데 하나하나 복사해서 EC2에 붙여넣기 하면된다.
- sudo systemctl status docker 까지 작성하여 설치를 마치면 설치가 완료된다.
- docker설치가 다 됐는데, docker-compose up이 되지 않는다.
경고문으로 나온 sudo apt install docker-compose
를 복사하여 붙여넣는다.
- 이제 EC2에 리액트 소스코드를 올려야하는데 2가지의 방법이 있다.
1번 : FTP를 이용해서 파일 올려주기 (Filezilla)
2번 : 깃허브로 리액트 파일을 올린 후에 EC2 인스턴스에서 Clone하기
- github 방법을 사용한다. 저장소를 만들고 올려준다.
- EC2 에서
git clone 주소
를 적고 저장소 코드를 클론한다.
- 완료가 되면
ls
를 입력하면 프로젝트명이 나오고cd 프로젝트명
으로 들어가서ls
를 입력하면client
와server
가 잘 들어온걸 확인 할 수 있다.
- 이제
docker
로 실행을 해본다.sudo docker-compose up
Docker Container는 성공
환경에 따른 env 파일 생성
프론트엔드는 localhost:3000
백엔드는 localhost:4000 으로 들어갔지만 EC2에서는 퍼블릭 IPv4 DNS
로 들어간다.
그래서 로컬호스트에서 실행될 때와 AWS에서 실행될 때를 구분하여 환경에 따른 소스코드가 있어야한다.
개발환경 ->
.env.development
운영환경 ->.env.production
기존 env
는 .env.development
로 파일명을 변경하고, .env.production
에서는 EC2 인스턴스
의 퍼블릭 IPv4 DNS
를 복사한다.
example ) NEXT_PUBLIC_SERVER_BASE_URL=http ://ec2-3-106-117-251.ap-southeast-2.compute.amazonaws.com:4000
이렇게 다르게 사용이 될 때 필요한 모듈이 있다.
env-cmd
패키지를 이용해서 환경에 따라 .env
파일을 따라 정의해서 사용할 수 있다.
*sever쪽 말고 client에서
npm install env-cmd --save
설치를 해준다.
그런다음 client의 package.json
의 "scripts"
에서 변경해준다.
기존
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
변경
"scripts": {
"dev": "next dev",
👉"build:dev": "env-cmd -f .env.development next build",👈
👉"build:prod": "env-cmd -f .env.production next build",👈
👉"start:dev":"env-cmd -f .env.development next start",👈
👉"start:prod":"env-cmd -f .env.production next start",👈
"start": "next start",
"lint": "next lint"
},
npm install pm2 -g
PM2를 사용하려는 이유는 무엇인가?
Node.js
애플리케이션을 계속 유지하기 위해서.Node.js
가 다운되면 PM2
는 다운타임 없이 자동으로 다시 복구한다.Linux
, Windows
및 Mac OS
에서 작동한다.Node.js
를 Cluster
모드를 이용해서 CPU 코어 수 만큼 프로세스를 지원할 수 있게 해준다.쉽게 npm run start 를 통해서 하는거 보단 pm2의 도움을 받아서 실행을 해주는게 안정적이다.
pm2 를 위한 설정 파일 생성
client
에서 ecosystem.config.js
파일을 생성한다. module.exports = {
apps: [{
name:"community-client",
script:"npm run start:prod"
}]
}
example) 변경전
const address = "http://localhost:4000/api/subs/sub/topSubs";
example) 변경후
const address = "/subs/sub/topSubs";
example) 변경전
await axios.get("/auth/me", {headers: { cookie }});
example) 변경후
await axios.get(`${process.env.NEXT_PUBLIC_SERVER_BASE_URL}api/auth/me`, {headers: { cookie }});
URL : https://nextjs.org/docs/messages/sharp-missing-in-production
*client에서
npm install sharp --save
설치를 하지 않는다면 Error
발생..
client
> next.config.js
에서
example) 변경전
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
//gravatar 기존이미지 에러 허용
images:{
domains: ["www.gravatar.com", "localhost"]
}
}
module.exports = nextConfig
example) 변경후
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
//gravatar 기존이미지 에러 허용
images:{
domains: [
"www.gravatar.com",
"localhost",
👉"ec2-3-106-117-251.ap-southeast-2.compute.amazonaws.com"👈
]
}
}
module.exports = nextConfig
Server
부분도 동일하다.
개발환경 ->
.env.development
운영환경 ->.env.production
*server에서
npm install env-cmd --save
운영환경 -> .env.production
PORT=4000
NODE_ENV=development
APP_URL=http://ec2-3-106-117-251.ap-southeast-2.compute.amazonaws.com:4000
ORIGIN=http://ec2-3-106-117-251.ap-southeast-2.compute.amazonaws.com
JWT_SECRET=super_secret
개발환경 -> .env.development
PORT=4000
NODE_ENV=development
APP_URL=http://localhost:4000
ORIGIN=http://localhost:3000
JWT_SECRET=super_secret
Script 변경
기존
"scripts": {
"start": "ts-node src/index.ts",
"dev": "nodemon --exec ts-node ./src/server.ts",
"test": "echo \"Error: no test specified\" && exit 1",
"typeorm": "typeorm-ts-node-commonjs"
},
변경
"scripts": {
"start": "ts-node src/index.ts",
"dev": "env-cmd -f .env.development nodemon --exec ts-node ./src/server.ts",
"start:prod": "env-cmd -f .env.production ts-node ./src/server.ts",
"test": "echo \"Error: no test s ecified\" && exit 1",
"typeorm": "typeorm-ts-node-commonjs"
},
그외에 http://localhost:XXXX
로 되어있는 부분을 바꿔준다.
ex )
기존
const origin = "http://localhost:3000";
변경
const origin = process.env.ORIGIN;
EC2에서 docker를 실행하고 오래 놔두었더니 가만히 있었다. 다시 리프레쉬했고 sudo docker ps
를 입력해보았다.
ubuntu@ip-172-31-4-214:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES af0f271fd7f3 postgres:latest "docker-entrypoint.s…" 10 hours ago 👉Up 10 hours 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp postgres
Status가 Up이 되어있기 때문에 실행이 되고있었다. 이부분 확인 후 다시 진행한다.
순서 :
npm 설치
->모듈 설치
->next js build
->next js 시작
텍스트 에디터에서는 소스코드 변경이 끝났다.
이제 EC2
에서도 변경된 코드가 들어가야하므로 다시 깃허브에 push
하고 EC2
에서 pull
해준다.
ubuntu@ip-172-31-4-214:~$ ls project04_community ubuntu@ip-172-31-4-214:~$ cd project04_community ubuntu@ip-172-31-4-214:~/project04_community$
cd
경로가 초기화 되어서 다시 ls
를 쳐서 project04_community
를 확인 하고 project04_community
로 경로를 바꿔주고 git pull
을 진행한다.
EC2 클라이언트 실행
**EC2에는 새로운 컴퓨터에서 실행이 되는거고 나의 github에서 클론이 되었기 때문에 .env로 인해 node_module이 없는 상황이다 그래서 클라이언트 실행조건을 만들기 위해 모듈설치를 한다.
sudo apt install npm
client
경로로 들어가서 npm install
2번을 진행하다가 오류가 생겼다.
sh: 1: env-cmd: not found
어쩌고 저쩌고.. node 버전이 맞지 않다고 하는말 같은데
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | zsh
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash
로 했음..source ~/.bashrc
source ~/.zshrc
nvm install 16.18 (lts 버전으로 설치)
를 했다.npm install
로 설치 ! 정상적으로 된다!이어서...
cd client
경로에서 빌드 npm run build:prod
를 해준다.
AWS
> EC2
에서 보안그룹
을 설정해야하는데 EC2
안에서 왼쪽메뉴에 보안 그룹
을 선택하고 보안 그룹 생성
을 누른다.
ex) project-community-deploy
유형
: 사용자지정 TCP포트범위
: 80 , 3000(front) , 4000(back) , 5432(db) 소스
: Anywhere-ip v4 를 선택하면 (0.0.0.0/0 아무나 접근가능 보안상 좋지는 않음)npm run start:prod
URL : http://ec2-3-106-117-251.ap-southeast-2.compute.amazonaws.com:3000/ 로 들어가준다.
클라이언트는 배포가 완료
http://ec2-3-106-117-251.ap-southeast-2.compute.amazonaws.com:3000/
포트 3000번에서 실행된 것을 포트 80번을 이용해서 접속할 수 있게 해주기위해 Proxy를 사용
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000
을 입력해주고 npm run start:prod
를 하고 3000번이 지워진 주소로 들어가면 나오게 된다.
http://ec2-3-106-117-251.ap-southeast-2.compute.amazonaws.com/
설정파일은 이미 ecosystem.config.js로 만들어 주었다.
module.exports = {
apps: [{
name:"community-client",
script:"npm run start:prod"
}]
}
지금 계속 켜져있는 EC2 인스턴스는 끄게된다면 같이 다운이 된다. PM2
로 실행을 해준다.
설치가 안된다면 앞에 sudo를 붙여서 다시
실행
잘 실행이 된 모습
URL : http://ec2-3-106-117-251.ap-southeast-2.compute.amazonaws.com/ 에서 잘 되는지 다시 확인
확인 후 PM2실행은 완료
EC2에서 cd 경로를 server로 이동 한다.
server경로에서 npm install을 한다.