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.
- /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 사용 법은 아래 링크에서 익히자
#!/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 &
- REPOSITORY=/home/ec2-user/app/step1
- 프로젝트 디렉토리 주소는 스크립트 내에서 자주 사용하는 값이기 때문에 이를 변수로 저장
- PROJECT_NAME=spring-boot-webservice도 동일하게 변수로 저장
- 쉘에서는 타입 없이 선언하여 저장
- 쉘에서는 $변수명으로 변수를 사용할 수 있음
- cd $REPOSITORY/$PROJECT_NAME/
- 제일 처음 git clone 받았던 디렉토리로 이동
- 바로 위의 쉘 변수 설명을 따라 /home/ec2-user/app/step1/spring-boot-webservice 주소로 이동
- git pull
- 디렉토리 이동 후, master 브랜치의 최신 내용을 받음
- ./gradlew build
- 프로젝트 내부의 gradlew로 build를 수행
- cp $REPOSITORY/$PROJECT_NAME/build/libs/*.jar $REPOSITORY/
- build의 결과물인 jar파일을 복사해 jar 파일을 모아둔 위치로 복사
- CURRENT_PID=$(pgrep -f ${PROJECT_NAME}.*.jar)
- 기존에 수행 중이던 스프링 부트 애플리케이션을 종료
- pgrep은 process id만 추출하는 명령어
- -f 옵션은 프로세스 이름으로 찾음
- if ~ else ~fi
- 현재 구동 중인 프로세스가 있는지 없는지를 판단해서 기능을 수행
- process id 값을 보고 프로세스가 있으면 해당 프로세스를 종료
- JAR_NAME=$(ls -tr $REPOSITORY/ | grep jar | tail -n 1)
- 새로 실행할 jar 파일명을 찾음
- 여러 jar 파일이 생기기 때문에 tail -n로 가장 나중의 jar 파일(최신 파일)을 변수에 저장
- 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 &
- -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로 혼자 구현하는 웹서비스