[DevOps] 스프링 부트 AWS에 배포하기

목차

  1. EC2 인스턴스 생성하기
    1. AWS 가입
    2. EC2 인스턴스 생성
  2. EC2 인스턴스에서 도커 실행
    1. 패키지 업데이트
    2. 도커 설치
    3. 도커 설치 확인
    4. 도커 실행
  3. 도커에 MySQL 서버 올리기
    1. MySQL 컨테이너 구동
    2. MySQL 컨테이너 접속
    3. MySQL 접속
    4. 사용할 DB 생성
  4. 도커에 스프링 부트 올리기
    1. 스프링 부트 컨테이너 만들기
       1.우분투 컨테이너 생성
       2. 패키지 업그레이드
       3. JRE 설치
    2. 깃허브에서 프로젝트 가져오기
       1. 깃 설치
       2. 깃 클론
    3. 데이터소스 IP 수정하기
       1. 컨테이너 IP 확인
       2. application.properties 수정
    4. 스프링 부트 프로젝트 빌드하기
    5. 서버 구동하기
  5. 브라우저에서 확인해보자
    1. 컨테이너 종료하지 않고 나가기
    2. EC2에서 나가기
    3. 브라우저에서 확인하기

이 글은 스프링 부트로 만든 프로젝트를 클라우드 환경으로 배포하는 방법을 설명한다. 도커 컴포즈 + 도커 파일 조합을 사용하면 간단하지만, 이번 실습에서는 사용하지 않는다. 사용하지 않고 얻는 교훈이 더 많기 때문이다.

이번 실습의 목표는 다음과 같다.

  1. AWS EC2 인스턴스에 도커를 설치하고, 도커 컨테이너를 구동할 수 있다.
  2. 도커 컨테이너에서 MySQL을 구동하고, 스프링 부트 애플리케이션과 연동할 수 있다.
  3. 도커 컨테이너에 JAR 파일을 복사하여 스프링 부트 서버를 구동할 수 있다.

EC2 인스턴스 생성 하기

AWS 가입

먼저, aws에 가입한다. 이 과정은 구글링으로 쉽게 완료할 수 있다.

가입 후 루트 사용자로 로그인한다.

EC2 인스턴스 생성

AWS에서 EC2 인스턴스를 생성한다. 자신이 원하는 이미지로 인스턴스를 생성하면 된다.
여기서는 Amazon Linux 2 AMI 이미지로 생성하였다.

  • Amazon Linux 2 AMI
  • Ubuntu Server 20.04 LTS
  • 프리티어는 30GB의 ssd용량이 주어진다. 이왕에 30GB로 사용하자.

보안 그룹 구성시에 인바운드 규칙은 아래와 같이 설정한다.

  • ssh : 내 IP
  • http, https : 위치 무관
  • 사용자 지정 tcp 규칙 : 8080, 위치 무관

EC2 인스턴스에서 도커 실행

패키지 업데이트

EC2 인스턴스에 접속하고, yum 패키지를 최신으로 업데이트 한다.

$ sudo su
$ yum update -y
$ yum install -y docker
Amazon Linux 2 AMI 인스턴스에서는 우분투에 비해 훨씬 간단한 설치가 가능하다.

Ubuntu 에서는 어떻게?
 - https://docs.docker.com/engine/install/ubuntu/

도커 설치 확인

$ docker -v

도커 실행

$ systemctl start docker

도커에 MySQL 서버 올리기

도커 컨테이너 내부에서 MySQL 서버를 구동하고, MySQL 서버에 접속하여 프로젝트와의 연동을 위해 DB를 생성해준다. 생성하는 DB 이름과 프로젝트의 properties에서 설정한 DB 이름은 같아야 한다.

MySQL 컨테이너 구동

$ docker run --name mysql-db -p 3306:3306 -e MYSQL_ROOT_PASSWORD=<password> -d mysql

MySQL 컨테이너 접속

$ docker exec -it mysql-db /bin/bash

MySQL 접속

$ mysql -u root -p
Enter pasword: <password>

사용할 DB 생성

mysql> create schema {DB 이름};
mysql> show databases;
{DB 이름} 은 프로젝트의 properties 에서 설정한 이름과 같아야 한다.

[properties]
 - spring.datasource.url=jdbc:mysql://localhost:3306/{DB이름}?serverTimezone=UTC&characterEncoding=UTF-8

도커에 스프링 부트 올리기

MySQL을 도커 컨테이너에 올려서 구동했던 것과 같이 스프링 부트 프로젝트도 도커 컨테이너에 올려서 구동하면 된다. 방법은 여러가지가 있는데 핵심은, 프로젝트 빌드 산출물인 jar 파일을 java 환경이 구축된 서버에서 구동시키는 것이다.

다음은 jar 파일을 도커 컨테이너로 옮기는 두 가지 방법이다.

  1. jar 파일을 sftp 를 사용하여 EC2로 옮기고, EC2에서 도커 컨테이너 내부로 복사하여 구동
  2. 도커 컨테이너에 git을 설치하고 github에서 소스파일을 클론받아 빌드한 뒤 jar 파일 구동

git 을 활용하는 방법은 추후 CI/CD 에 유리하다. 따라서 git 을 활용한 방법으로 진행할 것이다.

스프링 부트 컨테이너 만들기

