프로젝트 배포를 위한 EC2+RDS+GIT ACTION 사용기 목차
1. EC2생성 및 연결
2. RDS + EC2설정 (현재)
3. GITAction + EC2 + CodeDeploy등을 이용한 CD(자동배포)
RDS 인스턴스 생성 및 EC2와 연결은 다른 포스팅을 참고하자
이거대로 따라했다. 다만 이렇게 했었을 때 추가로 해야할 설정이 있을 수도 있음. (나는 그랬음)
아래에 해당 내용이 있으니 순차적으로 고고씽!
목차
1. EC2 연결 후 mysql설치
1. MySql 설치
#mysql설치 - AmazonLinux2용
#sudo yum install https://dev.mysql.com/get/mysql80-community-release-el7-5.noarch.rpm
#sudo yum -y install mysql-community-server
linux mysql 설치 중 Error:
Problem: conflicting requests
....
분명히 인터넷에 검색한대로 mysql설치를 진행하는데 자꾸 에러나며 설치가 안되는 것임.
그래서 찾아보니 EC2 AmazonLinux2023 버전으로 설치한 사람은 해당 리눅스에 연결된 레포가 잘못된거라 다른걸로 해야한다고 한다.
#mysql설치 - AmazonLinux2023용
sudo dnf install https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
sudo dnf install mysql-community-server
휴 정상 설치되고 버전도 확인할 수 있게 되었다!!!!!!!!!!!!!!!
2. MySql 설정작업
#mysql characterset설정
sudo vim /etc/my.cnf
[mysqld]
...
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
skip-character-set-client-handshake
systemctl restart mysqld
3. MySql 실행 후 비밀번호 작업
#mysql실행
sudo systemctl start mysqld
루트 임시비밀번호 확인 후 변경해야한다.
sudo cat /var/log/mysqld.log | grep 'temporary password'
root@localhost: 옆에 있는 값이 임시비밀번호다.
잘 기억해놓고 이제 로그인 후에 비밀번호를 변경해주자.
#mysql 비밀번호를 입력해서 로그인하겠다.
mysql -u root -p
mysql> alter user 'root'@'localhost' identified with mysql_native_password by '변경pw';
아니 근데 킹받게 자꾸 비밀번호 입력을 하면 정책이랑 안맞다는 에러가 엄청 났다.
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
비밀번호 정책
흠 특수문자라도 넣어야하나? 하고 root123!@# 넣었는데 그것도 실패
좀 더 찾아보니 사용자명과 겹치는 값이 들어가면 안된대서 shop123!@# 으로 해도 실패
대문자도 하나는 포함시켜줘야하나보다^^ 겨우 성공..
요즘 빡세진 다른 홈페이지 비밀번호 정책덕에 유추가 가능해졌다.
기본설정이 어떻게 되어있을진 모르지만
일단!! "특수문자1개 + 대문자1개 + 사용자명과 안겹치게 + 길이는 8글자 이상 + 숫자도 1개" 이상 포함한 것으로 만들어라. 일단!!! 통과를 해야 정책을 다운그레이드 시키고 쉬운걸로 바꿀 수 있기 때문이다...
중간에 암호정책을 보고 싶어서
mysql> show variables like 'validate_password%';
를 했더니 나오는 에러는 비밀번호를 바꾸고 해라~ ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 아뉘 장난하나.
어쩔 수 없이 빡센 규칙대로 적용을 하고 다시 조회해서 정책을 낮춘 후 쉬운 비밀번호로 변경했다.
비밀번호 정책 변경방법
해당 정책을 변경하고싶다면 쿼리문을 잘 써주면 되는데 형식은 아래와 같다.
mysql> SET GLOBAL validate_password.변경원하는명칭=값
근데 여기서 의문점은 이제 RDS랑 연결해서 쓸건데 mysql설치하고 ID/PW를 RDS랑 동일하게 만들어야하느냐 라는 부분..? 일단 혹시 몰라서 똑같이 맞춰서 진행했다.
2. RDS 셋팅 연결 확인
1.로컬에서 DB IDE를 이용한 접속 확인
인터넷 찾아보니까 대부분 Mysql WorkBench를 쓰던데 본인이 쓰는 DB용 IDE가 있다면 그걸로 해도 무관함
참고로 맥에서는 호환성 문제다뭐다 해서 Sequel ACE가 좋다고 해서 나는 원래 이걸 쓰고 있었다.
해당 설치방법은 따로 포스팅되어있으니 쓰고싶다면 그걸 보고 진행하자.
Host에는 RDS 데이터베이스에 있는 엔드포인트를 그대로 복사해서 넣어주면 된다.
이름은 대강 원하는대로 지어도 됨
실패가 떴다면 뭔가 RDS설정이 잘못됐다는 뜻이겠지..
잘 연결된다면 본인이 따라한 RDS설정 방식이 모두에게 오픈 된 것으로 혹은 내 IP기준으로 접속할 수 있게 인바운드 규칙을 잘 설정했다는 뜻이겠고.
아무튼 첨에 접속이 안돼서 생각을 해봤더니 RDS 보안그룹 관련된 작업으로 EC2랑 연결하려고
인바운드 규칙 편집시에 EC2에서 사용하던 보안그룹 이름을 선택했다.
사용자 지정 후 오른쪽 돋보기를 눌러보면 여러 설정들이 보인다.
여기서 나는 launch-wizard-1 | sg - 어쩌고가 EC2때 설정한 보안그룹이라 해당 내역을 선택했는데
해당 보안그룹 인바운드는 어떻게 되어있나 확인해봤더니
EC2 서버 접근이니 당연히 8080 22만 열려있고 (HTTP, HTTPS도 열어도 되긴함)
RDS는 디비서버라 3306포트로 여는데 EC2를 통해서만(?) 접속할 수 있다는 설정이라 내 로컬에서 접속이 안된듯 하다.
그래서 원래는 내 IP만 추가하고싶었는데 공유기 설정으로 고정IP를 따로 지정을 안해놔서 계속 바뀌는걸 보고
그냥 IPv4 모두에게 오픈하는걸로 설정했다.
본인 고정 IP가 있고 본인만!! 접근할거라면 본인 IP 넣어서 설정하는게 나을 것 같다.
아무튼 인바운드 규칙으로 모두 접근 허용을 하고나니 내 컴퓨터에서도 해당 RDS로 접근할 수 있게 되었다.
2.EC2 서버에서 RDS DB로 접속하기
mysql -u root -p --host RDS엔드포인트
비밀번호는 본인이 RDS생성할 때 기입했던 비밀번호로 기입하면 된다.
이렇게 되면 EC2에서 RDS접속도 완료!!
3. Spring Project 설정사항 (application.yml)
3-1. 본인 로컬에서 RDS만 연결해서 쓸 것이다.
사실 이럴이유는 굳이 있나? 싶긴함 로컬에서 걍 로컬 DB만들면 되지않나?
그래도 뭐 RDS잘 돌아가나 테스트겸 한다고 치고
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql/엔드포인트/3306/db이름
username: rds인스턴스 생성 시 이름
password: rds인스턴스 생성 시 pw
jpa:
database-platform: org.hibernate.dialect.MySQL8Dialect
이렇게 값을 강제로 주입해주면 되겠다. 본인 테스트용이니까 유출되도 상관없다는 전제하에!
git ignore로 안올릴거여도 상관은 없긴함.
3-2. EC2 + RDS 연결해서 같이 쓸 것이다.
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${rds_mysql_url}
username: ${rds_mysql_name}
password: ${rds_mysql_secret}
jpa:
database-platform: org.hibernate.dialect.MySQL8Dialect
배포용 / 혹은 개발용 application.yml이라고 가정하고 우리가 EC2 + RDS를 써서 접근할 것 아닌가?
EC2 서버에 환경변수를 선언해서 application.yml을 굳이 git ignore하지 않고도 쓸 수 있는 방법으로 접근하는게 편하다고 생각한다.
다시 EC2 연결 화면(터미널이든 기타 툴이든)으로 돌아가서 bashrc를 수정해주자.
sudo vim /etc/bashrc
그러고 하단부에 application.yml에서도 환경변수로 쓸 내용들을 모조리 등록해주고 환경변수 실행을 해주면 끝
source /etc/bashrc
4. EC2에 프로젝트 배포
4-1. 깃허브 프로젝트 배포
세번째 포스팅 참고
4-2. 로컬 프로젝트 배포
본인 테스트용으로 로컬에 있는 프로젝트를 올리려면 jar파일을 생성하여 그걸 ec2서버로 옮기는 방법이 있다.
터미널에서 프로젝트 경로로 이동하여 ./gradlew clean build 명령어를 실행하면 되는데
나처럼 permission denied: ./gradlew가 뜬다면 권한을 주면된다.
혹시나 테스트코드는 굳이 빌드할 필요가 없다면
./gradlew clean build -x test
해당 옵션을 추가하여 빌드를 진행해주면 된다.
그래서 jar파일이 생성이 완료됐다면 그걸 EC2서버로 복사해서 넣어주는 작업을 터미널에서 마저 하자.
여기서 주의해야할 점!! (./ssh/config설정 한 사람은 이 부분은 넘겨도 됨)
나는 호스트이름 설정을 따로 안해둬서 이 파일 복사를 진행하려면 jar파일을 키페어있는 위치로 이동시킨 후 거기서 작업을 해야한다.
scp shopping-0.0.1-SNAPSHOT-plain.jar shopping-0.0.1-SNAPSHOT.jar 퍼블릭DNS:
~/project
이렇게 명령어를 실행했더니 바로 권한 거절됨!
ec2-user@ec2-13-125-29-219.ap-northeast-2.compute.amazonaws.com: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
scp: Connection closed
그럼 방법이 두가지가 있다. jar파일 이동후 거기서 똑같이 하거나
host config설정을 하거나.. 나는 이걸 나중에 봐서 뒤늦게 추가하지만 앞선 포스팅대로 했다면 호스트 이름 설정을 해놨으리라 생각한다.
설정 한 사람은 여기서 부터 다시 시작
#스냅샷 파일 위치로 이동
cd build/libs
scp shopping-0.0.1-SNAPSHOT-plain.jar shopping-0.0.1-SNAPSHOT.jar hyeonjin:~/project
그러고나서 EC2에 접속해서 보면
기본경로 ~에서 project파일이 하나 생기고 그 안에 jar파일이 잘 복사되어있는 것을 볼 수 있다.
기존 파일이 있으면 덮어쓰기가 된다.
해당 스냅샷이 있는 경로로 이동한 다음 아래 명령어들을 실행해주면 되는데
#application-prod 설정 + 백그라운드로 jar파일 실행
nohup java -jar -Dspring.profiles.active=prod *.jar
본인 테스트용이라면 굳이 백그라운드로 돌릴필요는 없으니
java -jar -Dspring.profiles.active=prod *.jar
nohup 을 빼고 실행하면 되는데 이렇게 했을 때 혹시나
no main manifest attribute, in shopping-0.0.1-SNAPSHOT-plain.jar
이런 에러가 난다면 여러가지 방법들이 있는데 모든 케이스들을 알려주는 건 no main mainfest attribute in 에러 여기서 확인하시고
단순 테스트라 잘 가동되는지, EC2+RDS잘 되는지 확인만 할거라면
아까 스냅샷이 두개 따졌던 것을 봤을 거고 그 중에서 plain이 안달린!!! jar로 실행해주면 되겠다.
java -jar -Dspring.profiles.active=prod shopping-0.0.1-SNAPSHOT.jar
에러가 나면 뭐때문에 에러나는지 에러메세지는 잘 알려준다.
이렇게 뜨면서 JPA를 쓴다면 DB까지 크리에이트해주면 정상 동작이 되는 것이다.
끝
-------------------아래는 빌드하면서 배포 환경으로 뭔가 잘 안되는 사람들만 보길 ------------------
분명히 로컬에서 RDS경로 접속도 잘 했는데 빌드했을 때 접속 에러가 자꾸 났다.
좀 의아한건 @뒤가 'localhost'라는거..? 아닌데..? 흠... jar파일이 잘못된건가?
거기다 배포서버(RDS)는 mysql8인데 에러 읽어보다보니 5로 하고있다 라는 얘기도 있고 뭔가 prod로 실행이 잘 안되는듯한 느낌? 이다.
SQLException: Access denied for user 'root'@'localhost' (using password: YES)
...
HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
그리고 다른 사람들이 한 걸 봤더니 profiles에서 "prod"만 돼야할 것 같은데 자꾸 이상한 것도 딸려들어가서??? 그런 것 같기도하고... 그렇다고 하기엔 다른 파일들엔 Database내역이 없는데..
여튼 이를통해 확실한건 application.yml이나 application-prod.yml 셋팅 문제로 추정됐고 그래서 수정을 열심히 한 결과 드디어 항간에서 떠돌던 설정법에 대해 얼추 이해했다.
우선 나의 첫 application.yml 들의 구성은 로컬로만 되어있었고 -내가 설정한거 아님. 팀프로젝트 구성-
Case1. 디폴트에 로컬이 있던 yml구성
사실 인터넷에 떠다니는 로컬/개발/배포 yml구성은 이와는 좀 다른 모습일 것이다. 물론 저게 잘못된 것은 아님!
Case 2. 디폴트는 놔두고 local, prod추가 및 분리한 yml구성
그래서 일단 원형은 살리되 local과 prod만 추가 구성 했다.
이렇게 됐을 때 application.yml의 모습 변화를 한번 보여주겠다.
Case 1. 디폴트에 로컬이 있던 yml구성
application.yml
spring:
profiles:
include:
- jwt
- oauth
- s3
active: s3
devtools:
livereload:
enabled: true
restart:
enabled: true
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/shop-project
username: root
password: root123
jpa:
database-platform: org.hibernate.dialect.MySQL8Dialect
#이하 공통셋팅
Case 2. 디폴트는 놔두고 local, prod추가 및 분리한 yml구성
application.yml
spring:
profiles:
group:
local:
- jwt
- s3
- oauth
- local
prod:
- prod
active: ${profile}
#이하 공통셋팅
application-local.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/shop-project
username: root
password: root123
jpa:
database-platform: org.hibernate.dialect.MySQL8Dialect
위 application.yml 설정에서 봤듯이 이미 s3, oauth, s3를 다 따로 만들고 그걸 application.yml에서 include하고 있기 때문에 local에는 DB정보만 담았다.
여기다 몰아서 할거면 application.yml의 include에서 세개 다 빼고 여기다 넣어주면 되겠다.
application-prod.yml
spring:
security:
oauth2:
client:
registration:
google:
client-id: ${google_client}
client-secret: ${google_secret}
redirect-uri: http://localhost:8080/login/oauth2/code/google
scope:
- email
- profile
mvc:
pathmatch:
matching-strategy: ant_path_matcher
jwt:
secret_key: ${jwt_secret}
access:
expiration: 3600000000
refresh:
expiration: 1209600000000
cloud:
aws:
credentials:
access-key: ${s3_access}
secret-key: ${s3_secret}
s3:
bucket: ${s3_bucket}
region:
static: ap-northeast-2
auto: false
stack:
auto: false
---
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${rds_mysql_url}
username: ${rds_mysql_name}
password: ${rds_mysql_secret}
jpa:
database-platform: org.hibernate.dialect.MySQL8Dialect
open-in-view: true
show-sql: true
hibernate:
ddl-auto: update
properties:
hibernate:
show_sql: true
format_sql: true
default_batch_fetch_size: 500
배포 내용의 경우는 해당 배포서버의 환경변수에다 비밀키나 기타 정보를 담는 것이 편하다고 판단하여 이렇게 설정했다. 로컬도 비슷한 방식으로 해도 무방하다. 서버에 환경변수 넣는 법은 위에서 설명했다.
추가개념)으로 --- 의 역할이 대체 뭔지 이해 못했는데 yml을 처음 만들면
spring:선언 후 탭으로 하위항목임을 나타내느냐
spring:
profiles:
include:
- jwt
- oauth
- s3
jwt:
secret_key: ${jwt_secret}
access:
expiration: 3600000000
refresh:
expiration: 1209600000000
datasource: #spring하위 항목이라 탭이 들어가있음
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/shopping_project
username: root
password: 1234
--- 구분후 spring: 하위로 구분하느냐 이다.
사실 이게 좀 더 눈으로 보기에 쉬운 건 사실이긴하다. 탭 때문에 해당 설정이 인식이 안되는 경우도 왕왕있어서.
jwt:
secret_key: ${jwt_secret}
access:
expiration: 3600000000
refresh:
expiration: 1209600000000
--- #구분자가 들어가면 새로운 파일로 취급하여
spring: #spring: 부터 선언할 수 있음
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${rds_mysql_url}
username: ${rds_mysql_name}
password: ${rds_mysql_secret}
'IT이야기 > AWS' 카테고리의 다른 글
AWS EC2서버에 SWAP 적용하기 (Linux) (0) | 2024.10.30 |
---|---|
[AWS] S3 StatusCode 301에러 해결 (0) | 2024.10.22 |
[AWS Redis] SpringBoot + Redis 설정 및 생성, EC2(AmazonLinux) 설정까지 (1) | 2024.02.13 |
[GitActions] AWS EC2로 자동 배포하기 (feat Linux) / GITAction + EC2 + CodeDeploy등을 이용한 CD (0) | 2024.01.18 |
AWS EC2인스턴스생성부터 EC2 연결까지(MAC/AmazonLinux2023) (0) | 2024.01.17 |