CI CD/TeamCity

[TeamCity] 5. Build Config

bbyuk 2022. 5. 25. 19:52

https://bbyuck.tistory.com/43

이 포스팅으로부터,,,

Build Agent가 사용할 Gradle을 먼저 서버에 설치해주었다.

 

 

 

1. 미리 생성해둔 프로젝트

main 브랜치 버튼을 클릭해 프로젝트 콘솔로 들어간다.

 

 

포스팅 전 시행착오를 겪느라 이미 쌓인 빌드로그들,,,

무시하고 우측 상단의 Edit Configuration Settings 버튼을 클릭한다.

 

 

 

Configuration 메인화면

 

빌드명, 빌드 ID, 설명 등 기본적인 데이터 설정들,,

VCS 탭도 확인해보자.

 

 

프로젝트를 생성하면서 잡아둔 VCS 루트가 잘 잡혀있는 것을 확인할 수 있다.

Triggers로 간다.

아래 스크린샷에는 설정해둔 트리거가 하나 있지만, 원래는 없다,,,

Add new trigger 버튼을 눌러 빌드를 실행하게 할 Trigger를 추가한다.

물론 TeamCity 웹콘솔에 접속해 온디맨드로 빌드를 수행할 수도 있다.

 

처음에 구상했던 그림대로 개발자가 github repository에 소스 변경 사항을 push했을 때 자동으로 빌드하고,

빌드 결과물을 Oracle Cloud 개발서버로 전송해 배포까지 하기 위해서는 먼저 github repository hook을 받아야겠지,,

VCS Trigger를 선택하고 Branch Filter는 현재 main Branch만 있으니 기본설정대로 둔다.

 

 

이제 Build Step을 구성할 차례

Add Build Step 버튼을 눌러 각 Build Step을 구성한다.

 

먼저 구성한 Build Step을 보면 아래와 같다.

 

Trigger - 미리 지정한 Trigger를 통해 Github Repository의 변경점 감지.

--------------------------------------------------------------------------------------------------

1. 해당 소스를 가지고 gradle clean build

2. AWS(TeamCity가 올라가 있는 환경) -> Oracle Cloud(빌드 결과물을 배포할 App 서버)로 빌드 결과물 전송

3. Oracle Cloud(빌드 결과물을 배포할 App 서버)에서 빌드 결과물을 백그라운드 서비스로 실행 

-------------------------------------------------------------------------------------------------

을 설정하면 아래와 같다.

 

하나하나 설정값들을 살펴보자

1. 해당 소스를 가지고 gradle clean build

 

1.1. Runner type : Gradle

1.2. Step name : 임의의 Step name

1.3. Gradle tasks : clean build

1.4. Gradle home path : %env.GRADLE_HOME%

 

자,, 여기서 미리 설치해뒀던 Gradle을 TeamCity Build Agent의 환경변수 env.GRADLE_HOME으로 참조할 수 있도록 환경변수 설정을 해야한다.

 

터미널로 돌아가보자.

vi /var/lib/teamcity/buildAgent/conf/buildAgent.properties

buildAgent.properties 파일에 buildAgent가 참조할 수 있는 환경변수들을 설정할 수 있다.

 

buildAgent.properties 파일 가장 밑으로 내리면 환경변수 설정 예시가 주석으로 달려있다.

미리 설치했던 Gradle의 경로를 설정하고 저장한다.

env.GRADLE_HOME=/opt/gradle/gradle-7.4.2

 

그 후 buildAgent 재시작을 하면되는데,, 그냥 teamcity 서비스를 restart하자

 

service teamcity restart

저장,,, 리눅스 명령어를 직접 등록하는 방법도 있긴 한데,, 굳이굳이 제공해주는 템플릿을 이용하자.

 

 

2. AWS(TeamCity가 올라가 있는 환경) -> Oracle Cloud(빌드 결과물을 배포할 App 서버)로 빌드 결과물 전송

 

2.1. Runner type : SSH Upload

2.2. Step name : 임의의 Step name

2.3. Execute step : If all previous steps finished successfully

2.4. Target : ${ 목표 ip || 도메인 }:${ 목표 서버의 목표 디렉터리 위치 }

2.5. Transport protocol : SCP

2.6. Authentication method : Custom private key (상황따라 다르지만 지금 내 프로젝트에서는)

2.7.  Path to key file : %env.ORACLE_CLOUD_KEY%

2.8. Username : opc

2.9. Paths to sources : /var/lib/teamcity/buildAgent/work/${ git commit id }/build/libs/invitation-0.0.1-SNAPSHOT.jar

 

이번 Step도 물론 리눅스 명령어로도 처리가 가능하지만 SSH Upload 타입으로 설정한다.

두 번 째 Step이므로 이전 Step인 gradle build가 정상적으로 마무리 된 상태에서만 실행할 수 있도록 설정하고,

Target 경로는 Oracle Cloud의 opc home으로 일단 설정,,,

이거를 근데 이렇게 하드로 넣어도 되는건지는 의문이다. 이후 프로필화 할 수는 없을지 고민을 좀 더 해보자.

그리고 전송 프로토콜은 SCP와 SFTP 둘 중 하나를 선택할 수 있는데, 서버간 통신이고, 배포할 Spring Boot App이 무겁지 않으니

SCP로,,, 포트는 22 기본 포트 그대로 둔다.

  SCP SFTP
