CheerUp_Cheers

스프링 부트 - (8) EC2 서버에 프로젝트 배포 본문

서적 공부/스프링부트 - [스프링부트와 AWS로 혼자 구현하는 웹서비스]

스프링 부트 - (8) EC2 서버에 프로젝트 배포

meorimori 2020. 4. 22. 00:48

8.1 EC2에 프로젝트 Clone 받기

//깃 다운과 버전 확인

sudo yum install git

git --version

 

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

  ->app 디렉토리를 만들고 그안에 step1디렉토리 생성

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

 

//이동

cd ~/app/step1

 

//본인 깃 허브 https주소 복사

Git 주소 복사

git clone https://github.com/wotjd4305/com.jojodu.book.git  

 

//프로젝트에 들어간 후, 코드 확인.

cd 프로젝트명

ll

오류없이 만들어진 모습

 

//테스트로 검증

./gradlew test

 

if)권한 없음이 뜬다면?(Permission denied)

  chmod +x gradlew 입력 후, 재시도

성공

 


8.2 배포 스크립트 만들기

- 배포 : 작성한 코드를 실제 서버에 반영하는 것.

  앞서 했던 과정을 하나하나 명령어로 실행하는 것은 불편함.

  ->쉘스크립트를 작성하여, 스크립트만 실행하면 앞의 과정이 차례대로 진행되도록 할것.

 

[1]빔을 통해 쉘스크립트 작성

vim ~/app/step1/deply.sh <- 원본은 오타 있음(step1이 git으로 되있음)

 

deply.sh 코드

소스보기

더보기
#!/bin/bash

REPOSITORY=/home/ec2-user/app/step1
PROJECT_NAME=com.jojodu.book

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/

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 &

- REPOSITORY=/home/ec2-user/app/step1

  프로젝트 디렉토리는 스크립트내에서 자주 쓰임 -> 변수(리포지토리)로 저장

  타입없이 저장했으며, 쉘에서 $ 변수명으로 사용.

- cd $REPOSITORY$PROJECTNAME/

  해당 디렉토리로 이동.

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

  build의 결과물인 jar 파일을 복사해 ajr파일을 모아둔 위치로 복사.

- CURRENT_PID=$(pgrep -f springboot-webservice)

  기존 수행 중이던 스프링 부트 애플리케이션을 종료.

  pgrep은 process id만 추출하는 명령어

  -f 옵선은 프로세스 이름으로 찾음.

- JAR_NAME=$(ls -tr $REPOSITORY/ | grep *.jar | tail -n 1)
  새로 실행할 jar파일명을 찾음.

  여러 jar파일이 생기기 때문에 tail - n으로 가장 나중의 jar파일(최신)을 변수에 저장
- nohup java -jar $REPOSITORY/$JAR_NAME 2>&1 &

  찾은 jar파일을 nohup으로 실행.

  스프링부트의 장점으로 특별히 외장톰캣 설치할 필요 없음.

  애플리케이션 실행자가 터미널을 종료해도 계속 구동되도록 nohup명령어 사용

 

[2]실행권한 추가 및 실행

chmod +x ./deploy.sh //권한
./deploy.sh //실행

 

[3]nohup.out파일 열어 로그 확인

vim nohup.out

원래는 돌아가면 안됨..

->application-oauth.properties를 제외하지 않았음.

돌아가면 안되는데.. .gitingnore문제..

 


8.3 외부 Security 파일 등록하기

application-oauth.properties는 .gitignore 대상.

-> git제외 대상, 서버에서 이 설정을 가지도록 하자.

 

[1]app디렉토리에 로컬에있는 applictation-oauth.properties그대로 복사.

vim /home/ec2-user/app/application-oauth.properties

 

[2]방금 생성한, application-oauth.properties를 쓰도록 deploy.sh파일 수정.

....

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

- Dspring.config.location

  스프링 설정 파일 위치를 지정.

  applcation properties와 OAuth 설정들을 담고 있는 application-oauth.properties위치 설정.

  classpath가 붙으면 jar안에 있는 resources 디렉토리 기준으로 경로 생성.

  applictiaon-oauth.properties는 절대경로를 사용, 외부에 파일이 있기 떄문.

 

[3] deploy.sh를 다시 실행.

./deploy.sh

 


8.4 스프링 부트 프로젝트로 RDS 접근하기

Maria DB에서 스프링부트 프로젝트 실행하기 위해 3가지 작업.

- 테이블생성 : H2에서 자동 생성해주던 테이블들을 MariaDB에선 직접 쿼리를 이용해 생성.

- 프로젝트 설정 : 자바 프로젝트가 MariaDB에 접근하려면 데이터베이스 드라이버가 필요(추가).

- EC2 설정 : EC2 서버 내부에서의 접속정보 관리(데이터 유출 방지)

 

#RDS 테이블 생성

[1] RDS에 테이블 생성.

다음 2가지 SQL쿼리를 RDS에 생성.

