본문 바로가기

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

[스프링부트/AWS] 8장 EC2 서버에 프로젝트를 배포해보자

- EC2 Project Git Clone

# git 설치
sudo yum install git

# git version 확인
git --version

# git clone으로 저장할 디렉토리 설정
mkfir ~/app && mkdir ~/app/step1

# step1 폴더로 이동
cd ~/app/step1

# git clone 진행
git clone https://github.com/oss0202/com.jordy.book.git

# 프로젝트로 이동 후 올바르게 clone이 진행되었는지 파일 확인
cd 프로젝트 명
ll

# chmod로 실행 권한 추가
chmod +x ./gradlew

# 코드 테스트
./gradlew test

eunguru.tistory.com/93

 

[UNIX / Linux] 권한 관리(chmod, chown, chgrp, umask)

접근 권한 변경(chmod) - chmod 명령: 기존 파일 또는 디렉토리에 대한 접근 권한(파일 모드)을 변경할 때 사용 - 파일 모드의 변경은 파일 소유자나 슈퍼 유저만 가능 - 파일 모드는 기호(문자)나 8진

eunguru.tistory.com

※ EC2에 Gradle(그래들)을 설치하지 않았지만 Gradle Task(ex. test)를 수행할 수 있는 이유

프로젝트 내부에 포함된 gradlew 파일 때문입니다. gradle이 설치되지 않은 환경 혹은 버전이 다른 상황에서도 해당 프로젝트에 한해서 gradle을 쓸 수 있도록 지원하는 Wrapper 파일 입니다. 해당 파일을 직접 이용하기 때문에 별도로 설치할 필요가 없습니다.

 

- 배포 스크립트 만들기

deploy.sh

#!/bin/bash

REPOSITORY=/home/ec2-user/app/step2
PROJECT_NAME=com.jordy.book

cd $REPOSITORY/$PROJECT_NAME/

echo "> Git pull"

git pull

echo "> 프로젝트 Build 시작"

./gradlew build

echo "> step1 디렉토리 이동"

cd $REPOSITORY

echo "> Build 파일 복사"

