먹수의 개발일지

[AWS] EC2에 Nginx로 React, Next.js 프로젝트 배포 본문

AWS

[AWS] EC2에 Nginx로 React, Next.js 프로젝트 배포

icandle 2023. 2. 5. 23:47

회사에서 React와 Next.js 프로젝트 배포를 맡게 되었다. 다양한 배포 방법이 있겠지만, React는 build 파일 경로를 연결하는 방식, Next.js는 pm2를 활용한 방식을 사용했다.

각 프로젝트는 추후에 다른 인스턴스에 각각 분리하여 배포했지만( 서버1: Nginx & React, 서버2 : Next.js ) 이번 포스팅에서는 하나의 서버에 Nginx + 하나의 프로젝트(React or Next.js)만 배포하는 방법을 작성하고자 한다!

목차

  1. EC2 환경 세팅 (Git, Node)
  2. React 프로젝트 빌드
  3. Next.js 프로젝트 빌드 및 무중단 배포
  4. Nginx 설치 및 배포

1. EC2 환경 세팅 (Git, Node)

인스턴스 생성

Amazon Linux 2 AMI로 인스턴스를 생성해주었다.

Git 설치

git을 설치한 후 프로젝트 받아오기

(.env 파일로 환경변수 관리해주는 경우 잊지 말로 해당 파일을 별도로 추가해주자.)

sudo yum update  #설치 전 yum 업데이트 sudo yum install git git clone [git 저장소 url]

NVM 설치

node 설치를 nvm으로 하는 이유

협업을 하거나 다양한 프로젝트를 동시에 올릴 경우 호환성 문제가 나타날 수 있는데, nvm을 통해서 프로젝트 별로 node 버전을 다르게 사용하거나 다른 버전으로 쉽게 변경하는 등 버전 관리를 쉽게 할 수 있기 때문이다.

  • nvm use 커맨드로 사용할 node 버전을 쉽게 변경해줄 수 있다.
  • 여러 버전을 설치하고, 삭제하는 등 버전관 리가 편리해진다.

nvm(node version manager) 설치 및 활성화

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash  . ~/.nvm/nvm.sh : nvm  #활성화

Node 설치

Node 설치 및 원하는 버전 선택 사용 *node version history

#[버전] 같이 입력 안할 경우 최신 버전이 설치된다. 
nvm install node[버전]

재접속시 node.js를 사용하기 위해서 항상 nvm use [버전] 를 실행 해줘야 하는 번거로움이 있어서 추후에 스크립트로 자동화할 예정이다.

nvm use v16.17.1   # 현재 사용중인 버전 확인해보기 $ nvm current

그외에 nvm 명령어이다. default 버전도 설정해줄 수 있다.

# node LTS 최신버전 설치
$ nvm install --lts  

# 설치된 node.js 목록 확인하기
$ nvm ls  

# 현재 사용중인 버전 확인하기 
$ nvm current  

# node.js 설치 경로 확인하기
$ which node  

# 필요없는 node 버전 삭제하기 
$ nvm uninstall <version>  

# node 기본값 적용하기 
$ nvm alias default 8.9.4

2. React 프로젝트 빌드

→ Next.js 프로젝트인 경우 3번으로 가서 진행하면 된다.

프로젝트 디렉토리 최상단에서 아래 명령어를 실행하여 에러 없이 잘 진행되었다면 build 디렉토리가 생성된 것을 확인할 수 있다.

npm install  #build하기 -> build 디렉토리 생성된 것을 확인할 수 있음 
npm run build

3. Next.js 프로젝트 빌드 및 무중단 배포

빌드 명령어는 위와 동일하다. 하지만 react 프로젝트와 달리 build 명령어가 실행된 후 build 디렉토리가 생성되지 않고 .next 디렉토리가 생성된다. 보이지 않는다면 ls -al로 확인해보자.

npm install  npm run build

우선 build된 파일이 잘 실행되는지 확인해보자.

 npm start

PM2를 활용한 무중단 배포

위의 npm start는 포그라운드로 실행하기 때문에 프로세스가 실행 중인 터미널에서 다른 명령어를 이용할 수 없으며, 터미널이 종료되거나 접속 세션이 끊기면 프로세스가 종료된다. 따라서 데몬 프로세스를 생성해주는 pm2와 같은 프로세스 관리자를 사용해주어야 한다.

PM2를 선택한 이유

PM2는 Node.js 애플리케이션용 프로덕션 프로세스 관리자이며, 앱을 항상 작동 상태로 유지하고, 시스템 가동 중단 없이 앱을 다시 로드할 수 있다고 한다.

pm2 설치 및 배포

#pm2 설치 
npm install pm2 -g  

#pm2로 Next.js 프로젝트 배포 
pm2 --name next-app start npm -- start

현재 가동 중인 pm2 목록 확인 (배포 전) pm2 list

배포 후 name에는 설정한 이름인 next-app이 들어가게 된다.

해당 Next.js 프로젝트는 3000포트로 돌아가도록 되어있기 때문에 해당 IP의 3000포트로 접속했더니 잘 들어가졌다. 접속하여 확인할 때 EC2의 보안 (인바운드 규칙에서 해당 포트 열어주기) 부분도 잊지 말고 해주자!