- 스프링 세션 테이블

  schema-mysql.sql파일에서 확인(ctrl+Shift+N)

CREATE TABLE SPRING_SESSION (
	PRIMARY_ID CHAR(36) NOT NULL,
	SESSION_ID CHAR(36) NOT NULL,
	CREATION_TIME BIGINT NOT NULL,
	LAST_ACCESS_TIME BIGINT NOT NULL,
	MAX_INACTIVE_INTERVAL INT NOT NULL,
	EXPIRY_TIME BIGINT NOT NULL,
	PRINCIPAL_NAME VARCHAR(100),
	CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;

CREATE UNIQUE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX SPRING_SESSION_IX3 ON SPRING_SESSION (PRINCIPAL_NAME);

CREATE TABLE SPRING_SESSION_ATTRIBUTES (
	SESSION_PRIMARY_ID CHAR(36) NOT NULL,
	ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
	ATTRIBUTE_BYTES BLOB NOT NULL,
	CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
	CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;

- JPA가 사용할 테이블

  테스트 코드 수행시 발생하는 로그로 생성되는 쿼리 사용.

 

create table posts (
	id bigint not null auto_increment,
	created_date datetime,
    modified_date datetime,
    author varchar(255),
    content TEXT not null,
    title varchar(500) not null,
    primary key (id)) engine=InnoDB

 

- 반영된 모습

 

[2] 프로젝트 설정

- MaraiDB 드라이버를 build.gradle에 등록.

compile("org.mariadb.jdbc:mariadb-java-client")

 

- 서버에서 구동될 환경을 하나 구성.

  src/main/resources에 application-real.properties 추가.

  이 파일은 profile=real인 환경을 구성시킴.

  실제 운영될 환경이기 떄문에 보안/로그 상 이슈될만한 설정을 모두제거, RDS환경 profile설정이 추가

spring.profiles.include=oauth,real-db
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.session.store-type=jdbc

 

[3] EC2 설정

EC2서버에 직접 설정 파일을 둡니다(앞선 파일처럼)

# application-real.db.properties 추가

 vim ~/app/application-real.db.properties

다음 내용 추가.

나의 rds주소 = freelec-springboot2-webservice-2.cef4uqblg65l.ap-northeast-2.rds.amazonaws.com

spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:mariadb://rds주소:포트명(기본은3306)/database이름
spring.datasource.username=db계정
srping.datasource.password=db계정 비밀
spring.datasource.driver-class-name=org.maraidb.jdbc.Driver​

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

  JPA로 테이블이 자동 생성되는 옵션을 None하겠다.

  실제로 운영되는 테이블에서 새로만들지 않도록 해야함.

 

# deploy.sh가 real profile을 쓸수있도록 개선.

- deploy.sh

....

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

 

- deploy.sh실행.

./deploy.sh
vi nohup.out //실행결과 확인

성공

html코드 보기.

curl localhost:8080

 

 


8.5 EC2에서 소셜 로그인하기

앞서 curl 명령어를 통한 EC2의 서비스 배포를 확인하였고, 이제는 브라우저에서 확인.

 

[1] AWS 보안 그룹 변경

EC2의 8080포트 열기.

 

[2] AWS EC2 도메인으로 접속

아래의 퍼블릭 DNS에 포트번호 8080를 붙이면 브라우저에 접근가능.

 

# 결과 출력

 

[3] 구글에 EC2 주소등록

해당서비스에 EC2의 도메인을 동록하지 않았기 때문에 아래와 같이 나옴.

 

# https://console.cloud.google.com/ 접속

-API 및 서비스 > 사용자 인증 정보 > Oauth 동의 화면

승인된 도메인에 https://없이 EC2의 퍼블릭 DNS 입력 > 저장

다음 처럼 입력

 

-사용자 인증 정보 > 서비스 이름 클릭

 

-승인된 리디렉션에 URI 등록.

URI = http://ec2-3-34-20-71.ap-northeast-2.compute.amazonaws.com:8080/login/oauth2/code/google

 

-결과

EC2서버에서 구글로그인 서비스를 이용 가능하게 됨.

완료

 

[4] 네이버에 EC2 주소등록

# 네이버 개발자 센터(https://developers.naver.com/apps/#/myapps) 접속

  내 어플리케이션 > API설정.

 

#서비스 URL과 Callback URL 2개 수정.

URL = http://ec2-3-34-20-71.ap-northeast-2.compute.amazonaws.com

- 서비스 URL

  로그인을 시도하는 서비스가 네이버에 등록된 서비스인지 판단하기 위한 항목.

  네이버에서는 하나만 사용 가능(EC2주소 등록시, 로컬에서 확인 불가)

  개발단계에서는 등록하지 않는 것을 추천.

  만약, 로컬에서 확인하기 위해서는 네이버 서비스를 하나더 생성하여 발급.

 

- Callback URL

  전체 주소를 등록함!(EC2 공개 DNS:8080/login/oauth2/code/naver).

성공