cp $REPOSITORY/zip/*.jar $REPOSITORY/

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

CURRENT_PID=$(pgrep -fl com.jordy.book | awk '{print $1}')

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/*.jar | tail -n 1)

echo "> JAR Name: $JAR_NAME"

echo "> $JAR_NAME 에 실행권한 추가"

chmod +x $JAR_NAME

echo "> $JAR_NAME 실행"

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

https://github.com/oss0202/com.jordy.book/blob/master/scripts/deploy_01.sh

 

oss0202/com.jordy.book

Jordy Book Project. Contribute to oss0202/com.jordy.book development by creating an account on GitHub.

github.com

 

- 배포스크립트 실행

※ 실행권한 추가

# 모든 소유자에게 실행 권한 추가
chmod +x ./deploy

# 실행
sudo ./deploy.sh

 

- 실행로그 확인(nohup.out)

sudo ./nohup.out

Error Log 확인

- ClientRegistrationRepository 에러 원인

ClientRegistrationRepository를 생성하려면 Clientid와 ClientSecret이 필수입니다. 하지만 우리는 앞에서 .gitignore에서 application-oauth.properties를 제외해서 깃허브에는 올라가 있지 않습니다.

어플리케이션 길행을 위해서 공개된 저장소(public)에 Clientid와 ClientSecret을 올릴 수는 없으니 서버에서 직접 이 설정들을 가지고 있게 하겠습니다.

 

- 외부 Security 파일 등록 

# app 디렉토리에 생성(이후 무중단 배포때에도 공통으로 사용하기 위해서)
vim /home/ec2-user/app/application-oauth.properties

# 로컬에 있는 applicatoin-oauth.properties 파일을 복사 후 저장
:wq

# deploy.sh 파일 수정
nohup java -jar \
    -Dspring.config.location=classpath:/application.properties,/home/ec2-user/app/application-oauth.properties \
    $JAR_NAME > $REPOSITORY/nohup.out 2>&1 &

https://github.com/oss0202/com.jordy.book/blob/master/scripts/deploy_01_oauth_add.sh

 

oss0202/com.jordy.book

Jordy Book Project. Contribute to oss0202/com.jordy.book development by creating an account on GitHub.

github.com

-Dspring.config.location

  • 스프링 설정 파일 위치를 지정합니다.
  • 기본 옵션들을 담고 있는 application.properties와 OAuth 설정들을 담고 있는 application-oauth.properties의 위치를 지정합니다.
  • classpath가 붙으면 jar 안에 있는 resources 디렉토리 기준으로 경로가 생성됩니다.
  • application-oauth.properties은 절대경로를 사용합니다. (외부에 파일이 있기 때문입니다.)

위 설정들이 완료되었다면 ./deploy.sh이 정상적으로 실행이 됩니다.

 

- RDS 접근하기

- MariaDB에서 스프링부트 프로젝트를 실행하기 위해선 몇가지 작업이 필요합니다. 진행할 작업은 다음과 같습니다.

  • 테이블 생성 : H2에서 자동으로 생성해주던 테이블들을 MariaDB에선 직접 쿼리를 이용해 생성합니다.
  • 프로젝트 설정 : 자바 프로젝트가 MariaDB에 접근하려면 데이터베이스 드라이버가 필요합니다. 
  • EC2 (리눅스 서버) 설정 : 프로젝트 안에 접속 정보를 가지고 있다면 누구나 해킹할 위험이 있으니, EC2 서버 내부에서 접속 정보를 관리하도록 설정합니다.

1) RDS 테이블 생성

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) 프로젝트 설정(build.gradle에 등록)

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

3) application-real.properties 생성(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

모든 설정 완료 후 깃허브로 푸시합니다.

 

- EC2 설정

OAuth와 마찬가지로 RDS 접속 정보도 보호해야하니, 직접 설정 파일을 생성합니다

app 디렉토리에 application-real-db.properties 파일 생성

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

https://github.com/oss0202/com.jordy.book/blob/master/scripts/application-real-db.properties

 

oss0202/com.jordy.book

Jordy Book Project. Contribute to oss0202/com.jordy.book development by creating an account on GitHub.

github.com

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

  • JPA로 테이블이 자동 생성되는 옵션을 None(생성하지 않음)으로 지정합니다.
  • RDS에는 실제 운영으로 사용될 테이블이니 절대 스프링 부트에서 새로 만들지 않도록 해야합니다.
  • 이 옵션을 하지 않으면 자칫 테이블이 모두 새로 생성될 수 있습니다.
  • 주의해야 하는 옵션입니다.

- deploy.sh가 real profile을 쓸 수 있도록 다음과 같이 개선합니다.

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

https://github.com/oss0202/com.jordy.book/blob/master/scripts/deploy_01_realfile_add.sh

 

oss0202/com.jordy.book

Jordy Book Project. Contribute to oss0202/com.jordy.book development by creating an account on GitHub.

github.com

-Dspring.profiles.active=real

  • application-real.properties를 활성화시킵니다.
  • applicatoin-real.properties의 spring.profiles.include=oauth, real-db 옵션 때문에 real-db 역시 함께 활성화 대상에 포함됩니다.

 

- 위 세팅 후  다시 deploy.sh 실행

# git pull
sudo git pull

# deploy.sh 실행
./deploy

# curl 명령어로 html 코드 확인
curl localhost:8080

 

- EC2 소셜 로그인 연동

책 참고, 특별한 이슈 없이 진행했습니다.

 

- 이슈가 생겼었던 부분들

1. deploy.sh 실행

root 권한으로 실행하지 않아서 permittion error가 발생했었습니다.

그래서 root권한으로 실행 또는 권한 변경(sudo chmod +x ~) 후 실행 했습니다.

※ 사용중인 포트 찾기 스크립트 수정 - 저자처럼 사용하니 사용하는 포트를 찾지 못해서 아래와 같이 수정하였습니다.

# 저자가 사용한 스크립트
CURRENT_PID=$(pgrep -fl com.jordy.book | grep jar | awk '{print $1}')

# 내가 사용한 스크립트
CURRENT_PID=$(pgrep -fl com.jordy.book | awk '{print $1}')

 

2. 타이핑 이슈

editor(Notepad++, IntelliJ, ..)등을 이용해서 타이핑 한 후에 복사한게 아니라 바로 Shell로 타이핑 하다보니 오타가 발생했었습니다. 그래서 현재는 IntelliJ에 작성 후 복붙을 했습니다.(붙여넣기 : Shift + Insert)

- github.com/oss0202/com.jordy.book-> script에 보관

 

oss0202/com.jordy.book

Jordy Book Project. Contribute to oss0202/com.jordy.book development by creating an account on GitHub.

github.com

 

3. nohup.out 갱신

deploy.sh를 실행할 떄마다 로그가 쌓여서 언제 실행한 에러인지 확인이 어려웠습니다. 

그래서 deploy.sh를 실행하기 전에 삭제를 한 후에 deploy.sh를 실행했습니다.

sudo rm ./nohup.out
sudo ./deploy.sh

 

4.EC2에 자동으로 할당된 도메인 접속

https -> http로 접속

 

https://bigsun84.tistory.com/365

 

[Linux] pgrep 명령어 옵션 정리

pgrep  : ps 명령어와 grep 명령어를 합쳐서 하나의 명령어로 사용해서 원하는 정보를 편하게 출력하는 명령어 ### 옵션 -c : 조건에 맞는 프로세스 수를 출력한다. $ pgrep vi 14777 14988 $ pgrep -c vi 2 -d :..

bigsun84.tistory.com

https://zzsza.github.io/development/2017/12/20/linux-6/

 

리눅스 awk 사용법

awk awk : 데이터를 조작하고 리포트를 생성하기 위해 사용하는 언어입니다. 리눅스에서 사용하는 awk는 GNU 버전의 gawk로 심볼릭 링크되어 있습니다 간단한 연산자를 명령라인에서 사용할 수 있으

zzsza.github.io

 

5. region 미지정 이슈

AWS Console에서 아시아 태평양(서울 : ap-northeast-2)으로 지정을 해야하는데 default인 미국 동부(버즈니아 북부 : us-east-1)로 지정을 하고 EC2 인스턴스를 생성했었습니다. 그래서 처음부터 다시 세팅을 진행했습니다.