ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • AWS EC2에 스프링부트 프로젝트 배포하기
    프로젝트/게시판 프로젝트 2022. 6. 14. 02:38

    AWS 가입 및 EC2 인스턴스 생성(1)

    EC2 자바 11 설치 및 타임존 설정(2)

    AWS RDS 구축하기(3)

    AWS EC2에 스프링부트 프로젝트 배포하기(4)

     

    현재 RDS와 EC2를 모두 구축해 놓은 상황입니다.

    깃허브에서 코드를 받아올 수 있게 EC2에 Git을 설치합니다.

     

    1. putty를 통해 EC2에 접속하여 git --version 명령어를 입력합니다.

    현재 git이 설치되어 있지 않습니다.

     

    2. sudo yum install git 명령어로 git 설치

    이제 git이 설치되었습니다.

     

    3. git clone으로 프로젝트를 저장할 디렉터리 생성

    mkdir ~/app && mkdir ~/app/step1

     

    ls 명령어로 디렉토리가 잘 생성되었는지 확인할 수 있습니다.

     

    만약 잘못 생성해서 다시 생성하고 싶다면 다음 명령어를 입력하세요

    rm -rf app

     

    생성된 디렉터리로 이동합니다.

    cd ~/app/step1

     

    4. 본인의 github 웹페이지에서 https 주소를 복사합니다.

    github 웹페이지 주소

    git clone 복사한 주소

     

    git clone https://github.com/SW-Anthill/Anthill-BackEnd-JW.git 

     

    git clone 성공

     

    ll 명령어를 통하여 파일이 잘 복사되었는지 확인합니다.

    ll 명령어 설명

    ls 란 해당 디렉토리에 존재하는 파일목록을 표시합니다.

    ll 이란 ls 명령어에 -l 옵션을 준 형태이다. (참고로, -l 옵션은 long 옵션으로 상세히 출력하라는 의미입니다.)

    폴더들이 많아서 조금 더 들어간 후 프로젝트의 코드들이 모두 있는 것이 확인되었습니다.

     

     

    5. 코드들이 잘 수행되는지 테스트로 검증

     

    ./gradlew test

     

    local에서는 터미널에 ./gradlew test를 입력했을 때 정상적으로 잘 동작했습니다.

     

    하지만 AWS EC2에서는 환경이 조금 다를 것으로 예상됩니다.

     

    5-1. local에서의 자바버전은 16을 사용했습니다.

    즉, build.gradle 에 sourceCompatibility = '16'으로 설정되어 있을 것입니다.

    하지만 amazon linux ec2 서버에는 자바 11 버전이 설치되어 있습니다.

    즉, 16을 11로 수정해주어야 합니다.

     

    5-2. 자바버전으로 인해 발생하는 사이드 이펙트

    11 버전보다 높은 상위 버전에 종속적인 클래스들을 사용했다면 컴파일 에러가 발생할 수 있습니다.

     

    5-3. DB Connection 문제

    Local MySQL에서 SpringBoot와 연동했기 때문에 datasource.url, username, password 등이 모두 로컬 기준으로 설정되어있습니다.

     

    이를 RDS 기준으로 변경해주어야 합니다.

     

    에러가 날 것 같다고 생각하지만 우선 ./gradlew test 명령어를 수행해보겠습니다.

    Permission denined

    권한이 없다는 메시지가 떴습니다.

     

    다음 명령어로 실행 권한을 추가한 뒤 다시 테스트를 수행합니다.

     

    chmod +x ./gradlew

     

    chmod 명령어는 파일의 모드를 변경하는 명령어입니다.

    +x 는 실행할 수 있다는 의미인 executable을 의미합니다.

     

    즉, 위의 명령어는 ./gradlew 파일에 실행할 수 있는 권한을 준다는 의미입니다.

     

    이제 다시 명령어를 입력해보겠습니다.

     

    ./gradlew test

     

    열심히 빌드를 하다가 다음과 같은 에러를 뱉습니다.

    EC2에는 자바버전이 11이고 코드상에서는 16으로 설정되어있으니 예상된 에러입니다.

     

    vi build.gradle

     

    위의 명령어로 build.gradle 파일을 편집합니다.

    16 -> 11로 수정하였습니다.

    테스트가 정상적으로 수행되었습니다.

    DB 설정을 변경하지 않았는데 어떻게 테스트가 정상적으로 수행될까요?

    test시에 사용하는 test용 application.properties설정으로 테스트는 H2 인메모리로 수행되기 때문에 영향을 받지 않습니다.

     

     

    6. 배포 스크립트 만들기

    작성한 코드를 실제 서버에 반영하는 것을 배포라고 합니다.

    배포라 하면 다음의 과정을 모두 포괄하는 의미입니다.

    - git clone 또는 git pull을 통해 새 버전의 프로젝트를 받음

    - Gradle이나 Maven을 통해 프로젝트 테스트와 빌드

    - EC2 서버에서 해당 프로젝트 실행 및 재실행

     

    위의 과정을 배포할 때마다 개발자가 하나하나 명령어를 실행하는 것은 불편함이 많습니다.

    따라서 이를 쉘 스크립트로 작성해 스크립트만 실행하면 앞의 과정은 차례대로 진행되도록 하겠습니다.

     

    쉘 스크립트란?

    .sh라는 파일 확장자를 가진 파일로 노드JS가 .js라는 파일을 통해 서버에서 작동하는 것처럼 쉘 스크립트는 리눅스에서 기본적으로 사용할 수 있는 스크립트 파일의 한 종류입니다.

     

    즉, 리눅스 명령어들을 조합해서 만들어 놓은 파일으로 한 줄씩 순차적으로 읽으면서 운영체제의 Shell을 이용하여 명령어들을 한줄씩 실행시켜주는 인터프리터 방식의 프로그램입니다.

     

    위의 경로에 deploy.sh을 생성하겠습니다.

     

    vim deploy.sh

    무조건적으로 따라 치기보다는 프로젝트의 경로를 잘 생각하시면서 작성하셔야 합니다.

     

     

    이제 이 스크립트를 다음 명령어로 실행합니다.

    ./deploy.sh

     

    nohup.out  파일을 vim nohup.out 명령어로  열어보면 스프링 부트가 정상적으로 뜨려다가 mysql Connection 문제로 에러가 발생하게 됩니다.

     

    아까 5-3에서 예상한 에러가 발생한 것 같습니다.

     

    application.properties는 Local기준으로 작성되어 있습니다.

    여기서 수정되어야 할 점은 다음과 같습니다.

    datasource.url = jdbc:mysql://rds주소:포트명(기본은3306)//데이터베이스이름

    datasource.username = db계정

    datasource.password =  db계정 비밀번호

     

    주의할 점

    AWS 환경에서 show-sql을 할 필요가 없으니 false로 설정해주어야 성능상 이점이 있을 것 같습니다.

    또한 실제 배포 환경에서는 RDS에서 따로 테이블을 생성해주는 과정을 거친 후 ddl-auto = none으로 설정해주어야 합니다.

     

    위의 url,username,password 세팅 빼고는 그대로 두었습니다.

     

     

    이제 다시 ./deploy.sh 명령어를 실행하겠습니다.

     

    다음과 같은 오류가 발생했습니다.

     

    build를 하면 다음과 같이 .jar 파일이 2개 만들어졌습니다.

    두 파일의 차이점은 plain에 있습니다.

     

    Jar에 의해 생성된 jar는 plain archive라고 하며 어플리케이션 실행에 필요한 모든 의존성을 포함하지 않고 소스코드의 클래스 파일과 리소스 파일만 포함하고 있습니다.

     

    즉, java -jar 명령어로 제대로 실행되지 않습니다.

     

    BootJar에 의해 생성된 jar는 Executable archive라고 하며 모든 의존성과 함께 빌드하기 때문에 java -jar 명령어로 실행할 수 있습니다.

     

     

    이를 개선하기 위해서 build.gradle에 다음과 같은 코드를 추가하면 됩니다.

    jar {
        enabled = false
    }

     

    다시 ./deploy.sh 를 시도해 보아도 여전히 같은 오류가 발생합니다.

    ./deploy.sh를 분석해보면 build 파일을 복사하는 부분이 존재합니다.

    즉, 여기서 build/libs로 이동하여 jar파일을 모두 지운 후 다시 ./deploy.sh를 실행하면 오류가 해결됩니다.

     

     

    드디어 EC2에 정상적으로 스프링이 구동되었습니다.

     

    이후 curl localhost:8080 명령어를 입력했을 때 html 코드가 정상적으로 보이거나 REST API를 제공하는 Server라면  다음과 같은 메시지가 보이면 성공입니다.

     

    이제 직접 브라우저를 통하여 접근하겠습니다.

    이전에 EC2에 스프링 부트 프로젝트가 8080 포트로 배포되어있으니 8080포트가 보안그룹에 열려 있는지 확인합니다.

    없다면 추가해주세요

     

     

    저 같은 경우에는 REST API를 제공하는 서버지만 rest docs를 만들어 두어서 도메인주소:8080/docs/index.html으로 접근했을 때 문서가 정상적으로 보였습니다.

     

    추가적으로 포스트맨으로도 만든 API들을 테스트해보겠습니다.

    포스트맨까지 정상적으로 완료되었습니다

    불편한 점

    Local에서는 Java 16 AWS에서는 Java 11 버전을 사용하기 때문에 매번 build.gradle의 Java버전을 변경해주어야 한다.

    application.properties가 Github에서는 Local기준으로 작성되어 있기 때문에 매번 RDS기준으로 변경해주어야 한다.

     

    위의 작업 또한 가능하다면 deploy.sh를 통해 자동화하고 싶습니다.

     

    추후 도입하면 좋을 점

    + CI/CD작업을 통해 Github에 코드를 push하는것만으로 배포가 되도록하기

    + Nginx를 통한 무중단배포

     

    댓글

Designed by Tistory.