😓 Jenkins도 여러번 사용했지만 제대로 정리한 적은 없으니...
⛓ 개발과 운영 간의 협업을 강조하는 문화, 움직임, 실천 방법론
소프트웨어 개발 수명주기 전체에 걸쳐 개발자와
운영자가 지속적으로 소통하고 협력하는 것을 중시
소프트웨어 개발자, 시스템 운영자, 품질 보증(QA) 팀 등
다양한 IT 부서 간의 협업과 통합 강조
애플리케이션 개발 및 배포 과정을 자동화하고 가속화하는 것이 목표
⛓ 자동화 (Automation)
가능한 모든 것을 자동화하는 것을 강조
이를 통해 빠른 반복과 오류 감소를 이끌어 냄
CI/CD 파이프라인 구축, 인프라 자동화, 테스트 자동화 등이 그 예시
⛓ 코드 관리 (Code Management)
코드와 인프라 설정 등 모든 것을 버전 관리하여 변경 사항을 추적하고 관리
이를 통해 변경 사항의 추적, 롤백, 협업 용이
⛓ 지속적 통합 (Continuous Integration)
개발자들의 코드 변경이 자동으로 통합되고 테스트되며 빌드되는 프로세스
이를 통해 팀 내에서의 협업을 강화하고 품질을 유지 가능
⛓ 지속적 제공/배포 (Continuous Delivery/Deployment)
변경 사항이 테스트를 통과하면 자동으로 프로덕션 환경에 배포되는 프로세스
이를 통해 신속하고 안정적인 소프트웨어 배포가 가능
⛓ 모니터링과 피드백 (Monitoring and Feedback)
실시간으로 시스템 및 애플리케이션의 상태를 모니터링하고
사용자 피드백을 수집하여 지속적으로 개선
이를 통해 서비스 품질을 높이고 문제를 빠르게 해결할 수 있음
⛓ 애자일 개발 방법론과 린(Lean) 원칙 실천
⛓ 지속적 통합(CI), 지속적 배포(CD), 지속적 모니터링
⛓ IaC
: 코드로 인프라 정의 및 프로비저닝
⛓ 마이크로서비스 아키텍처 및 컨테이너 기술 활용
⛓ 애플리케이션 개발 및 배포 프로세스를 자동화하고 효율성을 높이는 방법론
⛓ CI (Continuous Integration – 지속적 통합)
개발자들이 코드를 공유 레포지토리에 푸시할 때마다
자동으로 테스트와 빌드가 실행되는 개발 프로세스
이는 팀 내에서의 협업을 촉진하고 통합 오류를 조기에 발견하여
해결할 수 있는 기회 제공
자동화된 빌드와 테스트, 빠른 피드백, 통합 오류 감소
⛓ CD (Continuous Deployment / Continuous Delivery)
CI를 확장하여 릴리스 프로세스를 자동화하는 것을 의미
Continuous Deployment (지속적 배포)
변경 사항이 테스트를 통과하면 자동으로 프로덕션 환경에 배포
이는 빠른 소프트웨어 배포를 가능하게 하며, 사용자에게 더 빠르게 새로운 기능을 제공할 수 있음
Continuous Delivery (지속적 제공)
변경 사항이 테스트를 통과하면 수동으로 프로덕션 환경에 배포할 수 있도록 하는 것
이는 지속적 배포와 유사하지만, 프로덕션 배포의 자동화 단계가 없음
⛓ CI/CD: Jenkins
, GitLab CI/CD
, Travis CI
, CircleCI
등
⛓ 컨테이너: Docker
, Kubernetes
등
⛓ IaC: Terraform
, Ansible
, Puppet
, Chef
등
⛓ 모니터링: Prometheus
, Grafana
, ELK
스택 등
주인장의 실습코드가 담긴 관련 repo 참고
⛓ GitHub에서 제공하는 CI/CD 자동화 도구
⛓ 자동화된 빌드/테스트/배포
→ 코드 푸시 또는 PR 시 자동으로 워크플로우 실행 가능
⛓ 이벤트 기반 트리거
→ push, pull_request, issue, schedule 등 다양한 GitHub 이벤트에 반응
⛓ 비밀 관리
→ Secrets 기능을 통해 API 키, 인증 토큰 등 민감한 정보 안전하게 저장 가능
⛓ 다양한 환경 지원
→ Linux, Windows, macOS 런타임에서 실행 가능
⛓ 확장성
→ 수천 개의 커뮤니티 액션을 조합하여 고급 기능 구현 가능 (예: 캐싱, 매트릭스 빌드, Slack 알림 등)
⛓ 쉬운 설정
→ .github/workflows/*.yml
파일만 작성하면 자동화 파이프라인 즉시 실행 가능
특정 이벤트 (push, PR, 스케줄 등)가 깃허브 저장소에서 발생
깃허브 액션은 워크플로 파일 전용 디렉토리 (.github/workflows
)를 검색
해당 이벤트에 대응하도록 만들어진 워크플로 파일을 찾음
대응하는 파일이 존재하는 경우, 하나 이상의 잡(job) 으로 구성된 워크플로를 실행
여러 단계의 스텝(step) 으로 구성된 작업은 필요에 따라 러너에서 실행
⛓ 구성요소 설명
구성요소 | 설명 |
---|---|
이벤트(Event) | 워크플로우를 트리거하는 조건 (예: push , pull_request , issue , schedule 등) |
워크플로우(Workflow) | 자동화 프로세스의 정의 단위. 하나 이상의 작업(Job)으로 구성되며, YAML 파일로 저장됨 |
작업(Job) | 워크플로우 내에서 실행되는 개별 작업 단위. 여러 단계(Step)로 구성되며, 병렬 또는 순차 실행 가능 |
단계(Step) | 작업(Job) 내에서 실행되는 개별 명령어 또는 액션. 순차적으로 실행됨 |
액션(Action) | 단계(Step)에서 실행되는 재사용 가능한 코드 블록. 마켓플레이스에서 가져오거나 직접 작성 가능 |
러너(Runner) | 작업(Job)을 실제로 실행하는 환경(가상머신 또는 컨테이너). GitHub 제공 러너 또는 자체 호스팅 러너 사용 가능 |
⛓ 워크플로 트리거 (Workflow Trigger)
워크플로를 자동으로 시작하게 만드는 조건 또는 이벤트
GitHub 저장소에서 발생하는 다양한 이벤트에 반응 가능
대표적인 트리거 종류
push
: 브랜치에 코드가 푸시되었을 때pull_request
: PR이 생성되거나 수정되었을 때schedule
: cron 표현식을 사용한 정기 실행workflow_dispatch
: 수동으로 실행 (버튼 클릭)issue
, release
, deployment
, fork
, watch
등 기타 GitHub 이벤트⛓ 잡 (Job)
jobs
키워드💡 Github Actions runner
- 깃허브 호스팅 러너 : https://github.com/actions/runner-images
- 자체 호스팅 러너 : https://github.com/actions/runner
⛓ VSCode에 github actions 확장기능 설치
.github/workflows
의 yaml 파일 편집, 확인, 실행, 검증🖥 .github/workflows/01helloWorld.yaml
name: Hello, Bzeromo?
on:
workflow_dispatch
jobs:
hello-world:
runs-on: ubuntu-22.04
steps:
- name: print hello message
run: echo "Hello, Github Actions!"
🖥 Push 이후
🖥 Run workflow
🖥 02build_gradle.yaml
(빌드하고 테스트 하기)
name: 마사이 마라 공원 gradle build
on:
workflow_dispatch
jobs:
gradle_build:
runs-on: ubuntu-22.04
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Grant execute permission
run: chmod +x gradlew
- name: build with gradle
run: ./gradlew clean build
- name: list build/libs directory
run: ls -al ./build/libs
- name: run springboot application
run: |
java -jar ./build/libs/massai_mara_park-0.0.1-SNAPSHOT.jar &
sleep 30
- name: run automated test #1
run: |
curl http://localhost:8080 || exit 1
- name: run automated test #2
run: |
curl http://localhost:8080/images || exit 1
- name: run automated test #3
run: |
curl http://localhost:8080/animal || exit 1
테스트 결과 잘 접속했음을 확인하였다.
(테스트는 한번에 그치고 이후 웹 접속은 불가능하다.)
🖥 03dockerfile_build.yaml
(빌드하고 테스트 하기)
name: 마사이 마라 공원 dockerfile build
on:
workflow_dispatch
jobs:
dockerfile_build:
runs-on: ubuntu-22.04
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup docker buildx
uses: docker/setup-buildx-action@v3
- name: Build Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: false
load: true
tags: massai_mara:v1
cache-from: type=gha
cache-to: type=gha,mode=max
- name: run docker container
run: |
docker run -d --name maratang -p 8080:8080 massai_mara:v1
sleep 20
docker ps
docker logs maratang
- name: run automated test #1
run: |
curl http://localhost:8080 || exit 1
- name: run automated test #2
run: |
curl http://localhost:8080/images || exit 1
- name: run automated test #3
run: |
curl http://localhost:8080/animal || exit 1
테스트 결과 잘 접속했음을 확인하였다.
(테스트는 한번에 그치고 이후 컨테이너 접근은 불가능하다.)
🖥 04compose_build.yaml
(빌드하고 테스트 하기)
name: 마사이 마라 공원 compose build
on:
workflow_dispatch
jobs:
compose_build:
runs-on: ubuntu-22.04
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: check docker compose version
run: docker compose version
- name: build with docker compose
run: docker compose build
- name: run with docker compose
run: |
docker compose up -d
sleep 30
docker compose ps
docker compose logs
- name: run automated test #1
run: |
curl http://localhost:8080 || exit 1
- name: run automated test #2
run: |
curl http://localhost:8080/images || exit 1
- name: run automated test #3
run: |
curl http://localhost:8080/animal || exit 1
테스트 결과 잘 접속했음을 확인하였다.
(테스트는 한번에 그치고 이후 컨테이너 접근은 불가능하다.)
🖥 05dockerhub.yaml
(도커 허브에 이미지 올리기)
name: 마사이 마라 공원 dockerhub
on:
workflow_dispatch
jobs:
dockerhub:
runs-on: ubuntu-22.04
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: login to docker hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: docker operations
run: |
docker build -t ${{ secrets.DOCKER_USERNAME }}/massai_mara:v1 .
docker push ${{ secrets.DOCKER_USERNAME }}/massai_mara:v1
- name: logout from dockerhub
if: always()
run: docker logout
❗ github repository secret에 docker username과 password를 변수로 저장하여 보안을 지킨다.
도커 허브에 이미지가 잘 올라와있음을 확인하였다.
🖥 06multiple_jobs.yaml
(아티팩트 활용하여 jobs 구분하기)
name: 마사이 마라 공원 multiple jobs
on:
workflow_dispatch
jobs:
build:
name: build JAR
runs-on: ubuntu-22.04
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Grant execute permission
run: chmod +x gradlew
- name: build with gradle
run: ./gradlew clean build
- name: list build/libs directory
run: ls -al ./build/libs
- name: Upload JAR artifact
uses: actions/upload-artifact@v4
with:
name: massai_mara_park-0.0.1-SNAPSHOT.jar
path: build/libs/*SNAPSHOT.jar
deploy:
name: deploy
needs: build
runs-on: ubuntu-22.04
steps:
- name: Setup JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: download JAR artifact
uses: actions/download-artifact@v4
with:
name: massai_mara_park-0.0.1-SNAPSHOT.jar
- name: check downloaded files
run: ls -al
- name: run springboot application
run: |
java -jar ./massai_mara_park-0.0.1-SNAPSHOT.jar &
sleep 30 || exit 1
# test:
# name: app test
# needs: deploy
# runs-on: ubuntu-22.04
# steps:
- name: run automated test #1
run: |
curl http://localhost:8080 || exit 1
- name: run automated test #2
run: |
curl http://localhost:8080/images || exit 1
- name: run automated test #3
run: |
curl http://localhost:8080/animal || exit 1
💡 새로운 Job에 셋업을 다시 해야 한다거나, 아티팩트로 저장했다가 다시 불러오는 등의 번거로움이 있지만 어쨌든 작업을 분류하여 단계별로 실행할 수 있기 때문에 이러한 방식을 사용한다.
README.md
(또는 문서 페이지) 상단에 삽입🖥 사용해보기(깃허브 워크플로 화면에서 바로 제작 가능)
Passing 표시가 떴음은 성공을 의미한다.
러너 옵션, 스텝, 액션 옵션 등을 활용해서 응용하는 법도 중요하지만 다음 기회에.... 아주 기본적인 것만 다루겠다는 약속은 지켰다.
⛓ 오픈 소스 자동화 서버로, 소프트웨어 개발 과정에서 코드 변경 사항을 자동으로 통합(빌드), 테스트, 배포하는 CI/CD(지속적 통합/지속적 배포) 도구
개발자가 코드를 저장소(Git 등)에 푸시하면 젠킨스가 이를 감지해 자동으로 빌드와 테스트를 실행하고, 필요하다면 배포까지 이어짐
이를 통해 반복적이고 오류가 발생하기 쉬운 작업을 자동화하여 개발 생산성과 소프트웨어 품질을 크게 높일 수 있음
⛓ 역사
2004년 Sun Microsystems의 고스케 카와구치(Kohsuke Kawaguchi)가 "Hudson
"이라는 이름으로 프로젝트 시작
2011년 Oracle의 Sun 인수 이후 오픈소스 커뮤니티와의 마찰로
프로젝트가 분리되어 "Jenkins
"로 이름 변경
현재는 전 세계적으로 가장 널리 사용되는 CI/CD 자동화 서버로 자리잡음
💡 잘 비교해보고 자신의 프로젝트에 알맞을 것으로 쓰자.
구분 젠킨스 (Jenkins) 깃허브 액션 (GitHub Actions) 호스팅 방식 자체 호스팅 (서버 직접 구축·운영 필요) SaaS(클라우드) 기본, 자체 호스팅 러너도 지원 설정/학습 난이도 복잡, 수동 설정 필요, 러닝커브 높음 GitHub과 통합, 설정 간편, 러닝커브 낮음 구성 언어 Groovy(파이프라인), XML 등 YAML(워크플로우) 확장성 강력한 플러그인 생태계, 고도의 커스터마이징 가능 GitHub Marketplace의 액션 활용, 커스텀 액션 제작 가능 유지보수 서버, 플러그인, 보안 등 직접 관리 필요 GitHub에서 인프라 관리, 자동 확장 스케일링 수동 확장 (노드 직접 추가) 자동 확장 (클라우드 러너), 자체 러너 추가 가능 비용 오픈소스 (서버 직접 운영 시 인프라 비용 발생) 퍼블릭 저장소 무료, 프라이빗 저장소는 사용량 과금 GitHub 연동 플러그인 필요, 일부 GitHub 이벤트 미지원 GitHub 이벤트와 완벽 연동, PR/이슈 등 자동화 용이 UI/시각화 별도 웹 UI, 커스텀 대시보드 지원 GitHub 내 통합 UI, PR/커밋과 연계 병렬 처리 직접 설정 필요, 병렬화 유연함 기본적으로 job 병렬 실행 지원 보안 직접 설정 및 관리 필요 GitHub 보안 정책 적용, 비밀 관리 내장 프로젝트 규모 대규모·복잡한 프로젝트, 다양한 기술스택에 적합 소규모~중규모, GitHub 중심의 프로젝트에 적합
Jenkins의 본격적인 사용 방법은 다음으로...