개발을 하다보면 가장 많이 처리하는 것이 배포일 것이다. 짧은 주기로 빠르게 기능을 구현하다보면 많을 땐 하루에 두 번 이상 배포할 때도 있다. 그럴 때마다 반복하는 동작이 있다.

  1. ssh 로 서버에 접속
  2. git clone
  3. 스크립트 실행

그나마 스크립트를 작성하여 빌드하여 배포하는 과정은 생략하였지만 위의 과정이 매번 반복된다. 이러한 배포 과정을 자동화하기 위해 Jenkins 를 이용하였다. Jenkins 말고도 다양한 배포 자동화 툴이 있지만 무료이며(체험판 X) 참고할 수 있는 자료들이 많아 선택하였다.

Jenkins 를 처음 접했을 때 이해가 안됐던 부분은 ‘내가 언제 배포할지 Jenkins 가 어떻게 알지?’ 였다. 물론 Jenkins 도 개발자가 언제 배포하고 싶어하는지 아는 것이 아니다. 외부에서 오는 알림을 받아 미리 작성해둔 동작을 처리하는 것 뿐이다. 이러한 동작은 깃허브를 통해 프로젝트를 관리하므로 Github 에서 Jenkins 에 알림을 보내면 된다.

Jenkins 의 동작 과정은 다음과 같다. 개발자가 원하는 기능을 구현하고 깃허브에 PR 을 보낸다. 깃허브에는 Webhook 을 보내는 기능이 있는데, 원하는 브랜치에서 원하는 동작이 수행될 경우 특정 위치로 Webhook 을 보낸다. 기능 개발이 완료된 PR 을 배포할 예정이므로 개발 서버라면 develop 브랜치를, 운영 서버라면 main(또는 release) 브랜치에 PR 이 머지가 되면 Webhook 을 보낼 예정이다.

외부에서 알림을 받은 Jenkins 는 미리 정의되어 있던 배포 과정을 수행한다. 이 과정은 위에서 언급했던 ‘매번 반복되던 배포 과정’ 이다. 즉, 개발자는 PR 을 머지시키는 것만으로 이전에 반복됐던 배포 과정이 자동화된 것이다.

Jenkins.png

그림에서 보면 API 서버와 Jenkins 를 관리하는 서버가 분리되어 있다. AWS EC2 프리티어 사양에서 Jenkins 와 Spring Boot 를 한번에 수행하기에 조금 어려움이 있다. 서버 사양의 문제로 서버가 다운되면 배포뿐만 아니라 서비스 운영에 큰 영향을 미친다.

Jenkins

Jenkins 를 관리할 AWS EC2 생성하고, 먼저 Java 를 설치한다. Jenkins 는 Java 11 또는 17 버전을 필요로 한다. Java 설치 후 Jenkins 도 설치해준다.

$ sudo apt-get update

$ sudo apt-get openjdk-11-jdk

$ curl -fsSL <https://pkg.jenkins.io/debian-stable/jenkins.io.key> | sudo tee \\
  /usr/share/keyrings/jenkins-keyring.asc > /dev/null
$ echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \\
  <https://pkg.jenkins.io/debian-stable> binary/ | sudo tee \\
  /etc/apt/sources.list.d/jenkins.list > /dev/null
$ sudo apt-get install jenkins

설치한 Jenkins 를 서비스에 등록하여 관리한다.

$ sudo systemctl enable jenkins
$ sudo systemctl start jenkins
$ sudo systemctl status jenkins

Untitled

Jenkins 의 기본 포트인 8080 으로 접속해보면 로그인 화면이 나타난다! 사이트에서 알려주는 대로 천천히 진행해서 Jenkins 를 셋팅하자.

Untitled

Untitled

Jenkins 서버에서 배포 서버 SSH 접근 실패