AWS EC2에서 React + Express 프로젝트 배포하기<삽질기> - 1
heroku라는 툴을 이용하면 배포부터 CI/CD까지 간편하게 할 수 있다고 들어서 처음엔 헤로쿠를 사용해서 배포하려고 하였다.
하지만 헤로쿠마저도 1시간 가까이 에러가 해결되지 않아서, '어차피 오래 걸릴거 제대로 배포해보자'라는 생각에 AWS EC2를 사용한 배포에 도전하였다.
현재까지 이해한 바로는,
- 클라이언트(React)와 서버(Express)를 각각 EC2 인스턴스를 생성하여 따로 배포한다.
- 서버 인스턴스에 mysql을 설치하여 서버와 mysql을 연결한다. (단, 현재 내가 작업한 mysql은 도커 환경에 올라가 있는데 이걸 어떻게 연결할 수 있는지는 찾아 봐야 한다.)
(모두 ubuntu를 사용하였다)
클라이언트(React) 배포
https://2ham-s.tistory.com/349
전체적으로 위 게시글을 참고하여 진행하였다.
- AWS EC2 인스턴스를 생성하고 보안 탭에서 포트 번호를 열어준다. (22, 80, 443, 3000 등)
- pem키를 생성해 client의 루트 경로에 저장 & gitignore에 pem 파일 추가
- 터미널에서 클라이언트 pem 키가 있는 경로로 이동 -> 인스턴스에 연결 (EC2 '연결' 탭에 있는 명령어 복붙) : 우분투 명령창이 열림
- 우분투 명령창에서 'git clone 프로젝트 경로' 입력
- 우분투에 nodejs, npm 설치
- git에서 받아온 우분투 내의 client 루트경로에서 npm install
- npm run build, npm start로 서버를 켠다
- 이후 EC2 '인스턴스에서 지정된 퍼블릭IP:열어둔 포트 번호'로 접속하면 클라이언트 서버가 배포된걸 확인할 수 있다

