Profile picture

[배포 가이드] 가상서버(Virtual Machine)에 node API 배포하기 - AWS Lightsail

JaehyoJJAng2023년 11월 20일

📜 Deployment Overview

image


📋 소스코드 주소


📕 AWS 인스턴스 생성

1. Lightsail 생성

'Create Instance' 클릭 image


Seoul(ap-northeast-2) 리전 선택
image


'On Only' 클릭 - Ubuntu 22.04 선택
image


인스턴스 Plan 선택
(학습용이므로 5달러 플랜 선택)
image


'Create Instance' 클릭
image


인스턴스가 기동되려면 시간이 조금 걸린다.
image


2. 가상머신에 SSH로 접속

가상머신이 'Running' 상태로 기동되었으면 아래 사진의 터미널 표시를 클릭해 웹 상에서 SSH로 VM에 접속이 가능하다.
image


하지만 나는 로컬에서 해당 VM(Ubuntu-1)로 접속할 것이다. 그러기 위해서는 아래의 정보가 필요하다.

  • VM 머신의 default .pem key 다운로드
  • VM 머신의 public IP
  • VM 머신의 User name

image


Download default key를 눌러 .pem 키를 원하는 경로에 다운로드 받자.

$ ls -lh ~/aws-pem
total 8
-rw-r--r--@ 1 jaehyolee  staff   1.6K 11 27 16:38 LightsailDefaultKey-ap-northeast-2.pem

# 이름이 너무 길어 좀 짧게 변경
$ mv ~/aws-pem/LightsailDefaultKey-ap-northeast-2.pem ~/aws-pem/ubuntu-01.pem

.pem 키의 권한을 600으로 변경

$ chmod 600 ~/aws-pem/ubuntu-01.pem

해당 pem를 가지고 VM에 SSH로 접속을 해보자.

$ ssh -i ~/aws-pem/ubuntu-01.pem <User Name@VM_Public_IP>
$ ssh -i ~/aws-pem/ubuntu-01.pem ubuntu@13.x.x.181

image
정상적으로 Lightsail 머신에 접속이 되었다.
172.26.10.221은 내부 NIC에 할당된 IP 주소이다.


3. SSH key github 등록

가상머신의 ~/.ssh 디렉토리 내부에 ssh key를 생성하자.

$ ssh-keygen -t rsa -b 4096 -C "Ubuntu-1"

id_rsa.pub 퍼블릭 ssh key를 https://github.com/settings/keys에 등록하도록 하자.
image


📕 필수 패키지 설치

이제 프로젝트 운용에 필요한 서비스들을 설치해주자.
express.git (Private) 프로젝트는 node.js + redis를 활용한 단순한 프로젝트이므로 node.js 및 redis를 설치 해야한다.


1. node.js 설치


위 깃허브에서 Node.JS 버전 별 설치 방법이 나와있다.
나의 경우 18.x 버전을 설치할 것이기 때문에 아래 단계를 따라하였다.


1. Download and import the Nodesource GPG key

sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg

2. Create deb repository

NODE_MAJOR=18
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list

💡 Optional: NODE_MAJOR can be changed depending on the version you need.

NODE_MAJOR=16
NODE_MAJOR=18
NODE_MAJOR=20
NODE_MAJOR=21


3. Run update and install

sudo apt-get update -y
sudo apt-get install -y nodejs

2. redis 설치

위 페이지의 'Install on Ubuntu/Debian' 각 단계를 하나씩 따라하면 된다.


1. install gpg, lsb-release, curl

sudo apt install lsb-release curl gpg -y

2. Add the repository

curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list

3. apt update

sudo apt-get update -y

4. install redis

sudo apt-get install redis -y

3. 설치 확인

node.js와 redis가 정상적으로 설치 되었는지 확인하자.


node.js 버전 출력

$ node --version
v18.18.2

# npm 버전 출력
$ npm --version
9.8.1

redis 데몬 확인

$ systemctl status redis-server | grep -i 'active'
     Active: active (running) since Mon 2023-11-27 08:02:12 UTC; 2min 39s ago

📕 프로젝트 clone

프로젝트 소스를 서버에 clone 받은 후 실행까지 해보자.


1. 프로젝트 clone
(Private 프로젝트를 SSH 방식으로 clone)
image

$ git clone git@github.com:JaehyoJJAng/express.git

🔺 Github에 ssh key 등록 필수.

SSH로 프로젝트를 clone 받으려면 현재 서버의 퍼블릭 SSH key(~/.ssh/id_rsa.pub)가 https://github.com/settings/keys에 등록되어 있어야 한다.


1. 프로젝트 실행

1. express/ 디렉토리로 이동하자.

$ cd express/

2. 필요한 dependency들을 모두 install

