Group Study (2024-2025)/Spring 입문

[Spring 입문] 6주차 - EC2 서버에 프로젝트를 배포해 보자

daram_di 2024. 11. 10. 18:56

Chapter 8. EC2 서버에 프로젝트를 배포해 보자

1~5장: 스프링부트를 이용한 서비스 코드 개발
6~7장: 배포 환경 구성
8장: 위 실습을 바탕으로 실제 서비스를 배포


8.1 EC2에 프로젝트 Clone 받기

  • EC2에 git 설치
    sudo yum install git
    git --version
  • 프로젝트 저장할 디렉터리 생성
    mkdir ~/app && mkdir ~/app/step1
    cd ~/app/step1


※ 깃허브 폴더명이 한글일 경우

[방법 1] 폴더명 영어로 바꾼 후 clone하기

[방법 2] 인스턴스 인코딩 변경하기

  1. locale 확인
    locale
     
  2. 한글로 변경하기
    sudo vi /etc/locale.conf
    vim locale.conf
    
    LANG=ko_KR.UTF-8
    LC_ALL=ko_KR.UTF-8

  • git clone
    git clone 복사한 주소


  • clone 된 프로젝트 내 파일 존재 확인하기 
  • 코드 수행 여부 테스트로 검증
  1. gradlew 실행 권한 부여하기
    chmod +x ./gradlew


  2. 테스트 수행
    ./gradlew test


  • .jar 파일
    • build 파일 내부에 생성
    • Java 애플리케이션의 패키징된 실행 파일
    • 코드, 라이브러리, 리소스 등을 하나의 압축된 파일로 묶어 배포 

8.2  배포 스크립트 만들기

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

배포 과정
1. git clone, pull을 통해 새 버전의 프로젝트를 받는다.
2. Gradle, Maven을 통해 프로젝트를 테스트하고 빌드한다. 
3. EC2 서버에서 해당 프로젝트를 실행 및 재실행한다. 