서버 배포가 안되어 있어서 정보가 다 나타나지 않는다.
이제 서버 배포를 시작해보자.
서버(express, mysql) 배포
ubuntu 환경에서 .env 파일을 인식하지 못하는 문제
당연한거겠지만 프로젝트 경로 상의 gitignore 파일에 .env파일을 넣어뒀기 때문에 ubuntu 상에서 gin clone을 했을때 .env파일을 불러오지 못한다.
express-session deprecated req.secret; provide secret option app.js:51:3
/home/ubuntu/superconnector-mvp-server/node_modules/passport-oauth2/lib/strategy.js:83
if (!options.clientID) { throw new TypeError('OAuth2Strategy requires a clientID option'); }
^
TypeError: OAuth2Strategy requires a clientID option
at Strategy.OAuth2Strategy (/home/ubuntu/superconnector-mvp-server/node_modules/passport-oauth2/lib/strategy.js:83:34)
at new Strategy (/home/ubuntu/superconnector-mvp-server/node_modules/passport-kakao/dist/Strategy.js:33:31
이때문에 위와 같은 에러가 발생했는데, ubuntu 터미널 상의 server 루트경로에서 vim .env 명령어를 이용해 .env 파일을 생성하고, 아래 명령어를 참고하여 직접 내용을 입력해서 해결했다.
— vim 명령어 —
i 입력모드로 전환
:q 종료한다
:q! 저장하지 않고 강제로 종료
:wq 저장하고 종료한다.
.env 문제를 해결하고 다시 node app.js로 서버를 실행하니 이제 다음과 같은 에러가 뜬다.

서버 실행까진 되었고, mysql과 연결하는 과정에서 에러가 발생했다.
도커 컨테이너의 IP가 172.17.0.1이므로 지금 IP 설정부터 뭔가 잘못된 것 같다.
.
.
.
문제 해결
회사 대표님의 소개 덕분에 정말 감사하게도 15년차 시니어 개발자분의 도움을 받게 되어 해결할 수 있었다. 다시한번 감사합니다🙏
우선 내가 애초에 잘못 생각하고 있던 부분이 있다.
난 도커 컨테이너 위에 띄워서 작업하던 기존의 DB를 직접 인스턴스에 배포하려 하고 있었는데, 그렇게 하는게 아니었다.
원래 개발용 DB와 배포용 DB는 따로 두는게 일반적이며, 기존에 개발 진행하던 DB와는 완전히 별개로 서버측 인스턴스의 ubuntu 환경에서 mysql을 설치하여 배포용 DB를 만들어서 연결하는 방식으로 진행하면 되는 것이었다.
(지금 생각해보면 매우 당연하고 기본적인 요소이지만 혼자서는 아무리 구글링을 해봐도 모르던 부분이었다.)
한 단계씩 차근차근 되짚어 보자.
mysql 설치 및 db 생성, 권한 부여

ubuntu 환경에서 위와 같이 mysql을 설치한다.
sudo mysql -u root -p을 입력하여 관리자 권한으로 mysql 서버에 접속한다. (비밀번호를 입력하라고 나오는데 관리자 권한이므로 그냥 엔터 치면 된다)
database를 하나 생성한다.
create database "DB이름";
db에 접속할 유저도 하나 생성한다.
create user '유저이름'@'localhost' identified by '비밀번호';
생성한 유저에게 권한 부여를 해준다
grant all on db이름.* to '유저이름'@'localhost';
flush privileges;
변경된 설정이 반영되게 하기 위해 mysql을 재실행 해준다.
sudo service mysql restart
외부 접속(mysql workbench)을 허용하기 위해 다음과 같이 입력한다.
$ cd /etc/mysql/mysql.conf.d
$ sudo vi mysqld.cnf
bind-address 가 127.0.0.1 로 되어 있는데 0.0.0.0 으로 수정한다.
이후 유저 하나를 추가로 생성하는데, 이 유저의 호스트는 '%'로 설정한다.
create user '유저이름2'@'%' identified by '비밀번호';
유저2에도 마찬가지로 권한 부여해주고, mysql을 종료한다.
config.js 수정
서버와의 연결을 관리하는 config.js를 수정해야 한다.
개발 환경에 따라 다른 DB에 연결되도록 설정했는데, 배포 환경(production)에서는 다음과 같이 연결되도록 설정한다.
const production = {
username: "첫번째로 생성한 유저 이름",
password: "비밀번호",
database: "DB이름",
host: "localhost",
dialect: "mysql",
port: 3306,
};
그리고 mysql workbench에서는 다음과 같이 두번째로 생성한(모든 호스트에서의 연결을 허용한) 유저네임에 서버측 EC2 인스턴스의 퍼블릭 IP를 호스트로 하여 연결한다.

이렇게 로컬호스트 유저와 퍼블릭 호스트 유저를 따로 분리해서 사용하는건 아마 보안 때문인 것 같다. (config.js가 유출될 것을 대비?)
-> 참고 : 여기서의 로컬호스트는 EC2의 IP 주소를 의미한다!
따라서 첫번째로 생성한 유저는 로컬호스트(EC2의 IP)에서만 접근 가능하도록 설정된 유저이고, 두번째로 생성한 유저는 모든 호스트(mysql workbench)에서 접근 가능하도록 설정된 유저이다!
이제 수정한 코드를 반영하기 위해 서버 코드의 터미널에서 git push 후 서버측 ubuntu에서 git pull 해주면 mysql 연결은 완료되었다.
하지만 여기에 더해 서버의 지속적 운영을 위해 pm2라는 툴을 사용하였는데, 이를 적용하는 과정은 다음 글에 게시하겠다.
+ 바뀐 크롬 설정 때문에 서로 다른 경로에서 cookie를 주고 받으려면 cookie 설정에서 sameSite: "None"을 설정해야 하지만 이 경우 secure옵션도 true로 바꿔줘야 하는데, secure를 true로 두면 https 도메인만 허용되기 때문에 도메인을 구매하고 SSL 인증서를 발급받아야 하는 이슈가 있었다.
이 역시 해결 후 다음 글에 게시하겠다.

Refereces
[AWS] AWS EC2 에 mysql 서버 만들기(with. React, express)
AWS RDS 라는 서비스를 사용하면 mysql 서버를 만들 수 있지만,돈이 많이 들기 때문에 EC2 를 이용하여 서버를 만든다.\[AWS] React project(express)를 AWS EC2에서 배포하기(with. git, putty, nginx)위 링크로 들어
velog.io
https://developerbee.tistory.com/204
[AWS EC2] EC2에 React 앱 + Node.js 서버 배포 1 - VPC, EC2 생성
AWS 각 서비스를 공부하기 이전에 한 EC2에 1. React로 만든 프론트엔드 프로젝트를 Nginx를 통해 실행하고 2. Node.js와 express를 사용한 백엔드 프로젝트를 실행하여 전체적인 하나의 웹 서비스를 배포
developerbee.tistory.com