$ npm install -D

3. Typescript build

$ npm run build

4. npm start

$ nohup npm run start 1>node.log 2>&1 &
[1] 3983

5. 터미널에서 http://localhost:4000으로 요청을 보내보자.

$ curl localhost:4000
hello from express

6. 브라우저에서 http://<서버_PUBLIC_IP>:4000으로 접속해보자.
image
접속이 안된다!

접속이 되지 않는 이유?

AWS Lightsail VM의 Networking을 수정해주어야 한다. (방화벽 문제)


2. 방화벽 허용

현재 ubuntu-1 머신의 방화벽 허용 상태는 아래와 같다.
image


4000번 포트로 들어오는 트래픽에 대해서는 서버가 허용을 하고있지 않으니 당연히 외부에서 서버의 포트 4000번대로 오는 트래픽은 전부 막혀버리는 것이다. 아래와 같이 포트 4000번을 허용해주자.
image


다시 브라우저에서 http://<서버_PUBLIC_IP>:4000으로 접속해보자.
image
정상적으로 접속되었다.


💥 셸 스크립트로 한 방에!

Node.js와 redis를 설치하고 프로젝트를 Clone하고 실행하는 부분까지 모두 셸 스크립트로 작성해보도록 하자.

💡 해당 챕터에서는 깃허브 프로젝트 Clone 시 SSH가 아닌 HTTPS 방식으로 인증함.


1. deploy.sh

~/install-script/deploy.sh

#!/usr/bin/bash

#### 1. Source ~/install-script/var.sh
echo "1. Source ${HOME}/install-script/var.sh"
source /home/jaehyo/install-script/var.sh
cd "${BASE_DIR}"

#### 2. Service check
if [[ -n "${PROJECT_ID}" ]]; then
  # 프로젝트 동작 중인 경우 KILL
  echo "Project kill complete (${PROJECT_ID})"
  kill -KILL "${PROJECT_ID}"
else
  #### 최초배포
  ## Install Node.JS
  # Download and import the Nodesource GPG key
  echo "2-1. Download and import the Nodesource GPG key"
  sudo apt-get update -y
  sudo apt-get install -y ca-certificates curl gnupg

  echo "2-2. Add gpg key"
  curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg

  # Create deb Repository 
  echo "2-3. Create deb Repository .."
  echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list

  # Run Update and install
  echo "2-4. Run Update and install"
  sudo apt-get update -y
  sudo apt-get install -y nodejs
  #

  ## Install Redis
  # install gpg, lsb-release, curl
  echo "2-5. install gpg, lsb-release, curl"
  sudo apt install lsb-release curl gpg -y

  # Add the repository
  echo "2-6. Add the repository"
  curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
  echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list

  # apt update
  echo "2-7. apt update"
  sudo apt-get update -y

  # install redis
  echo "2-8. Install redis ..."
  sudo apt-get install -y redis
  #
fi
#

#### 3. Project folder delete
if [[ -d "${BASE_DIR}/${PROJECT_NAME}" ]]; then
  echo "3-1. Project folder delete! (${BASE_DIR}/${PROJECT_NAME})"
  rm -rf "${BASE_DIR}/${PROJECT_NAME}"
fi
#

#### 4. git clone
echo -e "\nGithub TOKEN을 입력하세요"
read GITHUB_TOKEN
git clone https://${GIT_USER}:${GITHUB_TOKEN}@github.com/JaehyoJJAng/express.git
sleep 5
echo "4. git clone complete [${PROJECT_NAME}.git]"
#

#### 5. Start build
echo "5-1. Building project ..."
cd "${BASE_DIR}/${PROJECT_NAME}"
npm install -D
npm run build

echo "5-2. set .env"
cp -R .env.sample .env
# 

#### 6. Create log dir
if [[ ! -d "${LOG_PATH}" ]]; then
  echo "6. Creating log directory ..."
  mkdir -p "${LOG_PATH}"
fi
#

#### 7. start node
echo "7. Starting service ..."
DATE="$(date +"%Y-%m-%d")"
nohup npm run start 1>"${LOG_PATH}/${DATE}.log" 2>&1 &
#

2. var.sh

~/install-script/var.sh

#!/usr/bin/bash

BASE_DIR='/home/jaehyo'
NODE_MAJOR=18
COMMAND='npm run start'
PROJECT_ID="$(pgrep -f "${COMMAND}")"
PROJECT_NAME="express"
GIT_USER='JaehyoJJAng'
LOG_PATH="${BASE_DIR}/node_log"

3. 스크립트 실행

deploy.sh 파일에 실행 권한 부여

$ chmod u+x ~/install-script/deploy.sh

스크립트 실행

$ cd ~/install-script
$ bash ./deploy.sh

Loading script...