AWS와 Ubuntu로 nginx reverse-proxy와 pm2로 nodejs 무중단 서비스 만들기

PINOT·2020년 2월 3일
15

개발 이야기

목록 보기
1/4
post-thumbnail

이 강좌를 보면 알게 되는 것들

  • AWS 인스턴스 만들기
  • ssh로 AWS에 접속하기
  • nginx와 NodeJS 설치하기
  • nginx를 Reverse-Proxy로 변환하기

준비물

  • 오류에 굴하지 않는 강인한 정신
  • Amazon Web Service 계정
  • 리눅스에 대한 조금의 지식
  • ssh 클라이언트 (iTerm2 권장)
  • Node.js에 대한 지식 (서버를 만들 정도면 됩니다!)

왜 리버스 프록시인가?

  1. 로드 밸런싱^1을 사용하여 더 빠른 서버를 만들 수 있습니다.
  2. 쉬운 log 작성과 관리 : nginx 설정에서 access_log 같은 인수를 하나 추가하는 것만으로도 쉽게 로그를 작성할 수 있습니다.
  3. 보안 : 클라이언트에서 서버에 접속 할때, 3000와 같은 포트가 아니라, nginx의 80번 포트로 접속할 수 있어 직접적인 접근이 불가능합니다.
  4. 캐쉬 사용 : css나 js의 정적인 파일을 호스팅 할 때, 캐쉬를 사용해 더 나은 성능을 보여줄 수도 있습니다.

1. 인스턴스 만들기

AWS 계정을 사용하여 aws 콘솔에 접속해주세요.

좌측 상단에 보이는 인스턴스 시작 버튼을 눌러주시면, 이런 화면이 나타나게 됩니다.

우리는 ubuntu로 서버를 만들 것이기에, 위에서 5번째에 있는 Ubuntu Server 18.04 LTS (HVM), SSD Volume Type - ami-07ebfd5b3428b6f4d (64비트 x86) / ami-0400a1104d5b9caa1 (64비트 Arm) 옆에 있는 선택 버튼을 클릭해주도록 합시다.

선택 버튼을 누르게 된다면, 인스턴스 유형 선택으로 넘어가게 되는데, 우리는 크레딧이 없음으로, 프리티어 사용 가능이라는 뱃지가 붙은 t2.micro를 선택해주도록 합시다.

다음으로, 6. 보안 그룹 구성 이라는 버튼을 눌러주시면 아래와 같은 화면이 나타나게 됩니다.
여기서 아래 표에 맞춰 데이터를 입력해주세요.

유형프로토콜포트범위소스설명 (안 적으셔도 됩니다.)
sshTCP220.0.0.0/0ssh 접근을 위한 포트입니다.
httptcp800.0.0.0/0, ::/0http 접근을 위한 포트입니다.
httpstcp4430.0.0.0/0, ::/0https 접근을 위한 포트입니다.
사용자 지정 TCPtcp30000.0.0.0/0Node.JS 접근을 위한 임시 포트입니다.

결과적으로 아래와 같이 설정됩니다.

이제 검토 및 시작을 눌러 인스턴스 생성을 진행해주세요.

검토 및 시작 단계에서 시작 버튼을 누르면, 아래와 같이 모달창이 뜨게 됩니다.

AWS에서 로그인하기 위해서는, 비밀번호 대신 키 페어라는 프라이빗 키 파일로 인증을 대신 합니다.
키 페어 이름 탭에 원하시는 내용으로 입력을 한 후, 키 페어 다운로드 버튼을 눌러주세요.


키 페어 다운로드 버튼을 누르시게 되면, 위와 같이 (여러분들이 지정한 이름).pem 의 파일이 다운로드 되게 됩니다.

!!! 중요합니다 !!!
이 키 페어 파일이 없으면 여러분의 인스턴스에 접근이 불가능합니다!!!
반드시 신뢰할만한 저장 장치에 추가로 백업을 해주세요!!!
!!! 중요합니다 !!!

