[AWS] EC2에 mysql 설치 및 스프링 애플리케이션 배포하기 (scp 파일 전송 & 배포 스크립트 작성)
이 글을 참고했다.
1. EC2 우분투에 mysql 설치
mysql 설치
$ sudo apt update
$ sudo apt-get install mysql-server
mysql 접속
$ sudo /usr/bin/mysql -u root -p
패스워드를 설정했으면 입력하고, 없으면 그냥 엔터를 누른다.
ERROR 1698 (28000)
처음에 $ sudo mysql -u root -p 로 진행했더니 아래와 같은 에러가 발생했다.
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
해결방법: mysql 대신 /usr/bin/mysql 과 같이 경로를 정확하게 명시해주면 된다.
참고
이 블로그를 참고했다.
mysql 사용자 설정
mysql> create user 'root'@'%' identified by '비밀번호';
mysql> flush privileges;
이후 sudo mysql -u root -p
커맨드로 접속 시 설정한 비밀번호를 입력해야한다.
특정 ip 에서만 접속을 허용하고 싶다면?
create user 'root'@'ip주소' identified by '비밀번호';
로 입력한다.
mysql 사용자 확인
mysql> use mysql;
mysql> select user, host, authentication_string from user;
mysql 사용자에 권한 부여
mysql> grant all privileges on *.* to 'root'@'%';
특정 데이터베이스, 테이블 및 특정 ip에만 접속 가능한 사용자일 경우?
grant all privileges on 데이터베이스명.테이블명 to '사용자명'@'ip주소';
mysql 외부접속 허용
exit
명령어로 mysql 에서 나간 뒤 우분투에서 아래 커맨드를 입력한다.
$ cd /etc/mysql/mysql.conf.d # 디렉토리 이동
$ ls # 파일 확인
$ sudo vi mysqld.cnf
열린 문서에서 bind-address
부분을 0.0.0.0
으로 변경한다.
mysqlx-bind-address
도 0.0.0.0
으로 변경한다.
(혹은 맨 앞에 #
을 넣어 주석처리 한다.)
확인하기
netstat -p tcp -van | grep LISTEN | grep 3306
위 사진처럼 0.0.0.0:3306
이어야 한다. 127.0.0.1
이 아닌지 확인한다.
mysql 재시작
$ sudo service mysql restart
2. EC2의 mysql과 Spring Boot 애플리케이션 연결하기
mysql에 데이터베이스 생성하기
# default 이라는 데이터베이스를 생성하고 한글을 사용할 수 있는 UTF8로 문자열을 저장
mysql> create database naem default CHARACTER SET UTF8;
mysql> show databases; # 데이터베이스 확인
application.yml
파일 작성
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://[EC2_IP주소]:3306/naem?serverTimezone=Asia/Seoul&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: 아까 설정한 패스워드
jpa:
hibernate:
ddl-auto: update
properties:
hibernate:
globally_quoted_identifiers: true
format_sql: true
dialect: org.hibernate.dialect.MySQL8Dialect
3. swapfile 생성하기 - 내가 추가한 것
배포시 중단되는 문제를 예방하기 위해 swapfile 을 할당했다.
이 글을 참고했다.
4. EC2 서버에 Spring Boot jar 파일 배포하기
ec2 인스턴스로 jar 파일 전송
scp
커맨드를 이용해서 Local->Remote
로 jar 파일을 전송할 것이다.
인텔리제이 터미널로 아래 커맨드를 실행한다.
$ ./gradlew build jar -x test # 테스트 코드 제외하고 빌드
# scp -i "pem파일경로" jar파일명 ec2사용자이름@ec2퍼블릭Ipv4DNS:~/경로
$ scp -i "/Users/minju/study/Naem/second-keypair.pem" build/libs/server-0.0.1-SNAPSHOT.jar ubuntu@ec2-**-***-**-***.ap-northeast-2.compute.amazonaws.com:~/ # 생성된 jar 파일을 ec2 서버로 전송
이때 pem파일경로
는 pwd
커맨드로 알아낼 수 있다.
폴더를 전송하는 방법은 여기를 참고하자.
ec2에 접속해 전송된 jar 파일 확인
전송된 jar 파일 실행(=배포)
$ java -jar server-0.0.1-SNAPSHOT.jar
java가 설치되어 있지 않아서 에러가 발생했다.
java 11을 설치해보자.
java 11 설치
$ sudo apt-get install openjdk-11-jdk
환경설정
자바 설치가 끝나면 환경변수를 설정해야 한다. 먼저 java 위치를 확인한다.
$ which java
$ readlink -f /usr/bin/java
다음 명령어를 실행했을 때, 나는 /usr/lib/jvm/java-11-openjdk-amd64/bin/java
이렇게 나오는데,
뒤에 /bin/java
만 제거하고 앞부분까지만 복사한다.
복사한 뒤에, 아래 명령으로 환경설정 파일인 profile을 열어준다.
$ sudo vi /etc/profile
그럼 이런 파일이 나오는데, 위와 같이 맨 아래 3줄을 추가해주면 된다.
해당 작업이 끝난 뒤, 업데이트를 위해 아래 명령어를 입력한다.
$ source /etc/profile
마지막으로 환경변수가 잘 세팅 되었는지 확인한다.
$ echo $JAVA_HOME
이 명령어를 쳤을 때, 아까 복사해준 위치가 나타나게 된다면 성공이다.
참고
Trouble Shooting
시도1 - mysql user 생성 후 권한 부여
$ mysql -u root -p; // mysql 접속
mysql> use mysql; // mysql db 사용
mysql> select host, user from user; // user 조회
mysql> create user root@***.**.*.* identified by '비밀번호'; // 계정 생성
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'***.**.*.*'; // 권한 부여
mysql> flush privileges; // 메모리에 반영
mysql> show grants for root@***.**.*.*; // 권한 확인
시도2 - 방화벽 확인
$ sudo ufw status
# inactive 로 방화벽은 꺼져있었다.
# 만약 켜져있었다면 sudo ufw disable 로 끌 수 있다. (켜는건 enable)
시도3 - 연결 url에 퍼블릭 IPv4 DNS 사용 [해결!!!]
기존에는 퍼블릭 IPv4 주소
를 사용했는데 이를 퍼블릭 IPv4 DNS
로 바꿨더니 해결되었다…
# 기존
spring:
datasource:
url: jdbc:mysql://**.***.**.***:3306/naem?serverTimezone=UTC&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
# 변경
spring:
datasource:
url: jdbc:mysql://ec2-**-***-**-***.ap-northeast-2.compute.amazonaws.com:3306/naem?serverTimezone=UTC&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
5. 배포 스크립트 작성 및 무중단 배포
이 글의 5번 내용을 참고했다.
배포 스크립트를 이용해 배포 과정을 줄이고, 무중단 배포를 해보자.
배포 스크립트 작성
$ vi deploy.sh
echo "> 기존 실행되던 파일 종료"
kill $(lsof -t -i:8080)
echo "> 새 애플리케이션 배포"
nohup java -jar \
-Dspring.profiles.active=prod \
-Dspring.datasource.url='jdbc:mysql://ec2-**-***-**-***.ap-northeast-2.compute.amazonaws.com:3306/naem?serverTimezone=UTC&characterEncoding=UTF-8' \
-Dspring.datasource.username='root' \
-Dspring.datasource.password='비밀번호' \
server-0.0.1-SNAPSHOT.jar &
아까 실행시킬 때 수행했던 명령어 앞에 nohup
을 붙이고, 뒤에 &
을 붙이면 백그라운드에서 실행이 되어, 터미널을 종료해도 ec2상에서는 계속 돌아간다.
nohup java -jar server-0.0.1-SNAPSHOT.jar & > /dev/null
처럼 맨 뒤에 > /dev/null
은 log를 저장하지 않겠다는 뜻이고,
nohup java -jar server-0.0.1-SNAPSHOT.jar &
처럼 설정하지 않으면 nohup.out
으로 저장된다고 한다.
배포 스크립트 실행
$ chmod +x ./deploy.sh # 권한 부여
$ ./deploy.sh
소스코드 변경 후 다시 배포할 때는!!
# 로컬 터미널에서
$ ./gradlew build jar -x test
$ scp -i "/Users/minju/study/Naem/second-keypair.pem" build/libs/server-0.0.1-SNAPSHOT.jar ubuntu@ec2-**-***-**-***.ap-northeast-2.compute.amazonaws.com:~/
# 우분투에서
$ ./deploy.sh
- 이 방법은 application.yml을 gitignore하지 않아도 되지만, 환경변수가 변경될 때 배포서버 실행 명령어를 수정해주어야 한다는 단점이 존재한다.
- 매번 수정해주지 않아도 되는 방법 (대신 application.yml은 gitignore) 역시 존재한다.
프로세스를 중단하고 싶다면?
# 실행중인 자바 프로세스 확인
$ ps -ef | grep java # 조회된 내역에서 첫번째 5자리 숫자가 해당 프로세스의 PID이다.
# 실행중인 자바 프로세스 종료
$ kill -9 PID번호
💛 개인 공부 기록용 블로그입니다. 👻