나 JAVA 봐라

DockerHub를 통해 EC2에 Spring boot, mysql 올리기 본문

DevOps, MLOps

DockerHub를 통해 EC2에 Spring boot, mysql 올리기

cool_code 2024. 6. 5. 00:11

현재 Spring Boot와 MySQL을 통해 로컬 환경에서 프로젝트를 진행하고 있습니다. 개발이 얼추 마무리됨에 따라, AWS에 배포를 진행하기로 했습니다.

찾아보니 배포하는 방법도 다양했는데, 그 중 아래의 두 가지 방식을 고민했습니다.

  1. Spring Boot 프로젝트는 Amazon S3에 올리고, DB는 Amazon RDS를 사용하여 EC2에 연결하기
  2. Spring Boot, Mysql 둘 다 Docker Container로 EC2에 띄우기

로컬 환경에서 MySQL를 도커 컨테이너로 띄워 사용 중이었기 때문에 배포도 2번 방법에 따라 Docker를 사용하기로 했습니다 !

그래서 오늘은

  1. 어떻게 SpringBoot 프로젝트를 Docker Image로 만들고
  2. 어떻게 만든 Image를 DockerHub에 업로드하고
  3. 어떻게 EC2 인스턴스에서 해당 Image를 pull 받아 컨테이너로 실행하는지

에 대해 작성해보겠습니다.


선행될 것

  • EC2 인스턴스 생성
  • 생성한 인스턴스에 탄력적 IP 할당
  • 정상적으로 작동하는 Spring Boot 프로젝트

1. 로컬 터미널에서 EC2 인스턴스 접속하기

먼저 생성해둔 EC2 인스턴스를 로컬 터미널에서 접속해보겠습니다.

접속할 인스턴스를 체크하여 인스턴스 연결 버튼 클릭합니다.

 

 

SSH 클라이언트를 클릭하여 하단의 명령어를 복사합니다. (copy 아이콘 클릭)

 

인스턴스를 생성할 때 함께 생성되어 로컬에 .pem 비밀키가 저장되었을텐데요,

로컬 터미널에서 해당 .pem 비밀키가 있는 디렉토리로 이동하여 복사한 명령어를 붙여넣기합니다.

아래와 같이 뜬다면 성공입니다 !

 

 

만약 pem 관련하여 아래와 같은 권한 에러 발생 시,

(원인: 키파일이 너무 많은 권한을 갖고 있어서 SSH가 거부하고 있는 것으로 보입니다.)

Warning: Permanently added 'ec2-3-27-85-133.ap-southeast-2.compute.amazonaws.com' (ED25519) to the list of known hosts.

권한을 바꿔준 후 다시 명령어 사용하면 인스턴스에 접속할 수 있습니다.

chmod 400 [비밀키 이름].pem

접속 후 인스턴스에 있는 모든 패키지를 업데이트 합니다.

sudo yum update -y

2. EC2에 Docker 설치하기

다음으로는 Docker로 프로젝트를 배포하기 때문에 EC2에 Docker를 먼저 설치하겠습니다.

아래의 명령어로 Docker를 설치합니다.

sudo yum install docker -y

설치한 Docker의 버전을 확인해볼 수 있습니다.

docker -v

아래의 명령어로 Docker를 실행합니다.

sudo service docker start

사용자의 권한을 관리자 권한으로 바꾸어 Docker 그룹에 추가합니다.

이렇게 함으로써 Docker를 사용할 때 번거롭게 sudo를 사용하지 않을 수 있습니다.

sudo usermod -aG docker ec2-user

이렇게 하여 EC2에 Docker를 설치했습니다!

앞으로 Docker Image를 EC2에 생성할 수 있게 되었습니다.


EC2 swap

스왑 파일을 사용하여 Amazon EC2 인스턴스의 스왑 공간으로 메모리 할당


3. Docker Image로 EC2에 MySQL 설치하기

버전을 지정해주지 않으면 가장 최근의 MySQL 버전이 설치됩니다.

docker pull mysql

다운로드 된 Docker Image를 확인할 수 있습니다.

아래의 명령어를 입력하여 이미지를 조회하면, REPOSITORY에 mysql , TAG에 latest가 보입니다. (최신 버전으로 설치할 경우)

docker images

이제 다운 받은 이미지를 컨테이너로 생성하고 실행할텐데요,

바로 실행하기 전 컨테이너에 볼륨을 mount 하기 위해 볼륨을 먼저 생성하겠습니다.

컨테이너에 볼륨을 mount 해주면 컨테이너가 종료된 후에도 실행된 데이터를 유지할 수 있습니다.

create 뒤에 원하는 볼륨의 이름을 지정하여 볼륨을 생성합니다.

docker volume create [볼륨 이름]