스프링 부트 서버를 구동하기 위해 우분투 컨테이너를 만들고, 컨테이너에 java11  런타임 환경을 구성할 것이다. 도커 허브에 올라가있는 java 이미지를 이용하면 편하지만, 구성하려는 java 버전이 허브에 없을 수도 있기 때문에 직접 구성해보는 것이 좋다.

우분투 컨테이너 생성

$ docker run -it --name springboot-server -p 8080:8080 ubuntu /bin/bash

패키지 업그레이드

$ apt-get update -y && apt-get upgrade -y

JRE 설치

프로젝트 빌드 및 jar 파일 구동을 위한 자바 런타임 환경(jre)를 설치한다.
프로젝트에 맞는 버전으로 설치한다.

$ apt-get install -y openjdk-11-jre

깃허브에서 프로젝트 가져오기

깃 설치

깃을 통해 프로젝트 소스를 컨테이너 내부로 가져온다.

$ apt-get install -y git

깃 클론

적당한 경로에 클론한다.

$ git clone https://github.com/heoseongh/moamoa-server.git /home/springboot
...
Username for 'https://github.com': 아이디
Password for 'https://heoseongh@github.com': 비밀번호
...
git clone {레포지터리 주소} {경로}/{레포지터리이름} 형식으로 입력하면 원하는 경로에 원하는 레포지터리명으로 가져올 수 있다.

클론한 프로젝트 디렉토리에 들어가보면 아래와 같은 디렉토리 구조를 볼 수 있다.
아래 파일들이 모두 존재해야 빌드할 수 있다.

root@3f252f5f2342:/home/moamoa/moamoa-server# ls -l
drwxr-xr-x 9 root root  141 Apr 13 11:46 build/
-rw-r--r-- 1 root root 1201 Apr 13 11:31 build.gradle
drwxr-xr-x 3 root root   21 Apr 13 11:31 gradle/
-rwxr-xr-x 1 root root 5766 Apr 13 11:31 gradlew*
-rw-r--r-- 1 root root 2674 Apr 13 11:31 gradlew.bat
-rw-r--r-- 1 root root   28 Apr 13 11:31 settings.gradle
drwxr-xr-x 4 root root   30 Apr 13 11:31 src/

데이터소스 IP 수정하기

데이터소스 URL 호스트를 MySQL 컨테이너의  ip 로 설정한다.
빌드시 DB 연동 에러가 발생한다면, 데이터소스 URL 호스트를 localhost 로 설정한 것은 아닌지 확인한다. localhost 로 설정한 경우, 스프링 부트 컨테이너는 자기 자신을 가리키므로 MySQL과 연동되지 않는다. 따라서, MySQL이 구동 중인 컨테이너의 IP를 사용하여 데이터소스 URL  호스트를 설정해야 한다.

컨테이너 IP 확인

$ docker inspect mysql-db | grep IPAddress
...
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
...

필자의 MySQL 컨테이너 ip는 172.17.0.2 이다.

application.properties 수정

$ vi {프로젝트 디렉터리}/src/main/resources/application.properties
...
spring.datasource.url=jdbc:mysql://{컨테이너IP}:3306/moamoa2?serverTimezone=UTC&characterEncoding=UTF-8
...

스프링 부트 프로젝트 빌드하기

gradlew 파일이 존재하는 디렉터리로 이동하여 빌드를 수행한다.

$ ./gradlew build
...
BUILD SUCCESSFUL in 33s
...

빌드 중에 필자가 겪었던 2가지 에러와 해결 방법을 링크한다.
에러 없이 잘 진행되었다면, 다음 step으로 넘어간다.

  1. 메모리 부족현상 : swap 공간 확보로 해결
     - [Troubleshooting] AWS EC2 스프링 부트 빌드시 용량 부족 문제 (Not enough space) 해결
  2. 테스트 실패 : properites 에서 datasource.url 확인
     - [AWS-EC2] 도커에서 스프링 부트 빌드시 테스트 실패]

서버 구동하기

빌드에 성공하면 build 디렉터리가 생성된다. 그리고 build > libs 디렉터리 안에 jar 파일이 생성된다. 이 jar 파일을 실행하면 스프링 부트 서버가 구동된다.

$ java -jar ./build/libs/testproject.jar &
 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.4.4)

서버를 구동한 채로 도커 컨테이너에서 빠져나오려면, jar 구동 명령어 마지막에 & 를 추가하여 백그라운드에서 실행시켜야 한다.

브라우저에서 확인해보자

이제 스프링 부트 서비스 배포가 완료되었다.
도커 컨테이너와 EC2 인스턴스에서 빠져나온 뒤, 브라우저나 모바일에서 애플리케이션에 접속해보자.

컨테이너 중단 없이 빠져나오기

ctrl+p + ctrl+q  키를 눌러 컨테이너에서 빠져나온다.

ctrl+c 명령으로 나가면 컨테이너 자체가 내려가기 때문에
안에서 구동중인 스프링 부트 서버도 함께 종료된다.

EC2에서 나가기

exit 명령으로 EC2 쉘에서 빠져나온다.

도커를 사용하지 않고 EC2에서 모든 환경을 구축했다면,
nohub java -jar ./build/libs/testproject.jar & 명령어를 실행한 후
exit 명령어를 사용해서 쉘에서 나올 수 있다.

브라우저에서 확인하기

브라우저에서 {EC2 퍼블릭 IP}:8080 으로 접속하면 스프링 부트 서버에 접속할 수 있다. 만약 접속이 되지 않는다면, EC2 인스턴스의 인바운드 규칙에서 8080 포트가 열려 있는지 확인한다.