프론트는 React, 백은 express 로 만든 프로젝트를 Nginx를 이용해 배포했다.
실시간 비트코인 단타 시뮬레이션 게임
인 우리 프로젝트는 실시간 통신이 생명이라 socket.io를 사용한다. 근데 슬픈 소식은 Nginx 1.1.x 버전에서는 websocket 연결을 지원하지 않는다는 점이었다. 하지만 현재 사용하고 있는 버전이 1.14.x 버전이었고, 테스트 결과 websocket 통신도 되는 것 같아서 그냥 무작정 시작했다.
처음에는 react 와 express가 로컬 환경에서 어떻게 동작하고 있는지조차 이해하지 못하고 있는 상황이었다.
리액트의 동작 방식은 다음과 같다.
create-react-app 으로 react 프로젝트 생성 시, 자체적인 서버가 함께 생성되어 개발 과정에서 별도의 서버를 만들지 않아도 바로 확인 가능하다. 그동안은 로컬에서 작업할 때, express, react 두 개를 키고 작업했었는데, 이때 우리가 사용하는 express 서버는 그저 클라이언트에 데이터를 뿌려주는 용도였던 것이다. 하지만 react를 빌드하면, react의 create-react-app 서버는 포함되지 않는다.
이럴 경우, express 서버에서 build 디렉토리 내의 React 앱을 배포하는 방식으로 작동한다.
지금까지는 실제 유저가 있는 프로젝트를 만들어본 적이 없어서 배포 단계에 대한 큰 고민을 하지 않았다. 프론트, 백이 구분된 프로젝트도 처음이라 react + express 를 합치는 것도 상당히 고된 작업이었다. 그렇다면 Nginx는 왜 쓰는걸까
"You just may be hacked when some yet-unknown buffer overflow is discovered. Not that that couldn't happen behind nginx, but somehow having a proxy in front makes me happy"
Node JS 창시자가 위와 같이 말했다. Nginx를 앞단에 둠으로써 Express가 사용하는 실제 포트를 숨기고 Nginx의 80포트를 통해 Reverse Proxying 을 함으로써 보안 이슈를 방지할수도 있고 Nginx의 우수한 기능을 활용할 수 있다.
1. AWS EC2 ubuntu 에 Nginx, Node JS 를 설치해보자
sudo su
로 진행하면 일일히 sudo 안붙여도 됨
sudo apt-get update
apt-get -y install nginx
apt-get install -y nodejs
apt-get install -y npm
npm i -g n
n lts
패키지 설치 및 Node JS 버전 업데이트
2. 자신의 코드를 폴더에 다운받고 npm i
진행
이때, pm2 나 nodemon 을 다운
netstat -tlnp
: 웹서버 잘 돌아가고 있는지 확인
3. React 빌드
React 작업 디렉토리에서 npm run build
생성된 build 폴더를 /var/www/
경로로 옮겨준다
mkdir /var/www/폴더이름
cp -r build/* /var/www/폴더이름/
4. Nginx 설정파일 수정
cd /etc/nginx/sites-available
vim default
이 default 설정파일을 수정해줘야 우리 입맛대로 사용할 수 있다.
react, express 관련 코드는 구글링하면 많이 나온다.
우리 프로젝트는 socket.io를 사용한 websocket 방식이므로 조금 달랐다.
다행히 스택 오버플로우에서 같은 문제에 대한 엄청난 답변을 찾았고, 그대로 적용했다.
server {
listen 80;
root /var/www/폴더이름
server_name _;
location ~* \.io {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy false;
proxy_pass http://localhost:5000;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
location
부분이 스택 오버플로우에서 찾은 부분이다.
우리는 express 서버를 5000포트에서 돌리기 때문에 localhost:5000
으로 설정했다.
5. PM2로 express 서버 돌리기 && Nginx 재시작
express 코드가 있는 폴더에서 pm2로 express를 켠다.
켜둔 상태에서, nginx -s reload
로 리로드해준다.
그럼 이제, ec2 public ip 로 프로젝트에 접근이 가능하다!