Files
sam-docs/guides/jenkins-setup-guide.md
김보곤 86ea901de0 docs: [guides] Jenkins 셋업 가이드 작성
- Jenkins 이해하기 (용어, CI/CD 개념)
- 사전 준비 (Swap, Java, 방화벽)
- 설치 및 초기 설정
- 필수 플러그인 설치
- Credential 설정 (SSH, Gitea, Slack)
- Gitea Webhook 연동
- Jenkinsfile 작성 가이드
- 트러블슈팅 & FAQ
2026-02-26 20:36:00 +09:00

7.9 KiB

Jenkins CI/CD 셋업 가이드

작성일: 2026-02-22 상태: 설계 확정 대상: SAM 프로젝트 개발팀장


1. Jenkins 이해하기

1.1 Jenkins란

Jenkins는 오픈소스 자동화 서버다. 코드를 Push하면 자동으로 빌드, 테스트, 배포를 수행한다.

1.2 현재 수동 vs 자동화 비교

현재: 개발자 → git push → SSH 접속 → git pull → composer install → 재시작 (수동, 5~10분)
목표: 개발자 → git push → Jenkins 자동 감지 → 빌드/테스트/배포 (자동, Slack 알림)

1.3 핵심 용어

용어 설명
Job 하나의 작업 단위 (예: sam-api-deploy)
Pipeline Stage를 순서대로 실행하는 흐름
Stage / Step Pipeline의 단계 / 단계 내 개별 명령
Credential Jenkins에 저장하는 비밀 정보 (SSH 키, 토큰)
Webhook Gitea가 Push 이벤트를 Jenkins에 알려주는 HTTP 호출

2. 사전 준비

항목
IP 114.203.209.83
CPU/RAM 2코어 / 3.8GB
Gitea http://114.203.209.83:3000

경고: RAM이 부족하므로 Swap 추가가 필수다.

2.1 Swap 4GB 추가

sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
free -h  # 확인

2.2 Java 17 + 방화벽

sudo apt update && sudo apt install -y openjdk-17-jdk
java -version  # 17.x.x 확인

sudo ufw allow 8080/tcp  # Jenkins 웹 UI 포트

3. Jenkins 설치

3.1 패키지 설치

curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.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 update && sudo apt install -y jenkins
sudo systemctl start jenkins && sudo systemctl enable jenkins

3.2 초기 설정

sudo cat /var/lib/jenkins/secrets/initialAdminPassword  # 초기 비밀번호
  1. http://114.203.209.83:8080 접속 → 비밀번호 입력
  2. Install suggested plugins 선택 → 설치 대기 (3~5분)
  3. 관리자 계정 생성 (Username: admin)
  4. Jenkins URL: http://114.203.209.83:8080/Save and Finish

4. 필수 플러그인 설치

Jenkins 관리 → Plugins → Available plugins 에서 설치한다.

플러그인 역할 필수
Git plugin 소스 코드 체크아웃 🔴
Pipeline Jenkinsfile 지원 🔴
SSH Agent SSH 키로 운영 서버 배포 🔴
Generic Webhook Trigger Gitea Push 이벤트 수신 🔴
Slack Notification 배포 결과 Slack 알림 🟡
NodeJS React 빌드용 Node.js 🟡

참고: Git plugin, Pipeline은 suggested plugins에 포함되어 이미 설치되었을 수 있다.

NodeJS 설정: Jenkins 관리 → Tools → NodeJS installations → Add NodeJS → Name: NodeJS-20, Version: 20.x


5. Credential 설정

5.1 SSH 키 생성 (Jenkins → 운영 서버)

# Jenkins 서버에서 실행
sudo su - jenkins
ssh-keygen -t ed25519 -C "jenkins@sam" -f ~/.ssh/id_ed25519 -N ""
cat ~/.ssh/id_ed25519.pub  # 이 값을 운영 서버에 등록
exit

# 운영 서버에서 실행 (공개키 등록)
echo "ssh-ed25519 AAAA... jenkins@sam" >> /home/deploy/.ssh/authorized_keys

5.2 Jenkins Credential 등록

Jenkins 관리 → Credentials → (global) → Add Credentials

