Web

[AWS] 웹 어플리케이션 배포하기 (EC2)

lheunoia 2023. 5. 3. 00:43

 

 

안녕하세요. 이번 포스트에서는 AWS 배포를 위해 EC2를 생성하는 방법과 실제 프로젝트에서 서버를 실행하고 배포하는 방법에 대해 포스팅하겠습니다. 

 

 

 

 

🐹 EC2 생성하기

 

1.  AWS 사이트 접속 후 회원가입

 

https://ap-northeast-2.console.aws.amazon.com/console/home?region=ap-northeast-2 

 

https://ap-northeast-2.console.aws.amazon.com/console/home?region=ap-northeast-2

 

ap-northeast-2.console.aws.amazon.com

 

 


2. 지역 > 아시아 태평양(서울)으로 변경

 

 


3. EC2 > 인스턴스 시작

 

 


4. 서버 선택

본 프로젝트에서는 Ubuntu 서버를 선택했습니다.

 

 


5. 인스턴스 유형 선택

'프리티어 사용 가능'이라고 쓰여 있는 인스턴스는 무료로 사용할 수 있습니다.

 

 


6. HTTP, HTTPS 허용 

 

 

네트워크 설정에서 HTTPHTTPS 트래픽을 허용합니다.

IP가 0.0.0.0 이면 모든 IP에서 접근 가능합니다. SSH(개발 환경 터미널)는 집의 IP로 변경하여 해커들이 접근하지 못하도록 방지하는 것이 좋습니다.

 

 


7. 키 페어 생성

인스턴스에 접속하기 위해 키 페어를 생성합니다.

인스턴스 키 페어는 .pem 형태로, 이 파일이 있어야 EC2 인스턴스에 접근이 가능합니다.

 

 

생성하려는 키 페어의 이름을 입력하고 다운로드합니다. 키 페어가 다운로드되었으면 [인스턴스 시작] 버튼을 클릭하여 인스턴스를 시작합니다.

 

 

⭐️ 키 페어 파일을 프로젝트에 추가하기

다운로드된 키 페어 파일을 프로젝트의 루트 경로에 추가 후 깃허브에 노출되지 않도록 .gitignore키 페어 이름.pem을 추가합니다.

 

 

 

8. 인스턴스 시작

인스턴스 상태가 실행 중인지 확인합니다.

 

 

 

 

👾 EC2 인스턴스에 프로젝트 연결하기


1. EC2 서버에 접속

연결하려는 인스턴스를 선택하고 [연결] 버튼을 클릭합니다.

 

 

 

SSH 클라이언트

 

[SSH 클라이언트] 탭을 클릭한 후 하단의 ssh로 시작하는 텍스트를 복사합니다.

 

개발 환경 플랫폼(글쓴이의 경우 VScode)으로 돌아가서 터미널에 접속합니다.

키 페어 파일이 들어있는 경로(루트 경로)에서 위에서 복사한 텍스트를 붙여넣기 하고 Enter 키를 누릅니다.

 

그러면 Are you sure you want to continue connecting (yes/no/[fingerprint])?  문장이 나오는데 이 때 yes를 입력합니다.

Enter 키를 누르면 원격의 EC2 서버에 접속할 수 있게 됩니다.

 

 


2. EC2 서버에 해당 프로젝트의 깃허브 주소 연결

EC2 서버에 정상적으로 접속되면 터미널의 경로가 로컬이 아닌 ubuntu@ 경로가 됩니다. (선택한 서버에 따라 다릅니다.)

 

git clone https://github.com/<사용자명>/<레포지토리명>

해당 인스턴스에 연결하려는 프로젝트의 깃허브 레포지토리 주소를 ubuntu@ 경로에 클론합니다.

 

 


3. EC2 서버에 의존성 패키치 설치하기

+ 깃허브 레포지토리에 변경사항이 있으면 git pull 명령어를 수행합니다. (EC2 서버에서는 깃허브의 변경사항을 알지 못하기 때문)

 

💡
root@ 경로에서는 git pull
ubuntu@ 경로에서는 sudo git pull

 

 

cd back

배포하려는 서버의 루트 폴더로 이동합니다. (백엔드 서버를 배포하려면 백엔드 루트 폴더로 이동합니다.)

 

 

node 버전 확인

node -v

현재 경로에 node가 없다면 node를 설치합니다.

 

 

ubuntu@ 경로에 node 설치하기

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

위 명령어들을 순차적으로 입력하여 ubuntu@ 경로에 node를 설치합니다.

 

 

node -v
npm -v

node가 정상적으로 설치되었는지 확인합니다.

 

 

ubuntu@ 경로에 의존성 패키지 설치하기

npm i

위 명령어를 실행하여 back 폴더의 package.json에 포함된 의존성 패키지들을 ubuntu@ 경로에 일괄적으로 설치합니다.

 

 

 

 

