docs: [guides] Jenkins 셋업 가이드 작성
- Jenkins 이해하기 (용어, CI/CD 개념) - 사전 준비 (Swap, Java, 방화벽) - 설치 및 초기 설정 - 필수 플러그인 설치 - Credential 설정 (SSH, Gitea, Slack) - Gitea Webhook 연동 - Jenkinsfile 작성 가이드 - 트러블슈팅 & FAQ
This commit is contained in:
4
INDEX.md
4
INDEX.md
@@ -20,6 +20,7 @@
|
||||
| **게시판** | `specs/board-system-spec.md` | 게시판 시스템 설계 |
|
||||
| **단가관리** | `rules/pricing-policy.md` | 원가/판매가 계산, 리비전 관리 |
|
||||
| **운영 배포** | `plans/production-deployment-plan.md` | 운영 환경 배포 계획 (CI/CD, 서버 아키텍처) |
|
||||
| **서버 동작 원리** | `guides/server-how-it-works.md` | 요청 흐름, 배포 원리 이해 |
|
||||
| **과금정책 (고객용)** | `rules/customer-pricing.md` | 고객 안내용 서비스 요금표 |
|
||||
| **과금정책 (파트너)** | `rules/partner-commission.md` | 영업파트너 수당 체계 및 정산 |
|
||||
| **과금정책 (내부용)** | `rules/billing-policy.md` | 내부용 원가/마진/코드참조 (CONFIDENTIAL) |
|
||||
@@ -102,6 +103,8 @@ docs/
|
||||
| [item-management-migration.md](guides/item-management-migration.md) | Item 시스템 전환 가이드 | 마이그레이션 작업 전 |
|
||||
| [project-launch-roadmap.md](guides/project-launch-roadmap.md) | 런칭 준비 현황 | 런칭 관련 작업 시 |
|
||||
| [production-env-sync.md](guides/production-env-sync.md) | 운영 전환 시 .env 동기화 절차 | 테스트→운영 전환 시 |
|
||||
| [server-how-it-works.md](guides/server-how-it-works.md) | 서버 동작 원리 초보자 가이드 | 신규 합류 시 |
|
||||
| [jenkins-setup-guide.md](guides/jenkins-setup-guide.md) | Jenkins CI/CD 셋업 가이드 | Jenkins 설치/설정 시 |
|
||||
|
||||
### quickstart/ - 빠른 시작
|
||||
> 핵심 규칙 요약, 자주 쓰는 명령어
|
||||
@@ -148,6 +151,7 @@ docs/
|
||||
| [boards/mng-implementation.md](features/boards/mng-implementation.md) | MNG 게시판 구현 상세 |
|
||||
| [hr/hr-api-analysis.md](features/hr/hr-api-analysis.md) | HR API 분석 (근태/직원/부서) |
|
||||
| [quotes/README.md](features/quotes/README.md) | 견적 시스템 분석 (BOM 계산, 10단계 로직) |
|
||||
| [academy/fire-shutter-image-prompts.md](features/academy/fire-shutter-image-prompts.md) | 방화셔터 백과사전 이미지 생성 프롬프트 (Gemini용) |
|
||||
|
||||
### projects/ - 프로젝트별 문서
|
||||
|
||||
|
||||
274
guides/jenkins-setup-guide.md
Normal file
274
guides/jenkins-setup-guide.md
Normal file
@@ -0,0 +1,274 @@
|
||||
# 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 추가
|
||||
|
||||
```bash
|
||||
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 + 방화벽
|
||||
|
||||
```bash
|
||||
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 패키지 설치
|
||||
|
||||
```bash
|
||||
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 초기 설정
|
||||
|
||||
```bash
|
||||
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 → 운영 서버)
|
||||
|
||||
```bash
|
||||
# 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 |
|
||||
|
||||
```bash
|
||||
# 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-deploy` → **Pipeline** 선택
|
||||
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 기본 구조
|
||||
|
||||
```groovy
|
||||
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`)
|
||||
|
||||
```bash
|
||||
sudo su - jenkins && ssh deploy@운영서버IP # 수동 테스트
|
||||
# 운영 서버에서 authorized_keys 등록 확인
|
||||
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
|
||||
```
|
||||
|
||||
### 8.3 메모리 부족
|
||||
|
||||
```bash
|
||||
# Jenkins 힙 메모리 제한: /etc/default/jenkins에 JAVA_ARGS="-Xmx512m" 추가
|
||||
sudo systemctl restart jenkins
|
||||
# Job 설정 → Discard old builds → 최대 빌드 수: 10
|
||||
```
|
||||
|
||||
### 8.4 Webhook 미동작
|
||||
|
||||
```bash
|
||||
# 수동 트리거 테스트
|
||||
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
|
||||
|
||||
```bash
|
||||
# Jenkinsfile에서 메모리 증가
|
||||
sh 'export NODE_OPTIONS="--max-old-space-size=2048" && npm run build'
|
||||
# 실패 시 로컬(WSL)에서 react/deploy.sh 사용
|
||||
```
|
||||
|
||||
> **경고: 개발 서버에서 React 빌드 실패 시 로컬에서 `deploy.sh`를 사용한다.**
|
||||
|
||||
---
|
||||
|
||||
## 관련 문서
|
||||
|
||||
- [운영 환경 배포 계획서](../plans/production-deployment-plan.md) - Jenkinsfile 상세, 브랜치 전략
|
||||
- [.env 동기화 절차](production-env-sync.md) - 환경 변수 분리
|
||||
- [Docker 환경 스펙](../specs/docker-setup.md) - 현재 개발 환경
|
||||
|
||||
---
|
||||
|
||||
**최종 업데이트**: 2026-02-22
|
||||
Reference in New Issue
Block a user