Web/AWS

EC2 서버에 프로젝트 배포하기

태윤2 2021. 8. 23. 00:31

EC2 프로젝트 Clone

  • EC2에 깃 설치
sudo yum install git
  • git 버전 확인
git --version
  • 디렉토리 생성 및 이동
mkdir ~/app && mkdir ~/app/step1

디렉토리로 이동
cd ~/app/step1
  • git hub 주소 복사

git clone 복사한 주소
  • username 은 아이디를 입력
  • password는 로그인 패스워드가아닌 access token을 입력
    • 패스워드를 입력하면 아래와같은 오류가 뜸 
    • Cloning into 'spring-boot-webservice'...
      Username for 'https://github.com': fmoni1306@gmail.com
      Password for 'https://fmoni1306@gmail.com@github.com':
      remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.

access tokens 발급 받는법은 구글에 검색 해보자!

 

  • /gradelw test 를 실행
    • Permission denied 가 뜨면 chmod +x gradlew로 권한 설정을 해주자
  • 테스트를 실패해서 수정하고 깃허브에 푸시 했다면 EC2 서버에서 git pull 실행

테스트 통과

배포 스크립트 만들기

배포란?

  • git clone 혹은 git pull을 통해 새 버전의 프로젝트를 받음
  • Gradle이나 Maven을 통해 프로젝트 테스트와 빌드
  • EC2 서버에서 해당 프로젝트 실행 및 재실행

 

쉘스크립트로 위의 배포과정을 차례대로 실행하기

  • 쉘 스크립트(.sh) 파일 생성
vim ~/app/step1/deploy.sh
  • vim 으로 코드 추가
    • vim 사용 법은 아래 링크에서 익히자
 

GitHub - johngrib/simple_vim_guide: simple vim guide

simple vim guide. Contribute to johngrib/simple_vim_guide development by creating an account on GitHub.

github.com

 

#!/bin/bash

REPOSITORY=/home/ec2-user/app/step1
PROJECT_NAME=yoon-springboot2-webservice

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 &
  1. REPOSITORY=/home/ec2-user/app/step1
    • 프로젝트 디렉토리 주소는 스크립트 내에서 자주 사용하는 값이기 때문에 이를 변수로 저장
    • PROJECT_NAME=spring-boot-webservice도 동일하게 변수로 저장
    • 쉘에서는 타입 없이 선언하여 저장
    • 쉘에서는 $변수명으로 변수를 사용할 수 있음
  2. cd $REPOSITORY/$PROJECT_NAME/
    • 제일 처음 git clone 받았던 디렉토리로 이동
    • 바로 위의 쉘 변수 설명을 따라 /home/ec2-user/app/step1/spring-boot-webservice 주소로 이동
  3. git pull
    • 디렉토리 이동 후, master 브랜치의 최신 내용을 받음
  4. ./gradlew build
    • 프로젝트 내부의 gradlew로 build를 수행
  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 id 값을 보고 프로세스가 있으면 해당 프로세스를 종료
  8. JAR_NAME=$(ls -tr $REPOSITORY/ | grep jar | tail -n 1)
    • 새로 실행할 jar 파일명을 찾음
    • 여러 jar 파일이 생기기 때문에 tail -n로 가장 나중의 jar 파일(최신 파일)을 변수에 저장
  9. nohup java -jar $REPOSITORY/$JAR_NAME 2>&1 &
    • 찾은 jar 파일명으로 해당 jar 파일을 hobup로 실행
    • 스프링 부트의 장점으로 특별히 외장 톰캣을 설치할 필요가 없음
    • 내장 톰캣을 사용해서 jar 파일만 있으면 바로 웹 애플리케이션 서버를 실행할 수 있음
    • 일반적으로 자바를 실행할 때는 java -jar라는 명령어를 사용하지만, 이렇게 하면 사용자가 터미널 접속을 끊을 때 애플리케이션도 같이 종료됨
    • 애플리케이션 실행자가 터미널을 종료해도 애플리케이션은 게속 구동될 수 있도록 nohup 명령어를 사용

 

스크립트에 실행 권한 추가

chmod +x ./deploy.sh

 

실행 하면 oauth 파일 문제로 실행이 되지않음

  • .gitignore에 oauth관련 파일을 추가해 github에 올라가지 않기 때문에 서버에 직접 관련 정보를 입력
  • app 디렉토리에 application.yml(or properties) 파일 생성
vim /home/ec2-user/app/application-oauth.yml(properties)
  • deploy.sh 파일수정
  • 나는 goole, naver oauth 파일을 두개로 나눴기 때문에 yml 파일 두개 추가
nohup java -jar \ -Dspirng.config.location=classpath:/application.yml,/home/ec2-user/app/application-oauth-google.yml,/home/ec2-user/app/application-oauth-naver.yml \ $REPOSITORY/$JAR_NAME 2>&1 &
  1. -Dspring.config.location
    • 스프링 설정 파일 위치를 지정
    • 기본 옵션들을 담고 있는 application.yml(properties)와 OAuth 설정들을 담고 있는 oauth의 위치를 지정
    • classpath가 붙으면 jar 안에 있는 resources 디렉토리를 기준으로 경로가 생성
    • application-oauth-XXX.yml(properties)는 절대경로를 사용함. 외부에 파일이 있기 때문임
  • 다시 deploy.sh 실행

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

  • 프로젝트 실행시 만들어지는 테이블 생성

  • session 테이블 생성

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;
  • MariaDB 드라이버 build.gradle에 등록

  • application-real.yml 파일 만들기(실제 운영될 환경 설정이기 때문에 보안/로그상 이슈가 될 설정 제거)
spring:
  profiles:
    include: oauth-google, oauth-naver, real-db
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect
  session:
    store-type: jdbc
  • EC2 설정
  • deploy.sh가 real profile을 쓸수 있도록 수정
nohup java -jar \
        -Dspring.config.location=classpath:/application.yml,/home/ec2-user/app/application-oauth.yml,/home/ec2-user/app/application-real-db.yml,classpath:/application-real.yml \
        -Dspring.profiles.active=real \
        $REPOSITORY/$JAR_NAME 2>&1 &
  • -Dspring.profiles.active=real
    • application-real.yml를 활성화 시킴
    • application-real.yml의 spring.profiles.include=oauth-google, oauth-naver, real-db 옵션 때문에 real-db 역시 함께 활성화 대상에 포함됨

 

소셜 로그인 url 추가~

인스턴스 상세정보에 가면 내 주소가 있음

  • 위 주소를 소셜 로그인에 추가하면 된다

 

  • reference

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