🎉 여기까지는 프론트 서버와 백엔드 서버 모두 동일하게 진행해 주시면 됩니다. 🎉

 

 

 

 

 

👩🏻‍💻 EC2 서버에서 프론트 서버 실행하기

 

1. 백엔드 url 수정

인스턴스의 IPv4는 주기적으로 변하기 때문에 ubuntu@ 서버에 연결할 때 필요한 주소가 고정적이지 않습니다. (탄력적 IP를 사용하면 유료로 고정적인 IP를 사용할 수 있습니다.) 프론트 서버를 배포하기 전에 개발 시 사용하던 백엔드 url ➡️ back 인스턴스의 IP로 변경해야 합니다. (백엔드 서버를 배포하기 전에도 front 인스턴스 IP를 origin url에 추가해주어야 합니다.)

 

 

2. 포트 번호 80으로 수정

"scripts": {
    "dev": "next dev -p 3060",
    "build": "ANALYZE=true NODE_ENV=production next build",
    "start": "NODE_ENV=production next start -p 80"
  },

포트번호를 3060 ➡️ 80으로 변경합니다. (80: EC2 생성 당시 네트워크 설정에서 허용한 포트 번호)

변경 사항을 깃허브에 push 합니다.

 

 

3. 프론트 원격 서버 접속

cd front

로컬 경로(C:)에서 front 인스턴스의 주소를 입력하여 프론트 원격 서버로 접속합니다. 프론트 서버를 실행해야 하기 때문에 프론트 루트 폴더 경로로 이동합니다. git pull 명령어를 입력하여 깃허브의 변경사항들을 내려 받습니다.

 

 

4. 프론트 서버 실행

npm run build
npm run start

Ubuntu 서버에서 프론트 서버를 실행합니다.

해당 인스턴스의 IPv4 주소:허용된 포트 번호를 주소창에 입력하여 프론트 서버가 정상적으로 동작하는지 확인해 보세요! 🙂

 

 

💡 CI/CD 툴이나 docker를 사용하면 여러 개의 명령어를 한번에 실행할 수 있습니다. (더 찾아보기)

 

 

 

 

👩🏻‍💻 EC2 서버에서 백엔드 서버 실행하기

 

1. mysql 설치

wget -c https://repo.mysql.com//mysql-apt-config_0.8.13-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.13-1_all.deb
sudo apt update
sudo apt-get install mysql-server

먼저 ubuntu@ 경로의 back 폴더에서 mysql을 설치합니다. (암호는 strong이 권장됩니다.)

 

2. root 경로에서 mysql 암호 설정

mysql_secure_installation

sudo su를 입력하여 root@ 경로로 전환한 뒤, 위 명령어를 입력해 줍니다. (반드시 root@ 경로에서 진행)

암호는 strong으로 설정하고 나머지 응답에는 y(yes)를 입력합니다.

 

 

mysql -uroot -p

root@ 경로에서 위 명령어를 입력하면 비밀번호를 입력하라는 문구가 뜹니다. 위에서 설정한 비밀번호를 입력하면 mysql 경로로 이동됩니다.

 

 

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '설정한 암호'

mysql 경로에서 위 명령어를 입력하여 실제 암호를 설정한 암호로 변경해 줍니다.

mysql 경로에서 빠져 나오는 명령어는 exit; 입니다.

 

 

3. 실행 전 몇 가지 설정

app.js 파일 수정

// 1.
app.use(cors({
  origin: ['http://localhost:3060', 'http://52.79.157.220'], // front IP 추가
  credentials: true
}));

