요약
1) OpenJDK 21, Jenkins war 를 macOS에 설치
2) GitHub 연동, Springboot application gradle build, war 확인
*그림 설명은 그림 밑에 하겠습니다.
1. Jenkins 소개
CI/CD란?
CI(Continuous Integration) /CD(Continuous Delivery/Deployment) 는 애플리케이션 개발 단계를 자동화하여 애플리케이션을 더욱 짧은 주기로 고객에게 제공하는 방법입니다.
CI (Continuous Integration, 지속적 통합)
- 개발자들이 작성한 코드를 메인 브랜치에 지속적으로 통합
- 자동화된 빌드와 테스트를 통한 코드 품질 보장
- 여러 개발자의 코드 충돌 방지
- 빠른 피드백 루프 제공
CD (Continuous Delivery/Deployment, 지속적 제공/배포)
- Continuous Delivery: 수동 승인 후 배포
- Continuous Deployment: 완전 자동화된 배포
- 안정적이고 빠른 배포 프로세스 구현
- 운영 리스크 감소
Jenkins의 특징과 장점
주요 특징
오픈소스
- 무료로 사용 가능
- 활발한 커뮤니티 지원
- 다양한 플러그인 생태계
확장성
- 1,800개 이상의 플러그인 제공
- 다양한 개발 도구와의 통합 가능
- 커스텀 플러그인 개발 가능
유연성
- 다양한 환경에서 실행 가능
- 파이프라인을 코드로 정의 (Pipeline as Code)
- 분산 빌드 지원
장점
- 쉬운 설치와 구성
- 직관적인 웹 인터페이스
- 상세한 문서화
- 간단한 설정 방법
- 강력한 자동화
- 빌드, 테스트, 배포 자동화
- 다양한 트리거 옵션
- 복잡한 파이프라인 구성 가능
- 높은 안정성
- 검증된 도구
- 대규모 프로젝트에서의 신뢰성
- 활발한 보안 업데이트
Jenkins 아키텍처
기본 구조 예시
├── [Agent 1] - 빌드/테스트 실행
├── [Agent 2] - 배포 작업
└── [Agent 3] - 특수 환경 테스트
서버별로 Agent를 설치하여 다른 역할을 수행할 수 있습니다.
Jenkins Master
- 전체 시스템 관리
- 작업 스케줄링
- UI 제공
- 결과 표시
Jenkins Agent
- 실제 작업 수행
- 다양한 환경 지원
- 부하 분산 가능
Pipeline
- 작업 흐름 정의
- Jenkinsfile로 관리
- 단계별 실행 제어
사용 사례
- 코드 커밋 시 자동 빌드/테스트
- 정기적인 배포 자동화
- 품질 게이트 검사
- 보안 취약점 스캔
산업별 활용
- 프론트엔드/백엔드 통합 테스트
- 다중 환경 배포
모바일 앱
- iOS/Android 빌드 자동화
- 앱스토어 배포 준비
엔터프라이즈
- 레거시 시스템 통합
- 복잡한 의존성 관리
2. 설치 전 준비사항
- 시스템 요구사항
https://www.jenkins.io/doc/book/installing/linux/#prerequisites
Minimum hardware requirements:
256 MB of RAM
1 GB of drive space (although 10 GB is a recommended minimum if running Jenkins as a Docker container)
Recommended hardware configuration for a small team:
4 GB+ of RAM
50 GB+ of drive space
Comprehensive hardware recommendations:
Hardware: see the Hardware Recommendations page
Software requirements:
Java: see the Java Requirements page
Web browser: see the Web Browser Compatibility page
For Windows operating system: Windows Support Policy
For Linux operating system: Linux Support Policy
For servlet containers: Servlet Container Support Policy
- Java 설치
1) https://adoptium.net/download/ 에서 OS에 맞는 Java를 설치하세요. 저는 21을 설치 했습니다.
3. Jenkins 설치
- Docker를 이용한 설치
docker pull jenkins/jenkins
- War 파일을 이용한 설치 (저는 이 방법으로 진행 하겠습니다.)
1) https://www.jenkins.io/download/ 에서 .war 다운로드