기능 파일 전송만 허용하는 간단한 프로토콜 원격 파일 관리를 위한 광범위한 작업을 제공
원격으로 파일 제거, 중단 된 전송 재개 등의 추가기능을 가짐
플랫폼 대부분 Unix 플랫폼만 사용함 여러 플랫폼에서 사용할 수 있음
속도 SFTP 보다 빠르다 패킷의 암호화 및 일치를 기다려야 하므로 SCP보다 느림
파일 전송 용량 4GB 이상의 파일 전송 불가 4GB 이상의 파일도 전송가능 (대용량 전송이 가능)
세션 유지 파일 전송 취소시 세션을 취소해야함 파일 전송 취소시 세션을 유지할 수 있음
전송 재개 가능 전송 재개 불가능 전송 재개 가능

출처 : https://parkadd.tistory.com/129

 

---- 개인 설정 ----

Target 경로가 Oracle Cloud의 인스턴스이다 보니,, Auth key를 함께 주어야 접근이 가능하다.

Oracle Cloud에서 사용하는 key 파일을 우선 AWS(TeamCity가 올라가있는 서버)에 올리고, TeamCity Build Agent에서 그 것을 참조할 수 있도록 환경변수로 설정해주는 작업이 필요했다.

teamcity의 루트경로에 keys라는 디렉터리를 하나 만들어 이후에 TeamCity에서 다른 Cloud Target을 참조할 때 필요한 key파일들을 저장하도록 한다.

일단 Oracle Cloud의 인스턴스에 접근할 수 있는 private key파일을 여기에 저장하고 아래의 명령어로 key파일 권한 설정한다.

# 키파일의 소유권을 teamcity로 변경
chown teamcity:teamcity /var/lib/teamcity/keys/bbyuk-oracle-cloud-key
# 소유자외에 다른 유저의 private key 파일에 대한 권한을 모두 off
chmod 600 /var/lib/teamcity/keys/bbyuk-oracle-cloud-key

 

이렇게 Key파일이 준비가 되었으면 이제 Build Agent 환경변수를 설정한다.

vi /var/lib/teamcity/buildAgent/conf/buildAgent.properties

제일 아래에 환경변수 입력.

env.ORACLE_CLOUD_KEY=/var/lib/teamcity/keys/bbyuk-oracle-cloud-key

이렇게 Oracle Cloud에 접근할 수 있는 key 설정이 완료되었다.

 

그리고 Oracle Cloud 기본 유저인 opc를 username으로 설정해주면 Target 설정 완료.

 

이제 어떤 파일을 가지고 갈 것인가에 대한 설정이 남았다.

1번 Step의 결과물인 빌드 결과물에 대한 경로를 Paths to sources에 입력해주면 Step2도 설정 완료다.

 

 

3. Oracle Cloud(빌드 결과물을 배포할 App 서버)에서 빌드 결과물을 백그라운드 서비스로 실행 

 

3.1. Runner type : SSH Exec

3.2. Step name : 임의의 Step name

3.3. Target : ${ 목표 ip || 도메인 }

3.4. Authentication method : Custom private key

3.5. %env.ORACLE_CLOUD_KEY%

3.6. Username : opc

3.7. Commands :

pid=`ps -ef | grep invitation-0.0.1-SNAPSHOT.jar | grep -v 'grep' | awk '{print $2}'`
sudo kill -9 $pid
sudo nohup java -jar invitation-0.0.1-SNAPSHOT.jar 1>/home/opc/stdout.log 2>&1 &

 

2번 Step과 동일하게 목표 Oracle Cloud에 접속해야 하므로 Authentication 설정은 동일하게 해주면 된다.

Command를 보면

이미 Oracle Cloud 인스턴스에서 이전에 배포가 되어 돌고있는 프로세스는 kill하고 백그라운드로 다시 실행해주는 스크립트이다.

빠르게 빌드 배포가 되는지만 확인하려고 이전에 사용했던 스크립트를 그대로 사용했는데,,, 이러면 첫 빌드에서는 Oracle Cloud 쪽에서 에러가 한 번 뜨긴한다,,, 없는 pid kill하려고 하는거니깐,,,

 

이후에 bash shell 하나 짜서 얹고 그걸 실행만 하는 Step으로 변경해야겠다.

 

일단은 1>/home/opc/stdout.log 로 표준출력은 stdout.log파일로 보냈고,

2>&1로 표준에러도 표준출력과 같은곳,,, 그러니깐 stdout.log로 보내버렸다.

그리고 맨뒤 &로 백그라운드 실행,,,

리눅스 쉘은 공부를 빠른 시일내에 더 해야되겠다.

 

 

자 그럼 진짜 푸시해서 빌드/배포가 되는지 확인을 해보자.

아래의 간단한 컨트롤러 하나를 프로젝트에 추가해 github repository에 푸시해보자.

 

github repository에 push

 

 

 

 

자동으로 설정해둔 빌드를 수행해 성공한 모습이다.

 

배포까지 정상적으로 잘 되었는지 확인해보자.

빌드 결과물이 정상적으로 Oracle Cloud의 인스턴스에 잘 올라갔고, 프로세스도 잘 올라가 실행중인 모습을 볼 수 있다.

 

브라우저로 접속해보면 잘 올라간 모습을 볼 수 있다!

 

 

 

드디어 기나긴 배포 파이프라인 설정을 마치고 개발을 시작할 수 있게 되었다...

물론 스크립트도 손봐야 하고,, 빌드 패스 변수로 바꾸는 등등 추가적으로 공부해줘야 할 것들이 많지만 일단 빠르게 개발을 시작할 수 있는 환경은 마련된 것 같다.