키 파일도 다운로드 받으셨다면, 콘솔로 다시 이동 될건데요,

여기서 우리가 만든 인스턴스의 상태가 pending에서 running으로 바뀌기를 기다리면서, ssh 접속을 준비해보도록 합시다.

2. ssh를 사용하여 인스턴스에 접속하기

자주 쓰시는 터미널을 실행시켜주시고, 명령어에 아래와 같이 적어주세요.

ssh -i (인증서가 위치한 경로) -l ubuntu (여러분 인스턴스의 퍼블릭 DNS)

접속을 하게 된다면, 아래와 같은 경고가 뜨게 되는데, 이 서버를 신뢰하겠냐는 내용이므로, yes를 눌러 진행해주도록 합시다.

The authenticity of host 'ec2-54-211-235-112.compute-1.amazonaws.com (64:ff9b::36d3:eb70)' can't be established.
ECDSA key fingerprint is SHA256:/(SHA-256키)
Are you sure you want to continue connecting (yes/no)?

아래와 같이 메시지가 나타나게 된다면 성공입니다.
연결이 되지 않는다면, 이 링크 에서 오류의 원인과 해결 방법을 적어두었으니, 여러분들의 터미널에 나타난 내용을 대조해 보아서 접속해주세요!

Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-1057-aws x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Mon Feb  3 14:03:49 UTC 2020

  System load:  0.0               Processes:           93
  Usage of /:   21.8% of 7.69GB   Users logged in:     0
  Memory usage: 21%               IP address for eth0: 172.31.36.42
  Swap usage:   0%


7 packages can be updated.
7 updates are security updates.

3. Ubuntu 기본 설정 & nginx / Node.JS 설치

먼저, 아래와 같은 커맨드를 입력하여 기본적인 업데이트를 해보도록 합시다.

sudo apt-get update
sudo apt-get upgrade -y

그 다음에는, ngnix를 설치해보도록 합시다.

sudo apt-get install nginx 

ngnix가 잘 설치 되었는지 확인해보도록 하겠습니다.

sudo service ngnix start

이 커맨드를 입력하게 되면, 1초가 지나고 다시 다음 커맨드를 입력할 수 있게 바뀌는데요,

다시 인스턴스 콘솔로 돌아가 ipv4 퍼블릭 ip 부분에 있는 IP를 입력해 주시면. 이런식으로 nginx 서버에 접속을 할 수 있습니다!

이제 Node.JS를 설치해보도록 하겠습니다.
CLI에 다음과 같은 명령어를 입력해주시고, 기다려주세요!

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

설치가 되었는지 확인하려면 다음과 같은 커맨드를 입력해주세요!

node -v
// v13.7.0
npm -v
// 6.13.6

그리고, 추가적으로 pm2 라는 프로세스 매니저를 설치해주어야 합니다.

sudo npm install -g pm2

Node.JS와 pm2의 설치가 완료되었다면, 거의 다 왔습니다. 이제 조금만 더 하시면 됩니다 :)

4. Node.js 서버 실행시키기

다음과 같은 커맨드를 실행하여, nodejs라는 디렉토리 (자유롭게 지어주셔도 됩니다) 를 만들어주시고, 그 폴더 안으로 이동해주세요.

cd ~/
mkdir nodejs
cd nodejs

이제 여기에 Koa.JS라는 웹서버 라이브러리를 설치해 주도록 합시다.

npm install koa

이제 index.js 라는 파일을 만들어서 아래와 같이 입력해주세요!

touch index.js
nano index.js

index.js

const Koa = require('koa');
const app = new Koa();

app.use(ctx => {
    ctx.body = 'Hello Koa';
});

app.listen(3000, () => {
    console.log('server is listening to port 3000');
});

Ctrl + S를 눌러 저장을 완료한 다음, Ctrl + X를 눌러 저장해주세요.

이제 pm2를 실행시켜 NodeJS 서버를 열어볼 차례입니다.

터미널에 아래와 같이 입력해주세요.

pm2 start index.js

그러면 이런식으로 pm2를 사용하여 nodejs 서버가 열리게 됩니다.

