본문 바로가기
스프링/스프링부트

AWS EC2, RDS를 통한 스프링 부트 프로젝트 배포 및 설정하기

by 책 읽는 개발자_테드 2021. 3. 28.
반응형

이 글은 '스프링 부트와 AWS로 혼자 구현하는 웹 서비스' 서적을 참고하여 AWS와 스프링부트 프로젝트 연동하고, 배포하는 작업을 설명 합니다. 

 

깃허브에 본인의 프로젝트를 올린 후 실습을 진행할 수 있습니다. AWS EC2 - Ubuntu, RDS - MySQL5.7.30 환경에서 진행합니다.

 

- EC2 기본 설정

- 타임존 변경

- 호스트네임 변경

- 배포 스크립트 만들기

- 실행 권한 추가

- 스프링프로젝트와 RDS 연결하기

- 데이터베이스 접속 정보 보호 (외부 Security 파일 등록) 


 

EC2 기본 설정 

Java 11 설치

 

원하는 자바 버전을 다운로드한다. 이 글에서는 자바 11버전을 사용한다.

(자바8의 경우, sudo apt-get install openjdk-8-jre-headless)

 

sudo apt-get update

sudo apt-get install openjdk-11-jre-headless

 

설치가 완료되면 인스턴스의 Java 버전을 11로 변경한다. (다음 명령어로 자바 버전이 여러 개일 때 원하는 버전을 선택할 수 있다. 현재는 자바 버전이 11 한 개만 존재한다.)

 

update-alternatives --config java

 



타임존 변경

 

EC2 서버의 기본 타임존은 UCT다. 세계 표준 시간으로 한국과 9시간 차이가 난다. 서버의 타임존을 한국 시간(KST)로 변경한다.

 

sudo rm /etc/localtime

sudo ln -s /usr/share/zoneinfo/Asia/Seoul /etc/localtime

 

date 명령어로 타임존이 KST로 변경된 것을 확인한다.

 



호스트 네임 변경

 

여러 서버를 관리 중일 때 IP만으로 어떤 서비스의 서버인지 확인하기 어렵다. 각 서버가 어느 서비스인지 표현하기 위해 HOSTNAME을 변경하자. 현재는 ip-172-31-11-99와 같은 호스트네임을 갖고 있다.

 

 

vim, vi, nano 등 어느 편집기를 사용해 호스트 네임을 변경한다.

 

sudo vim /etc/sysconfig/network

 



변경 후 서버를 재부팅 한다.

 

sudo reboot

 

재부팅이 끝나고 다시 접속하면 HOSTNAME이 변경되어있다.

 



Github을 통해 EC2에 스프링 프로젝트 Clone으로 받기

 

깃허브에서 코드를 받아올 수 있게 EC2에 깃을 설치한다.

 

sudo apt-get install git

 



git clone으로 프로젝트를 저장할 디렉토리를 생성한다.

 

mkdir ~/app && mkdir ~/app/step1

 

생성한 디렉토리로 이동한다.

 

cd ~/app/step1

 

본인의 깃허브 웹페이지에서 https 주소를 복사한다.

 

 

복사한 https 주소로 git clone을 진행한다.

 

 

 

클론된 프로젝트로 이동해 파일들이 잘 복사되었는지 확인한다.

 

cd 프로젝트명

 

 

코드들이 잘 수행되는지 테스트로 검증한다.

 

./gradlew test

 

만약 gradlew 실행권한이 없다는 메시지가 뜬다면, 다음 명령어로 실행 권한을 추가한 뒤 다시 테스트를 수행하자.

 

chmod +x ./gradlew

 

EC2에 그레이들(Gradle)을 설치하지 않고, Gradle Task를 수행할 수 있었던 이유는 프로젝트에 포함된 gradlew 파일 덕분이다. 이는 그레이들이 설치되지 않은 환경 또는 버전이 달라도 해당 프로젝트에 한해서 그레이들을 쓸 수 있도록 지원하는 Wrapper 파일이다.



