앱 개발 단계에 자동화를 통합하는 앱 제공 방식으로, 지속적 통합(Continuous Integration) 및 지속적 제공/배포 (Continuous Delivery/Deployment)를 뜻한다. 애자일 개발 방식에서 발전한 CI/CD는 운영 원칙을 포함하는 포괄적인 용어이며, DevOps 팀이 코드 변경을 앱에 쉽고 빠르게 구현하도록 지원한다.
예전에 회사에서 진행한 프로젝트에서는 CI/CD가 완벽한 자동화를 이루지 못했다. 매번 깃헙에 파일을 올리고 버전만 변경시키는 배포 스크립트를 돌리고, 빌드 인스톨러를 구동시킨 뒤 인스톨 파일을 만든 다음 리눅스 서버에 접속해서 dist 정적 배포 파일을 변경해야 했다. 빌드할 때마다 최소 한 시간 정도 소요되었으며, 테스트를 제대로 거치지 못한 채 많은 과정을 거치느라 실수도 수도 없이 했다.
당시에는 CI/CD에 시간을 투여할 여지가 적었기 때문에 불편함을 감수하고 수동으로 작업을 진행했다. 결과를 돌이켜봤을 때, 만약 제대로 된 CI/CD가 있었다면, 개발 속도는 훨씬 빨라졌을 거란 아쉬움이 남는다.
신규 개인 프로젝트와 팀 프로젝트를 시작하면서, 이런 어려움을 최소화하고자, CI/CD를 구축한 다음에 프로젝트를 진행하고자 한다.
CI/CD를 위한 대표적 플랫폼으로 Jenkins 와 Github Actions가 있다.
소프트웨어 빌드, 테스트, CI/CD와 관련된 모든 종류의 작업 자동화에 사용하는 오픈 소스 자동화 서버. 기본 시스템 패키지, Docker를 통해 설치할 수 있으며, JRE가 설치된 모든 시스템에서 단독 실행 가능하다.
빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 CI/CD 플랫폼. 리포지토리에 대한 모든 pull request를 빌드 및 테스트하거나 merged pull request를 프로덕션에 배포하는 워크플로를 만들 수 있다.
| 비교분석 | Jenkins | Github Actions |
|---|---|---|
| 러닝 커브 | 높음 | 낮음👍 |
| 가격 | 무료👍 | 개인만 무료 |
| 참고 자료 | 많음👍 | 적음 |
| 사용 범위 | 넓음👍 | Github 한정 |
| 온프레미스* | 유연하게 적용👍 | 기능이 한정적 |
원격환경에서 서버를 운영하는 클라우드와는 대비되는 개념으로 기업이 서버를 자체적으로 보유하고 직접 설치 및 운영하는 방식
간단한 개인 프로젝트를 구현하기 위해서는 GitHub Actions를 사용하는 것이 좋다. 쉽고 간편하게 원하는 결과를 구현할 수 있기 때문이다.
Jenkins는 GitHub actions에 비해 사용하기 어려운 단점이 있으나, 가격 측면에서 우위를 가지고 있어 많은 기업에서 사용하고 있다.
나는 CI/CD를 학습하는 입장에서, 더 많은 배움을 위해 Jenkins를 선택했다.
개인 프로젝트 tmdb의 최종 결과물은 웹 사이트, 팀 프로젝트의 최종 결과물은 모바일 어플리케이션으로 나온다. 개인 프로젝트를 제대로 완성시킨 다음 팀 프로젝트에 적용할 것이라, 먼저 개인 프로젝트부터 정리한다.
Start
⬇ Github Push/Pull Request → Webhook TriggerEnd
플로우차트에는 테스트 과정이 빠져 있는데, 위의 과정이 제대로 이루어지고 난 다음 세부 테스트를 추가하려 한다.
Github Webhook: repository의 push 또는 pull request 이벤트 감지
→ Jenkins 파이프라인 실행
Step 1: cd frontend
Step 2: npm install (필요한 dependencies 설치)
Step 3: npm run build (Vite를 이용해 정적 파일 생성)
Step 4: 생성된 dist/ 폴더를 백엔드 폴더로 복사
Command: cp -r dist ../backend/dist
Step 1: cd backend
Step 2: ./gradlew clean build (gradle로 Spring Boot 빌드)
결과물: backend/build/libs/tmdb.jar 생성
Step 1: EC2 서버와 SSH 연결
Command: scp -i [pem 파일] target/tmdb.jar
ec2-user@[EC2 주소]:/home/ec2-user/app/
Step 2: EC2 서버에서 기존 앱 중단
Command: ssh -i [pem 파일] ec2-user@[EC2 주소] "pkill -f tmdb.jar || true"
Step 3: 새 앱 실행
Command: ssh -i [pem 파일] ec2-user@[EC2 주소]
"nohup java -jar /home/ec2-user/app/tmdb.jar > log.txt 2>&1 &"
Step 1: EC2 서버에서 앱 상태 점검 (포트 확인 등)
Command: curl -I http://[EC2 주소]:[포트]
Step 2: Jenkins에 성공/실패 알림 표시
무중단 서버가 아닌, 업데이트를 할 때에는 서비스가 모두 종료되는 사양이다. 애자일 기반으로, 최소 기능이 완성되고 난 다음 다른 기능을 추가하려 한다.
CI/CD는 개발의 밑바탕이다. 개발 시간의 최소화는 CI/CD에 달려 있다. 이번 프로젝트를 기회 삼아, DevOps의 역량을 키우고 싶다.
Jenkins 공식 문서
GitHub Actions 설명서
온프레미스 VS 클라우드 차이점과 앞으로의 발전방향은?