not-a-gardener 개발기 10) Jenkins: 빌드/배포 자동화

메밀·2023년 8월 10일
0

not-a-gardener

목록 보기
10/13
post-thumbnail

1. 들어가며

EC2의 jenkins에서 github push 트리거를 사용해서 배포하려다, '나 혼자 만들어서 배포하는 건데 굳이 github의 소스를 내려받을 필요가 있을까?'라는 생각이 들었다. 결국 로컬의 jenkins를 사용해 배포하기로 결정했다. 고로, 이 포스팅은

  1. 이 포스팅은 로컬 젠킨스에서 로컬 소스를 사용하여,
  2. Spring boot와 react를 하나의 jar 파일로 빌드하고,
  3. 이를 원격지에 배포하는 과정을 다룹니다.

2. Jenkins

젠킨스 다운로드와 계정 설정은 마쳤다는 가정하에 진행하며, Declarative 문법을 사용하였다.

1) project build

대시보드 > 새로운 아이템 > Freestyle Project > 생성

이후 General 설정에서 Pipeline > Definition > Pipeline script를 선택하고, 다음과 같은 스크립트를 입력한다.

pipeline{
    agent any
    tools {nodejs "node18"}
    
    stages{
        stage('build-react'){
            steps {
                echo '>>>>> building the react application...'
                
                sh """
                    cd /Users/equator/IdeaProjects/garden/front-end
                    
                    echo '>>> npm version'
                    npm --version
                    
                    npm install
                    npm run build
                """
            }
            
            post{
                success {
                    echo 'build success!'
                }
            }
        }
        
        stage('build-spring-boot'){
            steps {
                echo '>>>>> jar build'
                sh """
                    cd /Users/equator/IdeaProjects/garden
                    ls
                    ./gradlew clean build
                """
            }
        }
        
        stage('move jar file'){
            steps {
                echo '>>> move jar file'
                sh """
                mv /Users/equator/IdeaProjects/garden/build/libs/garden-0.0.1.jar /Users/equator/.jenkins/workspace/publish/garden-0.0.1.jar
                cd /Users/equator/.jenkins/workspace/publish
                ls -a
                """
            }
        }
    }
}

- stage('build-react')

# react 소스가 있는 디렉토리로 이동
cd /Users/equator/IdeaProjects/garden/front-end

# 로컬이니 npm은 다운로드 되어있지만 괜히 한 번 확인
echo '>>> npm version'
npm --version

# package.json의 의존성 다운로드
npm install

# 리액트 빌드
npm run build

- stage('build-spring-boot')

cd /Users/equator/IdeaProjects/garden
./gradlew clean build

gradlew로 jar를 빌드한다.
build.gradle에서는 build-react 스테이지에서 빌드한 결과물을 /resource/static 디렉토리로 이동시킨다.

task copyWebApp(type: Copy) {
	from "$frontDir/build"
	into "$projectDir/src/main/resources/static"
	println("copyWebApp")
}

참고로 build-react 스테이지의 스크립트는 원래 gradle 빌드 스크립트의 일부였는데, 어째서인지 jenkins에서 ./gradlew clean build를 실행하는 것만으로는 리액트 빌드가 제대로 실행되지 않아 파이프라인 스크립트로 옮겼다.

왜 거기선 안되고 여기선 되는지는 아직도 의문이다...


아무튼 여기까지 했으면 하나의 jar 파일로 react와 spring boot를 함께 빌드하는 것에 성공한 것이다.

- stage('move jar file')

코드는 생략한다.
/build/libs의 완성된 jar 파일을 publish 프로젝트의 디렉토리로 이동한다.


2) project publish

원격지의 컴퓨터로 jar 파일을 보내는 과정이다.

- Publish Over SSH plugin 다운로드

publish_over_SSH

Plugin Manager에서 Publish Over SSH 플러그인을 설치한다.

- Publish Over SSH 설정

Jenkins 관리 > 시스템 설정 > Publish Over SSH 탭 > 추가 버튼

publish_over_ssh_setting

  • Name: 이름 하나 지어준다
  • HostName: 파일을 전송하려는 원격 서버의 ip
  • Username: 원격서버 계정
  • Remote Directory: 원격 서버 디렉토리

그러고나면 보라색 별이 그려져 있는 Key를 만들어줘야 한다.

- SSH key 발급

젠킨스가 설치되어 있는 컴퓨터에서 실행해야 한다!

1) 터미널에 ssh-keygen 명령어를 입력한다
2) 아래 이미지를 따라 진행, passphrase는 생략한다.

3) key를 만든 디렉토리에 id_rsa, id_rsa.pub라는 파일이 생성되었는지 확인
4) cat {key가 있는 디렉토리}/.ssh/id_rsa 명령어로 키 복사!
5) 위 젠킨스 설정 페이지의 Key에 붙여넣는다


이렇게 하면 Publish Over SSH 설정이 끝난다.

- 원격 서버로 빌드한 파일 보내기

1) 우선, 새로운 프로젝트를 생성한다.

대시보드 > 새로운 아이템 > Freestyle Project > 생성

2) General 설정에서 빌드 트리거를 설정한다.

'빌드'가 성공적으로 완료되면 자동으로 실행된다.

3) 빌드 환경도 설정한다.

SSH Server의 Name을 통해 Publish Over SSH 설정을 불러오고,
Transfer의 Source files에 옮길 파일의 이름을 작성한다.

- Exec command

Exec command는 파일 전송 뒤 실행할 스크립트를 적어주면 된다.
나의 경우엔 1) 실행중인 프로세스가 있으면 종료하고 2) jar를 실행한다.

PROC=`ps aux | grep garden-0.0.1.jar`
if [[ $PROC == *"garden-0.0.1.jar"* ]]
then
  echo "Process is running."
  sudo kill -15 `ps -ef | grep garden-0.0.1.jar | awk '{print $2}'`
else
  echo "Process is not running."
fi

BUILD_ID=dontKillMe sudo nohup java -jar garden-0.0.1.jar 1> /dev/null 2>&1

https://ydeer.tistory.com/298
https://blog.jiniworld.me/94

1개의 댓글

comment-user-thumbnail
2023년 8월 10일

개발자로서 배울 점이 많은 글이었습니다. 감사합니다.

답글 달기