배포 스크립트 만들기

 

작성한 코드를 실제 서버에 반영하는 것을 배포라 한다. 배포는 다음 과정을 모두 포괄한다.

 

1. git clone 혹은 git pull을 통해 새 버전의 프로젝트 생성

2. Gradle or Maven으로 프로젝트 테스트와 빌드

3. EC2 서버에서 해당 프로젝트 실행 및 재실행

 

이런 과정을 배포할 때마다 개발자가 하나하나 명령어를 실행하는 것을 불편하다. 그래서 이를 쉘 스크립트로 작성해 스크립트만 실행하면 앞의 과정이 차례로 진행되도록 한다.

 

쉘 스크립트는 .sh 파일 확장자를 가진 파일로, 노드 JS가 .js라는 파일을 통해 서버에서 작동하는 것처럼 쉘 스크립트를 리눅스에서 기본적으로 사용할 수 있는 스크립트 파일의 한 종류다.

 

이제 ~/app/step1/에 deploy.sh 파일을 하나 생성한다.

 

vim ~/app/step1/deploy.sh

#!/bin/bash

REPOSITORY=/home/유저이름/app/step1
PROJECT_NAME=프로젝트이름

cd $REPOSITORY/$PROJECT_NAME/

echo "> Git Pull"

git pull

echo "> 프로젝트 Build 시작"

./gradlew build

echo "> step1 디렉토리 이동"

cd $REPOSITORY

echo "> Build 파일 복사"