Credential Kind ID 내용
SSH 키 SSH Username with private key prod-server-ssh ~jenkins/.ssh/id_ed25519 비밀키
Gitea 토큰 Username with password gitea-token Gitea 사용자명 + API 토큰
Slack URL Secret text slack-webhook Slack Incoming Webhook URL
# SSH 비밀키 확인 (Jenkins에 붙여넣기)
sudo cat /var/lib/jenkins/.ssh/id_ed25519
❌ Jenkinsfile에 비밀번호/토큰/키를 하드코딩 금지
✅ 모든 비밀 정보는 Jenkins Credential에 등록 후 credentials('ID')로 참조

6. Gitea Webhook 연동

6.1 Jenkins Pipeline Job 생성

  1. New Item → 이름: sam-api-deployPipeline 선택
  2. Build Triggers: Generic Webhook Trigger 체크, Token: sam-api
  3. Pipeline: Pipeline script from SCM → Git
    • URL: http://114.203.209.83:3000/SamProject/sam-api.git
    • Credentials: gitea-token
    • Branch: */main
    • Script Path: Jenkinsfile

6.2 전체 Job 목록

Job 이름 저장소 브랜치 Token
sam-api-deploy sam-api.git */main sam-api
sam-mng-deploy sam-manage.git */master sam-mng
sam-react-deploy sam-react-prod.git */master sam-react
sam-sales-deploy sam-sales.git */main sam-sales

6.3 Gitea Webhook 설정

각 저장소: Settings → Webhooks → Add Webhook → Gitea

항목
Target URL http://114.203.209.83:8080/generic-webhook-trigger/invoke?token=sam-api
Content Type application/json
Trigger On Push Events
Branch filter main

Test Delivery → 응답 200이면 성공


7. Jenkinsfile 작성 가이드

7.1 기본 구조

pipeline {
    agent any
    environment { KEY = 'value' }
    stages {
        stage('단계명') {
            steps { sh 'command' }
        }
    }
    post {
        success { slackSend channel: '#sam-deploy', message: "성공" }
        failure { slackSend channel: '#sam-alerts', message: "실패" }
    }
}

7.2 SAM 저장소별 Jenkinsfile

상세 코드는 plans/production-deployment-plan.md 4.4절 참조

저장소 Stage 흐름 특이사항
sam-api Checkout → Lint → Test → Deploy migrate --force 포함
sam-manage Checkout → Lint → Build Assets → Deploy 마이그레이션 없음
sam-react-prod Checkout → Install → Lint → Build → Package → Deploy tar.gz로 전송
sam-sales Deploy 간소화 (git pull + composer)

7.3 배치 방법

각 저장소 루트Jenkinsfile 생성 → git add Jenkinsfile && git commit -m "chore: Jenkinsfile 추가" → push


8. 트러블슈팅

8.1 빌드 실패

Jenkins 대시보드 → Job → 빌드 번호 → Console Output 에서 에러 로그 확인

8.2 SSH 권한 오류 (Permission denied)

sudo su - jenkins && ssh deploy@운영서버IP  # 수동 테스트
# 운영 서버에서 authorized_keys 등록 확인
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys

8.3 메모리 부족

# Jenkins 힙 메모리 제한: /etc/default/jenkins에 JAVA_ARGS="-Xmx512m" 추가
sudo systemctl restart jenkins
# Job 설정 → Discard old builds → 최대 빌드 수: 10

8.4 Webhook 미동작

# 수동 트리거 테스트
curl -X POST "http://114.203.209.83:8080/generic-webhook-trigger/invoke?token=sam-api"
# Gitea: Webhooks → Recent Deliveries → 응답 코드 확인 (200=정상, 403=Token 불일치)

8.5 React 빌드 OOM

# Jenkinsfile에서 메모리 증가
sh 'export NODE_OPTIONS="--max-old-space-size=2048" && npm run build'
# 실패 시 로컬(WSL)에서 react/deploy.sh 사용

경고: 개발 서버에서 React 빌드 실패 시 로컬에서 deploy.sh를 사용한다.


관련 문서


최종 업데이트: 2026-02-22