2) jenkins war 실행
java -jar jenkins.war 실행되면서 최초 비밀번호가 보입니다.
java -jar jenkins.war
Running from: /Users/sean/work/jenkins/jenkins.war
webroot: /Users/sean/.jenkins/war
2025-01-13 07:13:17.238+0000 [id=1] INFO winstone.Logger#logInternal: Beginning extraction from war file
2025-01-13 07:13:17.827+0000 [id=1] WARNING o.e.j.ee9.nested.ContextHandler#setContextPath: Empty contextPath
2025-01-13 07:13:17.853+0000 [id=1] INFO org.eclipse.jetty.server.Server#doStart: jetty-12.0.16; built: 2024-12-09T21:02:54.535Z; git: c3f88bafb4e393f23204dc14dc57b042e84debc7; jvm 21.0.5+11-LTS
2025-01-13 07:13:18.053+0000 [id=1] INFO o.e.j.e.w.StandardDescriptorProcessor#visitServlet: NO JSP Support for /, did not find org.eclipse.jetty.ee9.jsp.JettyJspServlet
2025-01-13 07:13:18.077+0000 [id=1] INFO o.e.j.s.DefaultSessionIdManager#doStart: Session workerName=node0
2025-01-13 07:13:18.265+0000 [id=1] INFO hudson.WebAppMain#contextInitialized: Jenkins home directory: /Users/sean/.jenkins found at: $user.home/.jenkins
2025-01-13 07:13:18.631+0000 [id=1] INFO o.e.j.s.handler.ContextHandler#doStart: Started oeje9n.ContextHandler$CoreContextHandler@3f93e4a8{Jenkins v2.479.3,/,b=file:///Users/sean/.jenkins/war/,a=AVAILABLE,h=oeje9n.ContextHandler$CoreContextHandler$CoreToNestedHandler@12b5454f{STARTED}}
2025-01-13 07:13:18.640+0000 [id=1] INFO o.e.j.server.AbstractConnector#doStart: Started ServerConnector@506dcf55{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2025-01-13 07:13:18.654+0000 [id=1] INFO org.eclipse.jetty.server.Server#doStart: Started oejs.Server@1b84f475{STARTING}[12.0.16,sto=0] @1717ms
2025-01-13 07:13:18.657+0000 [id=43] INFO winstone.Logger#logInternal: Winstone Servlet Engine running: controlPort=disabled
2025-01-13 07:13:18.748+0000 [id=50] INFO jenkins.InitReactorRunner$1#onAttained: Started initialization
2025-01-13 07:13:18.752+0000 [id=50] INFO jenkins.InitReactorRunner$1#onAttained: Listed all plugins
2025-01-13 07:13:19.077+0000 [id=58] INFO jenkins.InitReactorRunner$1#onAttained: Prepared all plugins
2025-01-13 07:13:19.079+0000 [id=49] INFO jenkins.InitReactorRunner$1#onAttained: Started all plugins
2025-01-13 07:13:19.079+0000 [id=67] INFO jenkins.InitReactorRunner$1#onAttained: Augmented all extensions
2025-01-13 07:13:19.166+0000 [id=55] INFO jenkins.InitReactorRunner$1#onAttained: System config loaded
2025-01-13 07:13:19.166+0000 [id=51] INFO jenkins.InitReactorRunner$1#onAttained: System config adapted
2025-01-13 07:13:19.167+0000 [id=51] INFO jenkins.InitReactorRunner$1#onAttained: Loaded all jobs
2025-01-13 07:13:19.167+0000 [id=51] INFO jenkins.InitReactorRunner$1#onAttained: Configuration for all jobs updated
2025-01-13 07:13:19.176+0000 [id=80] INFO hudson.util.Retrier#start: Attempt #1 to do the action check updates server
2025-01-13 07:13:19.402+0000 [id=60] INFO jenkins.install.SetupWizard#init:
*************************************************************
*************************************************************
*************************************************************
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
d1d7fe3d79e4458cb16095ec07dfdc87
This may also be found at: /Users/sean/.jenkins/secrets/initialAdminPassword
*************************************************************
*************************************************************
*************************************************************
2025-01-13 07:13:22.877+0000 [id=60] INFO jenkins.InitReactorRunner$1#onAttained: Completed initialization
2025-01-13 07:13:22.892+0000 [id=40] INFO hudson.lifecycle.Lifecycle#onReady: Jenkins is fully up and running
2025-01-13 07:13:24.627+0000 [id=80] INFO h.m.DownloadService$Downloadable#load: Obtained the updated data file for hudson.tasks.Maven.MavenInstaller
2025-01-13 07:13:24.627+0000 [id=80] INFO hudson.util.Retrier#start: Performed the action check updates server successfully at the attempt #1
3) 초기 비밀번호 설정
localhost:8080 접속 후 실행할 때 생성된 비밀번호를 입력합니다.


