Jeomxon's Tech Note

배포 스크립트는 어떻게 작성해야할까? 본문

우아한테크코스/프롤로그

배포 스크립트는 어떻게 작성해야할까?

저문(jeomxon) 2023. 6. 6. 17:05

배포 스크립트란 내부에 배포를 위한 동작 순서를 적어두어서

한번의 실행으로 배포의 과정을 간략하게 할 수 있게 하는 쉘 스크립트 파일이다.

 

서버가 우분투로 되어있기 때문에 리눅스 커맨드를 어느정도 사용할 수 있다면,

아주 어렵지는 않게 작성할 수 있다고 생각했다.

 

먼저 생각해야할 것은 '내가 서버에서 스프링 부트 서버를 직접 띄울 경우 어떤 순서로 진행할까?'였다.

파악됐던 순서는 다음과 같다.

1. git명령어를 통해 repository에서 띄우고자 하는 Spring Project를 pull 받아온다.
2. 현재 띄워져있는 스프링 부트 서버가 있다면 해당 프로세스를 종료시킨다.
3. pull받아온 프로젝트에 대한 jar파일을 생성하기 위해 build를 진행한다.
4. 해당 jar파일을 실행한다.

 

1. git명령어를 통해 repository에서 띄우고자 하는 Spring Project를 pull 받아온다.

1번은 간단했다.

먼저 홈 디렉토리에서 해당 프로젝트 파일로 cd를 통해 접근한다.

평소에 로컬에서 하던 것처럼 git pull 명령어를 통해서 원하는 브랜치를 선택한 후에

원하는 위치에 디렉토리를 받아왔다.

하지만 이를 위해서는 clone을 통해 프로젝트를 한번 미리 받아오는 과정은 있어야한다.

이 과정도 조건을 통해서 자동화 시킬 수 있다.

하지만 서버가 초기화되는 상황은 발생하지 않을 것이라 판단해서 해당 과정을 스크립트에 작성하지 않았다.

cd jwp-shopping-order/

git pull origin step1

 

2. 현재 띄워져있는 스프링 부트 서버가 있다면 해당 프로세스를 종료시킨다.

이 과정을 두번째에 위치하기 위해서는 여러번의 시행착오를 겪었다.

처음에는 build를 하고나서 jar파일을 실행하기 전에 띄워져있는 서버가 있다면 죽이는 방식으로 생각했다.

 

하지만 미션을 위해 주어진 우분투 인스턴스의 램은 1GB로 한정되어 있었고,

이는 자칫 뒤에 이어질 작업의 속도에 영향을 미칠 수 있다고 생각했다.

실제로 명령어를 한줄씩 실행해봤을 경우에도 서버의 반응속도가 느려진다고 느꼈다.

 

또한 램1GB에 두 개 이상의 스프링 부트 서버가 떠버리게 된다면 서버가 버티기 힘들 것이 분명했다.

따라서 새로 pull만 받아온 후에 이미 띄워진 서버가 있다면 해당 서버의 프로세스를 죽였다.

 

CURRENT_PID=$(pgrep -f jwp-shopping-order.jar)

if [ -z "$CURRENT_PID" ]; then

else
	kill -15 $CURRENT_PID
fi

쉘 스크립트에서 사용되는 if else문으로 처리를 했다.

먼저 pgrep명령어로 실행시킨 jar파일의 PID(프로세스 ID)를 변수에 저장한다.

if문의 -z옵션을 통해 해당 문자열이 비어있는지 검사합니다.

비어있지 않다면 kill을 통해 15번(정상 종료) SIGNAL을 CURRENT_PID로 보냅니다.

 

3. pull받아온 프로젝트에 대한 jar파일을 생성하기 위해 build를 진행한다.

./gradlew clean bootJar

cd ~

cp jwp-shopping-order/build/libs/jwp-shopping-order.jar ~

가장 처음 cd명령어를 통해 프로젝트 파일로 접근했으므로 현재 위치하는 디렉토리는 프로젝트 파일 내부이다.

여기서 ./gradlew clean bootJar를 통해 jar파일을 빌드해낼 수 있다.

clean이라는 것은 이전에 존재하는 jar파일을 삭제한 후에 빌드해주기 때문에

다른 오류가 발생하는 것을 미연에 방지할 수 있다.

 

이후 홈 디렉토리로 이동한다.

홈 디렉토리를 기준으로 프로젝트 파일에 있던 jar파일을 홈 디렉토리로 복사한다.

굳이 왜 홈 디렉토리로 복사를 하냐고 생각할 수도 있는데,

이후에 nohup을 사용할 때 nohup.out파일을 홈 디렉토리에서 쉽게 접근하기 위해서이다.

 

4. 해당 jar파일을 실행한다.

nohup java -jar -Duser.timezone=Asia/Seoul jwp-shopping-order.jar --spring.profiles.active=deploy &

jar파일을 실행을 하는데 여러가지 옵션과 명령어들이 따라 붙어있는 것을 알 수 있다.

 

nohup이란 no hang up의 약자로 "끊지마"라는 의미다.

즉 세션이 종료되어도 계속 실행하라는 의미를 가지고 있다.

그리고 해당 실행에 대한 출력은 기본적으로 'nohup.out'이라는 파일에 기록된다.

 

-Duser.timezone=Asia/Seoul은 서버를 띄울 때의 timezone을 지정해준다.

해당 옵션없이 서버를 띄우면 UTC+0기준으로 서버가 떠버리게 되어

프로그램 내부에서 시간을 다루게 된다면 한국시간 기준으로 9시간의 오차가 발생한다.

따라서 UTC+9의 시간대인 Asia/Seoul로 시간을 맞춰준다.

 

--spring.profiles.active=deploy은 설정파일에서 deploy를 사용하겠다는 의미이다.

로컬 개발용 설정파일과 배포용 설정파일을 분리해두었기에

배포용 설정파일을 쓴다는 의미에서 해당 옵션을 추가해주었다.

 

&는 백그라운드 작업으로 실행시킬 것을 의미한다.

CLI를 사용하게 되면 하나의 쉘에서만 계속해서 작업하게 되는데,

실행 파일을 백그라운드 명령없이 띄우게 되면 다른 작업을 할 수가 없다.

따라서 백그라운드로 실행을 시키고 로그를 확인하는 등의 다른 작업을 가능하게 한다.

 

결론

이를 과정을 통해 하나의 배포 스크립트를 완성할 수 있었다.

리눅스 명령어에 대해서 어느정도 알고 있으면 쉽게 작성할 수 있을 것이다.

또한 디렉토리 구조에 대해서도 충분히 파악하고 있는 것이 좋다.

배포 스크립트가 잘 실행되고 있는지 확인하기 위해서 중간중간 출력문을 넣어서

확인하는 방법도 좋을 것이다.

가장 중요한 것은 서버를 띄우기 위한 명령어들의 실행 순서를 아는 것이다.

따라서 수작업으로 한번정도 진행하면서 명령어들의 순서를 정리하고,

이를 스크립트 파일에 담는다면 효과적인 배포 스크립트가 완성될 것이라 생각한다.

'우아한테크코스 > 프롤로그' 카테고리의 다른 글

DAO와 Repository를 분리했던 이유  (4) 2023.06.06