// 2.
app.listen(80, () => { // 3065 -> 80(허용된 포트 번호)으로 변경
  console.log('서버 실행 중!');
}

1. app.js 파일의 cors 설정에서 origin url front 인스턴스의 IP 주소를 추가하여 cors 에러를 방지합니다.

2. 백엔드 서버의 포트 번호를 인스턴스에서 허용된 포트 번호로 변경해 줍니다. 허용된 포트 번호는 EC2를 생성할 때 네트워크 설정 탭에서 확인할 수 있습니다.

 

 

서버 실행 명령어 추가

"scripts": {
  "dev": "nodemon app", // 개발 모드
  "start": "node app" // 배포 모드
}

back/package.json 파일의 scripts에 배포 모드 실행 명령어를 추가합니다.

(변경 사항이 있으므로 변경 사항을 깃허브에 push하고 git pull 해주어야 합니다.)

 

 

.env 파일 추가

vim .env

환경 변수가 작성된 .env 파일은 깃허브에 업로드되지 않기 때문에 root@ 경로에 따로 추가해주어야 합니다. back/.env와 동일하게 입력 후 :wq를 입력하여 파일을 저장하고 나갑니다.

 

 

DB 생성

npx sequelize db:create

위 명령어를 입력하여 데이터베이스를 생성합니다. Database <DB 이름> created. 문구가 뜨면 성공적으로 생성이 된 것입니다.

 

 

4. 백엔드 서버 실행

npm start

위 명령어를 입력하여 백엔드 서버를 실행합니다. (ubuntu@ 경로에서는 80 포트를 허용하지 않기 때문에 sudo npm start)

해당 인스턴스의 IPv4 주소:허용된 포트 번호를 주소창에 입력하여 백엔드 서버가 정상적으로 동작하는지 확인해 보세요! 🙂

 

 

 

 

👥 background process 사용하기: pm2

node foreground process이기 때문에 터미널이 종료되면 원격 서버도 함께 종료됩니다. 만약 실수로 원격으로 접속해 놓은 shell을 끄면(ubuntu@ 경로에서 exit; 명령어를 입력했거나 개발 환경 창을 종료한 경우) 로컬 경로(C:)로 돌아가고 원격에 접속해 있던 shell이 종료되기 때문에 원격 서버도 함께 종료됩니다. 하루종일 원격 서버에 접속해 두긴 어렵기 때문에 background process를 사용하면 shell의 종료 여부와 관계없이 원격 서버를 계속 실행할 수 있습니다. background process를 사용하는 방법 중 하나는 pm2 라이브러리를 사용하는 것입니다.

 

 

백엔드 서버에서 pm2 사용하기

1. pm2 설치

npm i pm2

먼저 ubuntu@ 경로의 back 폴더에서 pm2를 설치합니다.

 

 

2. 서버 실행 명령어 수정

back/package.json

"scripts": {
  "dev": "nodemon app",
  "start": "pm2 start app.js" // 이렇게 수정
}

start 명령어를 위와 같이 수정합니다.

 

 

3. pm2로 서버 실행

sudo npm start // 서버 실행
sudo npx pm2 monit // 서버 모니터링

ubuntu@ 경로에서 위 명령어를 순차적으로 입력하여 pm2로 실행되는지 확인합니다.

해당 인스턴스의 IPv4 주소:허용된 포트 번호를 주소창에 입력하여 백엔드 서버가 정상적으로 동작하는지 확인해 보세요! 🙂

 

 

+ node 보안 관련 설정하기 (권장)

node의 배포 모드에서 보안을 위한 몇 가지 설정이 필요합니다.

- morgan 설정

- hpp, helmet 패키지 설치

 

 

npm i pm2 helmet hpp

로컬 경로(C:)의 back 폴더 경로에서 필요한 패키지들을 설치합니다.

 

 

back/app.js

if (process.env.NODE_ENV === 'production') {
  app.use(morgan('combined')); // 자세한 로그 확인 (ex. 접속자의 IP)
  app.use(hpp()); // 보안을 위한 패키지
  app.use(helmet()); // 보안을 위한 패키지
} else {
  app.use(morgan('dev'));
}

app.js의 코드의 일부분입니다. 위와 같이 수정합니다.

 

 

sudo git pull
sudo npm i

변경 사항들을 깃허브에 push 하고 ubuntu@ 경로에서 sudo git pull 합니다. 새로운 패키지들을 설치했기 때문에 sudo npm i 명령어로 의존성 패키지들을 설치합니다.

 

📍 Aborting error 발생 ➡️ git reset --hard

 

 

 

프론트 서버에서 pm2 사용하기

1. pm2 설치

npm i pm2

ubuntu@ 경로의 front 폴더에서 pm2를 설치합니다.

 

 

2. pm2로 서버 실행

npm run build (프론트 소스코드 변경될 때마다 실행)
npx pm2 start npm -- start

아래 명령어를 통해 pm2npm start 명령어를 실행할 수 있습니다.

 

 

 

💡 pm2 명령어 (ubuntu@ 경로에서는 명령어 앞에 sudo 붙이기)
     npx pm2 logs 로그 보기
     npx pm2 logs --error 에러 로그 보기
     npx pm2 list 실행 중인 서버 리스트 보기
     npx pm2 reload all 모든 서버 재시작

 

 

 

 

💬 도메인 연결하기

 

프론트 서버와 백엔드 서버의 인스턴스 IP 주소가 다르면 새로고침 시 로그인이 유지되지 않는 이슈가 발생하는데요. 개발자 도구의 네트워크 탭을 보면 요청 도메인과 응답 헤더의 도메인이 다릅니다. 이러한 경우에는 2가지 해결 방법이 있습니다.

 

 

1. 동일한 도메인으로 설정 (유료)

가비아와 같은 사이트에서 도메인을 구매하고 AWS에서 별도의 세팅을 통해 도메인 설정을 해줍니다.

 

 

2. 하나의 인스턴스로 관리 (무료)

두 서버를 하나의 서버에서 사용하여 쿠키가 공유되도록 합니다.

 

 

 

 

반응형