저는 추천 플러그인을 설치 하겠습니다.
인터넷이 안되는 환경이라면 추후 플러그인을 다운로드 받은 후 반입신청으로 수동으로 설치할 수 있습니다.

설치 과정 후

어드민 계정을 생성합니다.

도메인 또는 외부에서 접근할 수 있는 주소가 있다면 Jenkins URL을 변경으로 접속할 수 있습니다.
추후 변경 가능합니다.

설치 완료 후 초기 화면입니다.
4. 새로운 Item(Job) 생성
1) + 새로운 Item 선택

생성 후 기본 정보 입력하는 화면입니다.

소스 코드 관리를 Git 으로 선택합니다.

Credentials 설정이 필요합니다.

Github - Settings - Applications - My GitHub Apps 을 선택합니다.

Personal access tokens로 Token을 생성합니다.
Expiration, Permission은 조직 보안 레벨에 맞게 설정이 필요합니다.


Jenkins에서는 Contents (Read and write), Metadata (Read-only) 권한이 필요합니다.

권한 설정 후 화면입니다.

생성된 토큰은 지금만 복사할 수 있습니다. 아니면 다시 생성해야하니 주의해야합니다.
다시 Jnekins로 돌아가서

Kind 에는 Username with password를 선택합니다.
Username은 Github username을 입력하고 Password에는 token을 입력합니다.
ID는 Jenkins에서 식별할 수 있는 ID입니다.

이상이 없다면 위 화면과 같이 오류 메시지가 없습니다.
403 오류가 난다면 권한, username, token을 확인 해보시면 됩니다.

빌드 유발에는 5가지 방법이 있습니다.
빌드 유발은 브랜치 전략, 팀의 개발 방법에 따라 선택할 수 있습니다.
브랜치는 개발, 운영 환경에 따라 운영할 수 있는데요. 개발, 검증, 운영 환경이 있다면
크게 3개 개발, 검증, 운영 브랜치로 나눈 후 개발에서는 개발자 개인별로 브랜치를 생성하여 운영하는 방법이 있습니다.
그러면 배포하기도 수월합니다.
- 원격으로 빌드 유발
- Jenkins의 REST API를 통해 외부에서 빌드를 시작할 수 있습니다
- 다음과 같은 URL로 트리거 가능:
- CI/CD 파이프라인 통합이나 외부 스크립트에서 활용하기 좋습니다
- Build after other projects are built
- 다른 프로젝트의 빌드 완료 후 자동으로 빌드를 시작
- 의존성이 있는 프로젝트들을 순차적으로 빌드할 때 유용
- 상위 프로젝트의 성공/실패/불안정 상태에 따라 트리거 설정 가능
- Build periodically
- cron 표현식을 사용하여 정기적인 빌드 스케줄링
- 예시: H/15 * * * * (15분마다 실행)
- 주기적인 배치 작업이나 나이트리 빌드에 적합
- GitHub hook trigger for GITScm polling
- GitHub 저장소에 변경사항이 발생할 때 자동으로 빌드
- GitHub webhook을 통해 Jenkins에 즉시 알림
- 실시간 빌드가 가능하여 자원 효율적
- Poll SCM
- 정기적으로 소스 코드 저장소를 확인하여 변경사항이 있으면 빌드
- cron 형식으로 주기 설정
- webhook을 사용할 수 없는 환경에서 대안으로 사용
- 예시: */5 * * * * (5분마다 저장소 확인)
우선 빌드 유발은 설정하지 않겠습니다.
Build Steps
macOS, Linux 계열은 Excube Shell을 많이 사용합니다. 프로젝트 환경에 맞게 명렁어를 선택할 수 있습니다.
ls -a
sh gradlew build
cd build/libs
ls -a
이번 예시로는 gradel build 후 빌드 결과를 보여주는 shell을 준비해봤습니다.

저장 후 지금 빌드로 빌드 실행 후 Console Output으로 빌드 과정을 확인할 수 있습니다.
SaaS 기반 CI/CD도 많지만 Build 시간이 긴 프로젝트는 비용 이슈로 Jenkins를 활용하는 경우가 있습니다. 보안 이슈로 Cloud 환경을 이용 못하는 경우에도 Jenkins를 많이 활용하고 있습니다.
다음에는 Jenkins로 tomcat에 ssh로 배포하는 방법을 포스팅 해보겠습니다.
감사합니다.
'DevOps' 카테고리의 다른 글
| HAProxy vs. Nginx: 최고의 로드밸런서는? 차이점 완벽 비교! (0) | 2025.02.07 |
|---|