일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- jpa
- 내가해냄
- 개발자기술면접
- 스프링부트 테스트코드
- Flexbox
- 기술면접
- 스프링부트와 AWS로 혼자 구현하는 웹 서비스
- 어찌저찌해냄
- 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 2장
- 스프링부트
- 오늘도
- 그래도일단
- 스프링부트와 AWS로 혼자 구현하는 웹서비스
- 운영체제
- 자바스크립트
- 트랜지스터
- 테스트코드
- AWS EC2 구현
- 스프링 부트와 AWS로 혼자 구현하는 웹 서비스
- CS
- Today
- Total
개발 공부
스프링 부트와 AWS로 혼자 구현하는 웹 서비스 8장 - EC2 서버에 프로젝트 배포하기 본문
7장 정리글
https://paradiseiswhereiam.tistory.com/141
스프링 부트와 AWS로 혼자 구현하는 웹 서비스 7장 - AWS RDS
6장 정리글 https://paradiseiswhereiam.tistory.com/139 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 6장 - AWS 서버 환경 만들기 (AWS EC2) 5장 정리글 https://paradiseiswhereiam.tistory.com/138 스프링 부..
paradiseiswhereiam.tistory.com
7장까지 끝내느라 정말 애썼다... 방화벽의 힘을 아주 잘 알 수 있는 경험이었음
드디어 8장!
EC2에 프로젝트 Clone 받기
깃허브에서 코드를 받아올 수 있게 EC2에 깃을 설치하고자 한다.
우선 EC2로 접속해서 다음과 같은 명령어를 입력한다.
sudo yum install git
설치가 완료되면 다음 명령어로 설치 상태를 확인한다.
git --version
그럼 이렇게 깃 버전이 나오면서 설치가 됐다는 걸 알 수 있다.
성공적으로 깃이 설치 되면 git clone으로 프로젝트를 저장할 디렉토리를 생성한다.
mkdir ~/app && mkdir ~/app/step1
➡️git clone으로 프로젝트를 저장할 디렉토리를 생성하는 명령이다.
cd ~/app/step1
➡️디렉토리를 생성했으니 그 디렉토리로 이동한다.
그리고 본인 깃허브 웹페이지에서 https 주소를 복사한다.
이 복사한 코드를 아래에 입력한다.
git clone 복사한 주소
그럼 클론이 진행되며, git clone이 끝났으면 클론된 프로젝트로 이동해서 파일들이 잘 복사됐는지 확인한다.
cd 프로젝트명 (깃 기준)
ll
그러면 위와 같은 코드들이 뜬다.
이제 이 코드들이 잘 수행되는지 테스트로 검증해 볼 차례이다.
./gradlew test
나는 여기서
-bash: ./gradlew: Permission dinied
라는 실행권한이 없다는 메시지가 떴다.
이 경우에는 다음과 같은 명령어로 실행 권한을 추가한 뒤 다시 테스트를 수행하면 된다.
chmod +x ./gradlew
배포 스크립트 만들기
❓배포란
작성한 코드를 실제 서버에 반영하는 것을 배포라고 한다.
이 책에서는 다음과 같은 과정을 배포로 본다.
- git clone 혹은 git pull을 통해 새 버전의 프로젝트 받음
- Gradle이나 Maven을 통해 프로젝트 테스트와 빌드
- EC2 서버에서 해당 프로젝트 실행 및 재실행
이 과정을 배포할 때마다 실행하는 것은 불편하므로, 쉘 스크립트로 작성해 스크립트만 실행하면 앞의 과정이 차례로 진행되도록 하자.
✔️쉘 스크립트
- [.sh]라는 파일 확장자를 가진 파일
- 리눅스에서 기본적으로 사용할 수 있는 스크립트 파일의 한 종류
✔️vim
- 리눅스 환경과 같이 GU가 아닌 환경에서 사용할 수 있는 편집 도구
vim으로 리눅스 환경에서의 편집을 진행해 보자.
vim ~/app/step1/deploy.sh
➡️~/app/step1에 deploy.sh 파일을 하나 생성한다.
#!/bin/bash
REPOSITORY=/home/ec2-user/app/step1 //(1)
PROJECT_NAME=springbootWebservice
cd $REPOSITORY/$PROJECT_NAME/ //(2)
echo "> Git Pull" //(3)
git pull
echo "> 프로젝트 Build 시작"
./gradlew build //(4)
echo ">step1 디렉토리로 이동"
cd $REPOSITORY
echo "> Build 파일복사"
cp $REPOSITORY/$PROJECT_NAME/build/libs/*.jar $REPOSITORY/ //(5)
echo "> 현재 구동중인 애플리케이션 pid 확인"
CURRENT_PID=$(pgrep -f ${PROJECT_NAME}.*.jar) //(6)
echo "현재 구동중인 애플리케이션 pid 확인"
if [ -z "$CURRENT_PID" ]; then //(7)
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) //(8)
echo "> JAR Name: $JAR_NAME"
nohup java -jar $REPOSITORY/$JAR_NAME 2>&1 & //(9)
편집기가 나오는데, o 누르고 작성하면 된다. 위 코드를 다 작성한 후에,
esc
:wq
입력해서 저장 후 빠져나온다.
그 다음 생성한 스크립트에 실행 권한을 추가한다.
chmod +x ./deploy.sh
그리고 나서
ll
명령어로 확인해 보면 x권한이 추가된 것을 알 수 있다.
./deploy.sh
위의 명령어를 통해 애플리케이션을 실행해 보자.
만일
./deploy.sh: line 27: unexpected EOF while looking for matching `}'
와 같은 오류가 뜬다면 오타 난 거니까 다시 한번 더 체크 하고 실행하기!
잘 입력했다면 다음과 같이 뜬다.
실행이 되는 것을 확인했으니 이제 nohup.out 파일을 열어 로그를 보자.
nohup.out은 실행되는 애플리케이션에서 출력되는 모든 내용을 갖고 있다.
vim nohup.out
nohup.out 제일 아래로 가면 ClientRegistraionRepository를 찾을 수 없다(that could not be found)는 에러가 발생하면서 애플리케이션 실행에 실패했다는 걸 알 수 있다.
왜 이렇게 됐을까?
외부 Security 파일 등록하기
위의 이유는 ClientRegistrationRepository를 생성하려면 clientId와 cliendSecret이 필수인데, 로컬 PC에서는 application.oauth.properties가 있어 문제가 없었다.
하지만 이 파일은 .gitignore로 git에서 제외 대상이라 깃허브에는 올라가 있지 않았고 따라서 깃허브에 있던 프로젝트를 클론한 이 파일에는 applitaion.oauth.properties가 없기 때문에 그렇다.
그렇다고 깃에 직접 올릴 순 없으니 서버에서 직접 이 설정들을 가지고 있게 해보자.
먼저 step2, step3에서도 쓰기 위해 step1이 아닌 app 디렉토리에 properties 파일을 생성한다.
vim /home/ec2-user/app/application-oauth.properties
그리고 로컬에 있는 application-oauth.properties의 코드를 복사해서 위의 파일에 붙여넣기 한다.
붙여넣기는 마우스 오른쪽 버튼을 눌러서 Paste 하면 된다.
그리고 저장 후 종료한다(:wq)
방금 생성한 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 &
위의 코드를 추가한 후 다시 deploy.sh를 실행한다
스프링 부트 프로젝트로 RDS 접근하기
RDS로 접근하기 위해서 해야 할 것은
1. 테이블 생성 : H2에서 자동 생성해주던 테이블들을 MariaDB에서는 직접 쿼리를 사용해 생성한다.
2. 프로젝트 설정 : 자바 프로젝트가 MariaDB에 접근하려면 데이터베이스 드라이버가 필요하므로 이를 추가한다.
3. EC2(리눅스 서버) 설정: 데이터베이스의 접속 정보는 중요하게 보호해야 할 정보이기 때문에 EC2 서부 내부에서 접속 정보를 관리하도록 설정한다.
RDS 테이블 생성
생성할 테이블은 JPA가 사용될 엔티티 테이블과 스프링 세션이 사용될 테이블을 생성한다.
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;
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;
테스트 코드를 런 해보면 Hibernate: 뒤에 테이블 생성 쿼리문이 있다. 그것을 복사해서 DB 브라우저에 있는 파일에 옮겨준다. (나같은 경우에는 springboot2_webservice라는 파일)
스프링 세션 테이블은 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;
이 쿼리들을 복사했으면 RDS에 반영한다.
use springboot2_webservice;
설정한 이름마다 다르겠지만 use 명령어를 통해 디비에 접속한 후 위에 복사해서 옮긴 생성 쿼리들을 실행해주면 끝!
프로젝트 설정
먼저 MariaDB 드라이버를 build.gradle에 등록한다.
implementation("org.mariadb.jdbc:mariadb-java-client")
책에선 complie을 쓰는데 앞장에서도 말했듯이 안 쓰는 기능이 돼서 implementation으로 바꿔 적었다.
그리고
src/main/resources/에 application-real.properties 파일을 추가해서 다음 코드를 추가한다.
spring.profiles.include=oauth,real-db
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.session.store-type=jdbc
application-real.properties로 파일을 ㅏㅁㄴ들면 profile=real인 환경이 구성된다고 보면 된다.
실제 운영된 환경이므로 보안/로그상 이슈가 될 만한 설정들을 모두 제거하며 RDS 환경 profile 설정이 추가된다.
여기까지 했다면 깃허브로 푸시해 준다.
EC2 설정
OAuth와 마찬가지로 RDS 접속 정보도 보호해야 할 정보이므로 EC2서버에 직접 설정 파일을 둔다.
app 디렉토리에 application-real-db.properties를 생성한다.
vim ~/app/application-real-db.properties
그리고 다음과 같은 내용을 추가한다.
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:mariadb://rds주소:포트명/database이름
spring.datasource.username=db계정
spring.datasource.password=db계정 비밀번호
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
저기서 포트명은 기본적으로 3306이라 설정돼있으므로 3306을 적는다.
그리고 deploy.sh가 real profile을 쓸 수 있도록 다음과 같이 수정한다.
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 &
수정할 때는
vi deploy.sh라고 명령하면 편집창이 뜬다.
이렇게 설정한 후 다시 한번 deploy.sh를 실행해 보자.
그리고 nohup.out 파일을 열어 다음과 같이 로그가 보인다면 성공이라는데 나는 안 보였다(?)
Tomcat started on port(s): 8080 (http) with ccontext path ''
Started Application in ~~ seconds (JVM running for ~~~)
하지만 curl 명령어로도 잘됐는지 확인 가능하므로 다음 명령어를 실행해 보았다.
curl localhost:8080
이렇게 html 코드가 정상적으로 보인다면 성공이다.
EC2에서 소셜 로그인 하기
curl 명령어를 통해 EC2에 서비스가 잘 배포된 것은 확인했다.
이제 브라우저에서 확인해 볼 텐데, 그 전에 다음과 같은 몇 가지 작업을 해야 한다.
1. AWS 보안 그룹 변경하기
EC2에 스프링 부트 프로젝트가 8080 포트로 배포되었으니 8080포트가 보안 그룹에 열려 있는지 확인한다.
열려 있지 않으면 편집하기
2. AWS EC2 도메인으로 접속
왼쪽 사이드바의 인스턴스 메뉴를 선택하면 퍼블릭 IPv4 DNS 라는 부분에 amazonaws.com으로 끝나는 주소가 있다.
그 주소가 EC2에 자동으로 할당된 도메인이며, 인터넷이 되는 장소에서 이 주소를 입력하면 우리의 EC2에 접근 가능하다.
이 도메인 주소 뒤에 :8080을 붙여 접속하면 전에 만든 서비스가 뜬다.
3. 구글에 EC2 주소 등록
체크한 부분에 DNS 주소를 적는다.
저장 후, 다시 사용자 인증 정보 탭에 들어가서 내가 등록한 서비스의 이름을 클릭한다.
그러면 승인된 리디렉션 URI에 위에 등록한 DNS 주소가 있다.
거기에 추가로
http:// DNS 주소 :8080/login/oauth2/code/google 을 붙여서 입력한다.
저장 후 EC2 DNS 주소로 이동해서 구글 로그인을 시도해 보면
잘 된다! 성공
4. 네이버에 EC2 주소 등록
쭉 내려 보면
서비스 URL과 Callback URL을 입력하는 부분이 있다.
서비스 URL은
로그인을 시도하는 서비스가 네이버에 등록된 서비스인지 판단하기 위한 항목이다.
8080포트 제외하고 http://DNS주소 를 입력한다.
네이버에서 아직 지원되지 않아서 하나만 등록 가능하다. 즉 EC2의 주소를 등록하면 localhost가 안 된다.
개발 단계에서는 등록하지 않는 것을 추천하고, localhost에서도 테스트하고 싶으면 네이버 서비스를 하나 더 생성해서 키를 발급받으면 된다.
CallbackURL은
전체 주소를 등록한다. 위의 캡쳐에서 localhost만 도메인 주소로 바꾸면 됨.
수정 후 다시 로그인 해보면
잘 된다!
우여곡절이 많았던 8장도 끝~~
하지만 다음 장을 위해 짚고 넘어가야 할 부분이 있다.
현재 방식의 문제점 두 가지
- 수동 실행되는 Test
: 내가 짠 코드가 다른 개발자의 코드에 영향을 끼치지 않는지 확인하기 위해 전체 테스트를 수행해야 한다
현재 상태에선 항상 개발자가 작업을 진행할 때마다 수동으로 전체 테스트를 수행해야 한다.
- 수동 Build
: 다른 사람이 작성한 브랜치와 내가 작성한 브랜치가 합쳐졌을 때 이상이 없는지는 Build를 수행해야만 알 수 있다.
이를 매번 개발자가 직접 실행해야 한다.
➡️그래서 다음 장에서는 깃허브에 푸시를 하면 자동으로 테스트와 빌드 그리고 Deploy가 진행되도록 개선하는 방법을 알아보도록 할 것이다.
'Spring > Spring Boot' 카테고리의 다른 글
빌드 시 --stacktrace 옵션 실행하는 방법 (0) | 2022.09.14 |
---|---|
스프링 부트와 AWS로 혼자 구현하는 웹 서비스 7장 - AWS RDS (0) | 2022.09.01 |
[문제해결] AWS Connection timed out (1) | 2022.09.01 |
스프링 부트와 AWS로 혼자 구현하는 웹 서비스 6장 - AWS 서버 환경 만들기 (AWS EC2) (0) | 2022.08.29 |
스프링 부트와 AWS로 혼자 구현하는 웹 서비스 5장 - 책 보면서 다른 부분, 이해 안돼서 찾아본 부분 보충해서 설명 / 스프링 시큐리티와 OAuth 2.0으로 로그인 기능 구현하기 (0) | 2022.08.28 |