gradle 을 사용한 springboot 프로젝트를 CodeBuild 을 이용하여 온프레미스에 배포하고, 실행하는 방법이다.

  • springboot 정상적으로 올라와 있는지 확인하는 스크립트를 우선 작성하여 project root 에 넣어 놓는다.

#!/bin/bash
echo "> Health check 시작"
echo "> curl -s http://localhost:8080/health "

for RETRY_COUNT in {1..15}
do
  RESPONSE=$(curl -s http://localhost:8080/health)
  UP_COUNT=$(echo $RESPONSE | grep 'UP' | wc -l)

  if [ $UP_COUNT -ge 1 ]
  then # $up_count >= 1 ("UP" contains )
      echo "> Health check success"
      break
  else
      echo "> Health check unknown or not ready...."
      echo "> Health check: ${RESPONSE}"
  fi

  if [ $RETRY_COUNT -eq 10 ]
  then
    echo "> Health check fail.. "
    exit 1
  fi

  echo "> Health check connect fail to retry... "
  sleep 10
done
exit 0
  • 스프링을 실질적으로 실행하는 스크립트이다. 역시 project root 프로젝트에 만들어 놓는다.

#!/bin/bash
cd /home/myname/app
echo 'kill springboot applcation'
kill -9 `cat app.pid`      
kill -9 `$(lsof -t -i:8080 -sTCP:LISTEN)`
nohup java -jar app-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev &
sh ./healthcheck.sh
  • 실제 패스워드를 보관하고 있는 파일, CodeCommit 절대 포함 시키지 않는다. 이 파일은 S3 bucket 에 넣어 놓고 빌드할때 copy 하여 사용하도록 한다.

targetHost=xxx.xxx.xxx.xxx
targetPort=22
targetUser=myname
targetPassword=mypassword
targetDir=/home/myname/app
  • codebuild 가 수행할 yml 파일, 비공개 버킷 MY-BUCKETgradle.properties 업로드 해 놓는다.

version: 0.2

env:
  variables:
    S3_BUCKET: "MY-BUCKET"

phases:
  pre_build:
    commands:
  build:
    commands:
      - aws s3 cp s3://${S3_BUCKET}/gradle.properties .
      - chmod +x ./gradlew
      - echo unit testing ...
      - ./gradlew test
      - echo make jar ...
      - echo Build started on `date`
      - ./gradlew assemble
      - echo copy jar and startup to target server started on `date`
      - ./gradlew deploy
  post_build:
    commands:
cache:
  paths:
    - '/root/.gradle/**/*'
  • springboot project 메인 gradle, healthcheck 를 위해 org.springframework.boot:spring-boot-starter-actuator 필수로 넣는다.
  • org.hidetake.ssh 는 gradle 에서 ssh 를 사용하기 위한 필수 플러그인 이다.
  • remotes.targetServer 부분에 있는 것이 위의 gradle.properties 에 입력해 놓았다.

plugins {
    id "org.hidetake.ssh" version "2.10.1"
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
}

remotes {
    targetServer {
        host = project.properties["targetHost"]
        port = project.properties["targetPort"].toInteger()
        user = project.properties["targetUser"]
        password = project.properties["targetPassword"]
        targetDir = project.properties["targetDir"]
        knownHosts = allowAnyHosts //알 수 없는 호스트라도 접속 가능
    }
}

task deploy {
    doLast {
        ssh.run {
            println "${remotes.targetServer.host} connecting..."
            //remotes.targetServer 호스트 세션 시작
            session(remotes.targetServer) {
                put from: "${projectDir}/build/libs/${archivesBaseName}-${version}.jar", into: targetDir
                println "success to transfer ${archivesBaseName}-${version}.jar "

                put from: "${projectDir}/healthcheck.sh", into: targetDir
                println "success to transfer healthcheck.sh"
                execute "cd ${targetDir} && chmod +x healthcheck.sh"
                put from: "${projectDir}/bootstrap.sh", into: targetDir
                println "success to transfer bootstrap.sh"
                execute "cd ${targetDir} && chmod +x bootstrap.sh"
                println "success to chmod to execute bootstrap.sh"
                execute ("${targetDir}/bootstrap.sh", pty: true)
                println "success to bootstrap....."
            }
        }
    }
}
  • 중요 : bootstrap.sh 에서 healthcheck.sh를 호출해서 OK 가 완료되면 CodeBuild 이 정상 종료된다. 그렇지 않으면 CodeBuild 종료되지 않는다.