볼륨이 잘 생성되었는지 확인할 수 있습니다.

docker volume ls

새로 생성할 mysql 컨테이너에 -v 옵션을 추가하여 볼륨을 mount 합니다.

참고로 컨테이너 내부에서 /var/lib/mysql는 일반적으로 MySQL이 데이터베이스 파일과 데이터 디렉터리를 저장하는 기본 경로라고 합니다!
아래의 명령어를 통해 컨테이너를 생성, 실행할 수 있습니다.

docker run --name [컨테이너 이름] -e MYSQL_ROOT_PASSWORD=[패스워드] -d -p [포트번호] -v [볼륨 이름]:/var/lib/mysql mysql:[이미지 태그]

잘 생성되었는지 확인하기 위해 실행 중인 Docker 컨테이너 리스트를 확인할 수 있습니다.

docker ps -a

생성된 mysql container에 터미널로 접근해보겠습니다.

bash로 생성한 mysql-container에 접근 후, 패스워드 입력하여 접속합니다.

아래의 명령어를 순차적으로 입력하면 Enter password가 뜨는데, 컨테이너를 생성할 때 설정해둔 패스워드를 입력하면 접속할 수 있습니다.

docker exec -it mysql-container bash

mysql -uroot -p

4. EC2에 띄운 mysql를 workbench로 연결하기 (필수 아님)

EC2에 띄운 mysql을 터미널로 확인하기에는 너무 귀찮고, 데이터가 많아질 경우 터미널은 더욱더,,, 어지러울 것입니다. 따라서 데이터를 쉽게 보기 위해 생성한 mysql container를 MySQL workbench에 연결하겠습니다.

 

먼저 workbench가 깔려있지 않다면 다들 로컬에 MySQL workbench를 설치해주세요!

 

workbench에 접속한 후, MySQL Connections 옆 + 버튼을 누르면 새로운 Connection을 설정할 수 있습니다. Connection Name과 Hostname, Port, Username, Password를 입력합니다.

Hostname의 경우 생성한 EC2 인스턴스의 퍼플릭 IPv4 DNS를 입력합니다. (아래의 이미지를 참고하시면 좋을 것같아요!)

 

Password로 Store in Keychain 클릭 후, 컨테이너 생성 시 설정한 비밀번호를 입력합니다.

다 입력이 되었다면 Test Connection을 눌러서 연결이 잘 되는지 확인하고 OK 버튼을 누르면 연결 작업은 끝납니다.


5. EC2에 띄운 MySQL과 로컬의 프로젝트를 연동하기

이제 로컬의 프로젝트도 EC2에 올려야하는데요, 그 전에 프로젝트가 기존 로컬 DB와 연결되어있기 때문에 프로젝트의 application.yml 파일 중 datasource 부분을 EC2의 MySQL과 연결되도록 수정합니다.

저는 아래와 같이 파일을 수정했습니다.

spring:
  datasource:
    url: jdbc:mysql://3.36.181.132:3306/teach_me?useSSL=false&useUnicode=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: [비밀번호]

6. 로컬의 Spring Boot 프로젝트의 jar를 생성하기 (로컬 터미널에서 진행)

먼저 로컬 프로젝트 내부에 Dockerfile을 생성합니다.

저는 간단하게 파일을 작성했는데, 이 때 DockerFile의 파일 위치는 아래와 같은 경로에 위치해야 합니다.

 

먼저할 것들

  • 프로젝트 내부에 dockerfile 생성
  • jar 파일로 빌드하기
  • 도커 허브 로그인하기

이제 jar 파일 빌드하겠습니다. 프로젝트에 테스트코드가 많이 완성되지 않았기 때문에 먼저는 테스트 없이 빌드하겠습니다!

./gradlew clean build -x test

다음은 jar 파일을

Docker Hub login하기 → DockerHub에 이미지 업로드 하기 위함.

-u 뒤에 본인의 아이디를 입력한다.

docker login -u myid

로컬 터미널에서 생성한 jar 파일을 dockerhub에 올리기 위해 이미지를 생성한다.

dockerhub에서의 id:이미지명

docker build -t myid/boot-teachme . --platform=linux/amd64

DockerHub에 push한다.

docker push myid/boot-teachme

EC2 에서 DockerHub에 있는 프로젝트 이미지를 다운로드 받기

push한 이미지를 EC2에서 pull 한다.

docker pull yejinsong/boot-teachme

컨테이너 생성하고 실행한다.

docker run --name boot-teachme -p 8080:8080 -v /path/to/host/data:/var/lib/mysql --rm yejinsong/boot-teachme

실제 실행에 필요한 명령어 모음

MySQL Docker 컨테이너를 생성하고 실행한다. (일단은 1234로 설정)

docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=[패스워드] -d -p 3306:3306 mysql:latest