ip에 :3000번 포트를 추가하여 한번 접속해 볼까요?

잘 열린 것 같네요 :)

이제 모든 준비가 끝났습니다.

5. Nginx Reverse-Proxy 설정하기

다시 터미널로 돌아와, 아래와 같은 명령어를 입력해 /etc/nginx/sites-enabled 경로로 이동해주세요.

cd /etc/nginx/sites-enabled

ls 를 사용해, 파일의 구조를 보면, default라는 파일이 보일건데요, 이것을 삭제한 다음, 이것을 nano 에디터를 사용해 다시 만들고, 수정해보겠습니다.

ls
// default
sudo rm default
sudo nano default

nano 텍스트 에디터를 열어, 다음과 같은 내용을 입력해주세요.

default

server {
        listen 80;
        listen [::]:80;

        access_log /var/log/nginx/reverse-access.log;
        error_log /var/log/nginx/reverse-error.log;

        location / {
                    proxy_pass http://127.0.0.1:3000;
  }
}

Ctrl + S를 눌러 저장을 완료한 다음, Ctrl + X를 눌러 저장해주세요.

내가 작성한 코드가 정상적으로 입력 되었는지 확인 하려면, 아래 명령어를 입력해보세요.
주석과 같이 표시되게 된다면, 모든 준비는 끝난겁니다 :)

sudo nginx -t
// nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
// nginx: configuration file /etc/nginx/nginx.conf test is successful

이제 nginx를 재부팅 해주세요.

sudo service nginx restart

이제 다시 한번 ip에 접속을 해본다면...?

짜잔! 3000 번 포트가 없는데도 불구하고, Node.js에서 작업했던 파일이 보입니다!
이제 중요한 작업들은 끝났습니다!

6. 3000번 포트 다시 막기

우리가 인스턴스를 생성할 때, Node.js 가 제대로 동작하는지 확인하기 위하여 3000번 포트를 열어두었었습니다.

이제 더이상 3000번 포트를 사용하지 않으니, 보안을 위해 막아두도록 합시다!

다시 한번 AWS 콘솔에 접속하여, 좌측 네트워크 및 보안 탭에 있는 보안 그룹을 클릭해주세요.

그럼 이런 화면이 나타나게 되는데, lunch-wizard-1 을 클릭하면, 아래에 설명, 인바운드, 아웃바운드, 태그 라는 탭이 보이게 되는데, 우리는 여기서 인바운드를 선택해주세요.

위와 같이 화면이 바뀌게 되었나요?
그러면 편집 버튼을 눌러 인바운드 규칙 편집 팝업을 띄워주세요.

여기서 3000 포트 옆에 있는 X 버튼을 클릭해주시고, 저장을 하게 된다면 긴 대장정이 끝나게 됩니다!
고생하셨습니다!

피드백 / 오타 수정은 댓글이나, 이메일 (pinot.kim@kakao.com) 으로 보내주세요!

Pinot. Kim 이였습니다! 감사합니다~

추가로 읽어보면 좋은 자료


^1 : 부하 분산을 위해서 가상 IP를 통해 여러 서버에 접속하도록 하는 기능입니다.

profile
프론트엔드 개발자

6개의 댓글

comment-user-thumbnail
2020년 2월 4일

좋은글 감사합니다. 많이들 pm2 + nodejs로 무중단 서비스를 사용하는데 nginx의 reverse-proxy를 더해 엣지를 추가하다니 최고입니다 👍

1개의 답글
comment-user-thumbnail
2021년 1월 26일

고맙습니다~ 덕분에 사내 서비스용으로 잘 쓰고있어욤

답글 달기
comment-user-thumbnail
2021년 2월 14일

default파일을 수정하고 정상적으로 뒤에 3000포트 없이도 잘 작동됬었는데 보안그룹에서 3000을 없앤 이후로는 계속 gateway timeout이 뜨네요 이건 어디서 오류가 난걸까요 짐작이 가지 않습니다..

답글 달기