4. Nginx 설치 및 배포

웹서버 설치 전 생각해보기

  • AWS는 웹서버에 접속할 수 있는 외부 포트(ex. 80)를 열어주어야 한다. 해당 인스턴스의 보안탭에서 인바운드 규칙 편집을 통해 포트를 추가해줄 수 있다.
  • EC2 인스턴스에 탄력적 IP를 부여하는 것을 추천한다. 인스턴스 유형을 변경하는 등 재시작할 일이 발생했을 때 IP가 변경되기 때문이다. 도메인도 바로 연결할 것이라면 미리 하는 것이 편하다.

Nginx 설치 및 시작

sudo yum update  #항상 설치전 패키지 update  

#sudo yum install -y nginx       
#ec2에서는 위의 명령어 에러 발생함 amazon-linux-extras를 통해서 설치해줘야 한다. 

sudo amazon-linux-extras install nginx1  

#nginx 웹서버 시작 
sudo systemctl start nginx

인스턴스 ip로 접속했을 때 아래처럼 잘 실행된 것을 알 수 있다.

Nginx 설정

웹서버와 프론트 프로젝트를 연결해주기 위해 기존 설정 파일들을 수정해줘야 한다.

sudo vi /etc/nginx.conf

nginx.conf 파일은 include 기능이 가능하다. server 블럭 부분의 코드조각을 따로 정의해서 include 할 것이다.

  • http 블럭 내부에 있는 기본세팅 server {} 블록 행들을 모두 주석 처리 한다.
  • nginx.conf에 아래 코드를 추가하여 sites-enabled 하위의 설정 파일들을 포함하도록 한다.
include /etc/nginx/sites-enabled/*.conf;

/etc/nginx.conf

처음 Nginx 설치시 sites-enabled 디렉토리가 없으므로 직접 생성해야 한다.

일반적으로 sites-available디렉토리에 필요한 파일들을 작성한 후 이들과 연결되는 symbolic link(syslink)를

sites-enabled에 추가해준다. 아래 디렉토리를 모두 생성해주고 sites-available내에 원하는 이름으로 설정 파일을 생성해 열도록 한다.

$ sudo mkdir /etc/nginx/sites-available $ sudo mkdir /etc/nginx/sites-enabled $ sudo vi /etc/nginx/sites-available/[원하는 파일 이름].conf

Nginx 설정 파일 작성

1) React 프로젝트를 /에 연결하는 경우

지금은 HTTPS 를 고려하지 않기 때문에 HTTP에 해당하는 기본 설정만 포함한다.

location /는 해당 인스턴스 IP 주소의 80 포트를 통해 들어오는 모든 URL을 연결시켜 준다. root에는 아까 React build 디렉토리 경로를 입력한다. server_name은 구입한 도메인명을 입력해주면 된다.

front-app.conf

server {         
	listen 80;                 
	server_name siteurl.com         
    location /{                 
		root home/ec2-user/app-front/build                 
		index index.html index.htm;                 
		try_files $uri $uri/ /index.html;         
	} 
}

sites-enabled에 symlink를 생성하고, Nginx 설정 파일 테스트를 진행한다.

sudo ln -s /etc/nginx/sites-available/streetlamp.conf /etc/nginx/sites-enabled/streetlamp.conf sudo nginx -t  #nginx .conf 파일 문법 오류 검증  #nginx 시작 혹은 재시작 필요 sudo systemctl restart nginx

시행착오 하나,

sudo nginx -t 테스트 진행시 아래와 같은 에러가 나는 경우 conf 파일 편집시 마지막에 ;를 빼먹었을 수 있음.

테스트 성공

시행착오 둘,

nginx가 실행되어 있고 해당 IP에 들어갔는데 500 에러가 발생한 경우

외부에서 build까지의 경로로 접근할 때 거치는 디렉토리에 대한 실행 권한이 없어서 발생할 가능성이 높다고 한다. 아래 명령어로 외부 실행 권한을 주니까 접속이 잘 되었다.

chmod 711 /home/ec2-user

2) Next.js 프로젝트를 /에 연결하는 경우

Nginx와 Next.js가 같은 서버에 있다는 가정 하에, proxy_pass에 아래와 같이 url을 작성해주면 된다.

.conf를 수정한 후에는 nginx를 재시작 해주도록 하자.

sudo systemctl restart nginx

front-app.conf

 server {         
     listen 80;                 
     server_name siteurl.com         

    location / {                 
         proxy_pass http://localhost:3000;                 
         proxy_set_header Host $host;                 
         proxy_set_header X-Real-IP $remote_addr;                 
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;                 
         proxy_set_header X-Forwarded-Proto $scheme;                 
     } 
 }

위와 같이 작성 후 해당 도메인 혹은 ip로 접속했을 때 화면이 잘 뜨는 것을 확인할 수 있다.

마무리

하나의 도메인에 /로 하나의 프로젝트만 연결하는 것은 생각보다 금방 되었지만, React와 Next.js 프로젝트 두 개를 하나의 도메인으로 연결할 때는 시행착오를 조금 겪었다.

다음 포스팅에는 하나의 도메인에 여러 프로젝트를 sub directory로 연결하는 방법과 시행착오들을 작성해야겠다!

참고

Comments