cp $REPOSITORY/$PROJECT_NAME/build/libs/*.jar $REPOSITORY/$PROJECT_NAME.jar

echo "> 현재 구동중인 애플리케이션 pid 확인"

CURRENT_PID=$(pgrep -f ${PROJECT_NAME}*.jar)

echo "현재 구동 중인 애플리케이션 pid: $CURRENT_PID"

if [ -z "$CURRENT_PID" ]; then
   echo "> 현재 구동 중인 애플리케이션이 없으므로 종료하지 않습니다."
else
   echo "> kill -15 $CURRENT_PID"
   kill -15 $CURRENT_PID
   sleep 5
fi

echo "> 새 애플리케이션 배포"

JAR_NAME=$(ls -tr $REPOSITORY/ | grep *.jar | tail -n 1)

echo "> JAR Name: $JAR_NAME"

nohup java -jar $REPOSITORY/$JAR_NAME 2>&1 &

 

코드설명

 

1) REPOSITORY=/home/유저이름/app/step1

프로젝트 디렉토리 주소는 스크립트 내에서 자주 사용하기 때문에 변수로 저장한다. 동일한 이유로 PROJECT_NAME = 프로젝트이름 도 변수로 저장한다. 

쉘에서는 타입 없이 선언하여 저장하고, $변수명으로 변수를 사용할 수 있다.

 

2)cd $REPOSITORY/$PROJECT_NAME/

git clone 받은 디렉토리(home/유저이름/app/step1/프로젝트이름)로 이동한다.

 

3)git pull

디렉토리 이동 후, master 브랜치의 최신 내용을 받는다.

 

4)./gradlew build

프로젝트 내부의 gradlew로 buid를 수행한다.

 

5)cp  $REPOSITORY/$PROJECT_NAME/build/libs/*.jar $REPOSITORY/

build 결과물인 jar 파일은 jar 파일을 모아둔 위치로 복사한다.

 

6)CURRENT_PID=$(pgrep -f ${PROJECT_NAME}*.jar)

기존의 수행 중이던 스프링 애플리케이션을 종료한다. pgrep은 process id만 추출하는 명령어이고, -f 옵션으로 프로세스 이름을 찾는다.

 

7)if ~ else ~ fi

현재 구동 중인 프로세스의 존재 여부를 판단해서 기능을 수행한다. process is 값을 보고 프로세스가 있으면 해당 프로세스를 종료한다.

 

8)JAR_NAME=$(s -tr $REPOSITORY/ | grep *.jar | tail -n 1)

새로 실행할 jar 파일명을 찾는다. 여러 jar 파일이 생기기 때문에 tail -n로 가장 나중에 생성된 jar 파일(최신 파일)을 변수에 저장한다.

 

9)nohup java -jar $REPOSITORY/$JAR_NAME 2>&1 &

찾은 jar 파일을 nohub으로 실행한다. 여기서 스프링 부트의 장점을 볼 수 있다. 외장 톰캣을 사용하지 않아도 jar 파일만 있으면 내장 톰캣으로 웹 애플리케이션 서버를 실행할 수 있다.

 

일반적으로 자바를 실행할 때 java -jar라는 명령어를 사용하지만, 이렇게 하면 사용자가 터미널 접속을 끊을 때 애플리케이션도 같이 종료된다. 터미널을 종료해도 애플리케이션은 계속 구동될 수 있도록 nohub 명령어를 사용한다. 

 

실행 권한 추가

 

chmod +x ./deploy.sh

 

 

다음 명령어로 스크립트를 실행하자.

 

./deploy.sh

 

다음과 같은 로그와 함께 애플리케이션이 실행된다.

 

 

이때 deploy.sh 파일과 실행한 디렉토리에 nohup.out 파일이 생성되고, 여기에는 애플리케이션에서 출력되는 모든 내용이 담겨있다.

 

 

스프링프로젝트와 RDS 연결하기

 

스프링프로젝트 build.gradle 파일에 jpa와 mysql-connector dependency를 추가한다.

 

dependencies {

 …
   compile('org.springframework.boot:spring-boot-starter-data-jpa')
   compile('mysql:mysql-connector-java')
}

스프링프로젝트의 application.properties 파일의 접속할 DB 정보와 필요한 설정을 추가한다.

 

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
spring.jpa.properties.hibernate.dialect.storage_engine=innodb
spring.sesion.store-type=jdbc
spring.jpa.hibernade.ddl=none
spring.datasource.url=jdbc:mysql://rds주소:포트명(기본 3306)/DBNAME
spring.datasource.username=db계정
spring.datasource.password=db계정 비민번호
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

 

코드설명

 

1)spring.jpa.hibernate.ddl-auto=none 

JPA로 테이블이 자동 생성되는 옵션을 None으로 지정한다. RDS에는 실제 운영으로 사용될 테이블이 저장되므로 스프링 부트에서 새로 만들지 않도록 한다. 이 옵션이 없으면 테이블이 모두 새로 생성될 수 있으므로 주의하자.

 

데이터베이스 접속 정보 보호 (외부 Security 파일 등록)

 

스프링부트와 RDS를 연결할 때 application.properties 파일에는 RDS 접속 정보가 포함되어있었다.

 

spring.datasource.url=jdbc:mysql://rds주소:포트명(기본 3306)/DBNAME
spring.datasource.username=db계정
spring.datasource.password=db계정 비민번호
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

 

 

하지만 이런 정보는 보안을 위해 노출되면 안되므로 깃헙에 파일을 올릴때는 제거해야한다. 때문에 해당 정보를 위한 설정 파일을 EC2에 직접 만들자. 

 

기존에 생성한 EC2의 app 디렉토리에 application-real-db.properties 파일을 만들어 다음 내용을 추가한다. 

 

spring.datasource.url=jdbc:mysql://rds주소:포트명(기본 3306)/DBNAME
spring.datasource.username=db계정
spring.datasource.password=db계정 비밀번호
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

 

그리고 deploy.sh가 해당 파일을 쓸 수 있도록 deploy.sh의 코드 마지막 줄을 다음과 같이 수정한다.

 

nohup java -jar \
-Dspring.config.location=classpath:/application.properties,/home/유저명/app/application-real-db.properties \
    -Dspring.profiles.active=real \
    $JAR_NAME > $REPOSITORY/nohup.out 2>&1 &

 

 

출처

스프링 부트와 AWS로 혼자 구현하는 웹 서비스

반응형

댓글