매번 deploy할 때마다 ssh ubuntu 인스턴스에 접속한 뒤 많은 명령어를 써야하는데 이 작업을 원클릭으로 만들수 없을까?
내가 원하는 것은 개발중인 프로젝트를 git에 push한 뒤, 로컬에서 deploy.bat을 실행하면 원격으로 서버를 deploy하는 것이다.
즉, ubuntu가 최신 프로젝트 코드를 git pull하고
.env파일을 로컬에서 copy해간 뒤
ubuntu가 스스로 pm2를 통해 프로젝트를 실행하는 것이다
이 많은 명령어를 하나의 집합으로 모은 뒤 원클릭으로 원격서버를 제어하는게 목표다.
deploy.bat
@echo off
echo ===== Starting Deployment... =====
@REM ssh login, execute
set KEY="C:\\Users\\Yujung\\Documents\\TubePicker\\key_pair.pem"
set HOST=ubuntu@ec_________.ap-northeast-2.compute.amazonaws.com
@REM copy .env
scp -i %KEY% ./.env %HOST%:TubePicker/Server
ssh -i %KEY% %HOST% -t "cd TubePicker; git fetch --all; git reset --hard origin/master; cd Server; bash run.sh"
echo ===== Finished Deployment =====
먼저 ssh접속하기위해 필요한 키페어와 인스턴스 dns를 KEY, HOST로 정리해줬다.
그 다음 scp 를 통해 인스턴스에게 .env 파일을 copy해줬다.
그 다음 인스턴스에서 실행될 명령어들을 ; 단위로 끊어 나열했다.
ssh 명령어를 자세히 보면
- 먼저 프로젝트로 이동한 뒤
- git fetch로 최신버전을 가져오고
- run.sh를 실행했다.
run.sh에서는 pm2로 나의 프로젝트를 실행한다.
#!/bin/bash
echo "Starting PM2 processes..."
APP_NAME="tube_picker"
SCRIPT_PATH="app.js"
# Check if the process is running
if pm2 list | grep -q "$APP_NAME"; then
echo "The process $APP_NAME is already running in PM2."
pm2 restart "$APP_NAME"
else
echo "The process $APP_NAME is not currently running in PM2."
pm2 start "$SCRIPT_PATH" --name "$APP_NAME" -- pro
fi
echo "All PM2 processes started."
- PM2를 사용해 앱을 실행한다
- 이미 앱이 실행하고 있으면 restart
- 실행되지 않았으면 start해준다 (pro는 개발, 제품환경을 구별하기 위한 커스텀 argument다)
문제
하지만 deploy.bat을 실행한 뒤 다음과 같은 오류가 떴다
같은 명령어가 ubuntu에서는 아래처럼 실행이 잘 되는데 로컬window에서는 pm2: command not found 라는 오류가 뜨는게 이상했다.
해결
찾아보니 ubuntu상 pm2의 directory를 알아야했다
pm2 를 ⇒ "/home/ubuntu/.nvm/versions/node/v17.9.1/bin/pm2”로 변경해주니 해결됐다.
(NVM을 통해 설치된 Node.js v17.9.1 버전의 PM2 실행 파일이 저장된 곳/pm2)
최종 run.sh
#!/bin/bash
echo "Starting PM2 processes..."
APP_NAME="tube_picker"
SCRIPT_PATH="app.js"
PM2="/home/ubuntu/.nvm/versions/node/v17.9.1/bin/pm2"
# Check if the process is running
if "$PM2" list | grep -q "$APP_NAME"; then
echo "The process $APP_NAME is already running in PM2."
"$PM2" restart "$APP_NAME"
else
echo "The process $APP_NAME is not currently running in PM2."
"$PM2" start "$SCRIPT_PATH" --name "$APP_NAME" -- pro
fi
echo "All PM2 processes started."