위 배포 과정을 개발자가 매번 명령어를 실행해 진행하는 것은 불편함이 많으므로
쉘 스크립트를 작성해 스크립트만 실행한다.

  • 쉘 스크립트 VS 빔(vim)
    1. 쉘 스크립트
       - .sh 확장자
       - 리눅스에서 기본적으로 사용 가능한 스크립트 파일

    2. 빔(vim)
      - 리눅스 환경과 같이 GUI가 아닌 환경에서 사용 가능한 편집 도구


  • deploy.sh 파일 작성
    vim ~/app/step1/deploy.sh
    
    #!/bin/bash
    
    REPOSITORY=/home/ec2-user/app/step1
    MIDPATH=/freelec-springboot2-webservice-sample/이름으로된폴더명
    PROJECT_NAME=freelec-springboot2-webservice
    
    cd $REPOSITORY/$MIDPATH/$PROJECT_NAME/
    
    echo "> Git Pull"
    git pull
    
    echo "> 프로젝트 Build 시작"
    ./gradlew build
    
    echo "> step1 디렉터리 이동"
    
    cd $REPOSITORY
    
    echo "> Build 파일 복사"
    cp $REPOSITORY/$MIDPATH/$PROJECT_NAME/build/libs/*.jar $REPOSITORY/
    
    echo "> 현재 구동 중인 애플리케이션 pid 확인"
    CURRENT_PID=$(pgrep -f ${PROJECT_NAME}.*.jar)
    
    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 &
  • 스크립트에 실행 권한 추가
    chmod +x ./deploy.sh


  • ./deploy.sh, nohup.out 실행
    ./deploy.sh
    vim nohup.out

[실행 결과]
nohup.out: ClientRegistrationRepository를 찾을 수 없어 애플리케이션 실행에 실패

***************************
APPLICATION FAILED TO START
***************************

Method springSecurityFilterChain in xxx 
required a bean of type 'xxx.ClientRegistrationRepository'
that could not be found

[실패원인]
application-oauth.properties가 .gitignore로 git에서 제외 대상이라 반영되지 않음
-> 8.3장에서 해결


8.3 외부 security 파일 등록하기

위의 8.2에서 application-oauth.properties가 .gitignore로 인해 반영되지 않으므로
리눅스 EC2 서버 내에서 동일한 내용의 파일 생성 필요

  • 서버 내에서 application-oauth.properties 생성
    vim /home/ec2-user/app/application-oauth.properties
    파일 내용은 로컬 PC의 application-oauth.properties와 동일

  • deploy.sh 파일 수정
    nohup java -jar \
    			-Dspring.config.location=classpath:/application.
    			properties,/home/ec2-user/app/application-oauth.properties \
    			 $REPOSITORY/$JAR_NAME 2>&1 &
    -Dspring.config.location
    : 위에서 생성한 application-oauth.properties를 반영해 스프링 설정 파일 위치를 지정

 

  • deploy 재실행
    정상적으로 실행되었다는 로그 확인
    Tomcat started on port(s):8080 (http) with context path ''

 


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

RDS가 사용중인 MariaDB에서 스프링부트 프로젝트를 실행하기 위한 작업

1. 테이블 생성
H2에서는 테이블을 자동 생성해주지만, MariaDB에서는 직접 쿼리를 이용해 테이블 생성하므로 RDS에 쿼리 반영하기

  • 테스트 코드 로그 복사 붙여넣기
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;

create table user
 (id bigint not null auto_increment, created_date datetime,
  modified_date datetime, email varchar(255) not null,
  name varchar(255) not null, picture varchar(255),
  role varchar(255) not null, primary key (id)) engine=InnoDB;
  • schema-mysql.sql 파일의 세션 테이블 복사 붙여넣기
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;

 

2. 프로젝트 설정
자바 프로젝트가 MariaDB에 접근하기 위한 데이터베이스 드라이버를 프로젝트에 추가

  • 드라이버 build.gradle에 등록
implementation "org.mariadb.jdbc:maridb-java-client"
  • 서버에서 구동될 환경 구성(RDS 환경 profile 설정)
spring.profiles.include=oauth,real-db
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.session.store-type=jdbc

※주의
리눅스 서버가 아닌 로컬 PC에서 추가한 후 push 할 것

3. EC2 리눅스 서버 설정
개인정보 유출 위험 방지를 위해 EC2 서버 내부에서 접속 정보 관리하기 

  • application-real-db.properties 생성
vim ~/app/application-real-db.properties

spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:mariadb://rds주소:3306/database명
spring.datasource.username=db계정
spring.datasource.password=db계정 비밀번호
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver

 

  • 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,classpath:/
			application-real.properties \
			-Dspring.profiles.active=real \
			 $REPOSITORY/$JAR_NAME 2>&1 &

 

  • ./deploy, vim nohup.out,curl 명령어 차례대로 실행
curl localhost:8080

=> html 코드가 보인다면 성공!


8.5 EC2에서 소셜 로그인하기

  • EC2에서 8080포트 보안 그룹에 열려 있는지 확인

[AWS EC2]->[보안 그룹]->[인바운드]

 

  • 인스턴스 선택하여 퍼블릭 IPv4 DNS(=도메인) 확인하기

  • 도메인 주소:8080 브라우저에 입력 

서비스에 localhost만 등록되어있어 구글, 네이버 로그인 불가능 

 

Google 클라우드 플랫폼

로그인 Google 클라우드 플랫폼으로 이동

accounts.google.com

  1. 승인된 도메인 입력 

[API 및 서비스]->[OAuth 동의화면]->[앱 수정]->[1.OAuth 동의화면]/ 작성형식: DNS

2. 승인된 리디렉션 URI 등록

[사용자 인증 정보]->[서비스 이름 클릭]/ 작성형식: DNS:8080/login/oauth2/code/google

 

 

애플리케이션 - NAVER Developers

 

developers.naver.com

1. 서비스, callback URL 등록 

[내 애플리케이션]->[API 설정]/ 작성형식: 서비스-http://DNS/, callback-http://DNS/login/oauth2/code/naver

로그인 성공 확인하면 실습 완료