zioinfo-mail/manual/20_zio서버_CICD_가이드.md
DESKTOP-TKLFCPR\ython 11c670f2a0 refactor: 101.79.17.164 → zioinfo.co.kr 전체 도메인 변환 + Manager UI 배포
- 37개 파일 IP → zioinfo.co.kr 치환 (소스/매뉴얼/설정/하네스)
- Manager DrConsole/NetworkConsole/CsapConsole 빌드 + /var/www/manager/ 배포
- 테스트: Manager HTTP 200, ITSM 신규 API 7개 전체 200

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 10:09:17 +09:00

10 KiB

zio-server CI/CD 파이프라인 가이드

서버: zio-server | IP: zioinfo.co.kr
작성일: 2026-05-30


1. CI/CD 아키텍처

┌─────────────────────────────────────────────────────────┐
│                    개발자 로컬 PC                         │
│  코드 수정 → git commit → git push gitea main:main      │
└──────────────────────┬──────────────────────────────────┘
                       │ HTTP push (포트 3000)
                       ▼
┌─────────────────────────────────────────────────────────┐
│              Gitea (zioinfo.co.kr:3000)                  │
│  zio/zioinfo-web 저장소 → 웹훅 트리거                   │
└──────────────────────┬──────────────────────────────────┘
                       │ POST http://localhost:9999/
                       ▼
┌─────────────────────────────────────────────────────────┐
│         ZioInfo Deploy Server (포트 9999)                │
│  /opt/zioinfo/deploy_server.py                          │
│                                                         │
│  ① git pull                (소스 최신화)                │
│  ② npm ci && npm run build (React SPA 빌드)             │
│  ③ mvn clean package       (Spring Boot JAR 빌드)       │
│  ④ cp app.jar /opt/zioinfo/app/                        │
│  ⑤ cp static/* /var/www/zioinfo/                       │
│  ⑥ systemctl restart zioinfo                           │
└──────────────────────┬──────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────┐
│          Spring Boot (포트 8082)                         │
│  /opt/zioinfo/app/app.jar                               │
│  DB: /opt/zioinfo/app/data/zioinfo.db (SQLite)         │
└──────────────────────┬──────────────────────────────────┘
                       │ proxy_pass
                       ▼
┌─────────────────────────────────────────────────────────┐
│          Nginx (포트 80)                                  │
│  /var/www/zioinfo/  → React SPA 정적 파일               │
│  /api/              → localhost:8082 프록시              │
└─────────────────────────────────────────────────────────┘
                       │
                       ▼
              http://zioinfo.co.kr   (서비스 엔드포인트)

2. 로컬 개발 환경 설정

2-1. Git remote 설정 (최초 1회)

# 현재 remote 확인
git remote -v

# Gitea remote 추가
cd C:\GUARDiA\workspace\zioinfo-web
git remote add gitea http://zio:Zio%40Admin2026%21@zioinfo.co.kr:3000/zio/zioinfo-web.git

# 설정 확인
git remote -v
# gitea   http://zio:...@zioinfo.co.kr:3000/zio/zioinfo-web.git (fetch)
# gitea   http://zio:...@zioinfo.co.kr:3000/zio/zioinfo-web.git (push)
# origin  https://github.com/... (fetch)    ← GitHub (기존)

2-2. 코드 배포

# 1. 변경 사항 커밋
git add .
git commit -m "feat: 기능 설명"

# 2. Gitea에 push → 자동 빌드·배포 시작
git push gitea main:main

# 3. 배포 진행 상황 확인 (SSH 접속 후)
ssh root@zioinfo.co.kr "tail -f /var/log/zioinfo/deploy.log"

3. 배포 서버 구성

3-1. 파일 위치

파일 경로 설명
배포 스크립트 /opt/zioinfo/deploy_server.py 웹훅 수신 + 빌드·배포 실행
소스 코드 /opt/zioinfo/src/ Gitea 클론 경로
실행 JAR /opt/zioinfo/app/app.jar 배포된 Spring Boot JAR
정적 파일 /var/www/zioinfo/ 배포된 React 빌드 결과물
배포 로그 /var/log/zioinfo/deploy.log 빌드·배포 과정 기록

3-2. systemd 서비스

# /etc/systemd/system/zioinfo-deploy.service
[Unit]
Description=ZioInfo CI/CD Webhook Server
After=network.target

[Service]
User=root
ExecStart=/usr/bin/python3 /opt/zioinfo/deploy_server.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
# 서비스 관리
systemctl status zioinfo-deploy
systemctl restart zioinfo-deploy
journalctl -u zioinfo-deploy -n 20 --no-pager

3-3. 웹훅 보안

배포 서버는 HMAC-SHA256으로 요청을 검증합니다.

# 검증 키: zioinfo-deploy-2026
# Gitea 웹훅 설정의 Secret 값과 동일

4. Gitea 웹훅 설정

4-1. 현재 웹훅 확인

# API로 웹훅 목록 조회
curl -s http://localhost:3000/api/v1/repos/zio/zioinfo-web/hooks \
  -u "zio:Zio@Admin2026!" | python3 -m json.tool

# 브라우저에서 확인
# http://zioinfo.co.kr:3000/zio/zioinfo-web/settings/hooks

4-2. 웹훅 재등록 (필요 시)

# 기존 웹훅 삭제
curl -s -X DELETE http://localhost:3000/api/v1/repos/zio/zioinfo-web/hooks/1 \
  -u "zio:Zio@Admin2026!"

# 새 웹훅 등록 (Python)
python3 << 'EOF'
import urllib.request, json, base64

data = json.dumps({
    "type": "gitea",
    "active": True,
    "config": {
        "url": "http://localhost:9999/",
        "content_type": "json",
        "secret": "zioinfo-deploy-2026"
    },
    "events": ["push"]
}).encode()

cred = base64.b64encode(b"zio:Zio@Admin2026!").decode()
req = urllib.request.Request(
    "http://localhost:3000/api/v1/repos/zio/zioinfo-web/hooks",
    data=data,
    headers={"Content-Type": "application/json", "Authorization": f"Basic {cred}"})
resp = urllib.request.urlopen(req)
d = json.loads(resp.read())
print(f"Webhook ID: {d.get('id')}")
EOF

5. 배포 이력 및 롤백

5-1. 배포 이력 확인

# Gitea 커밋 이력
curl -s "http://localhost:3000/api/v1/repos/zio/zioinfo-web/commits?limit=10" \
  -u "zio:Zio@Admin2026!" | python3 -c "
import json, sys
commits = json.load(sys.stdin)
for c in commits:
    print(c['sha'][:8], c['commit']['message'][:60], '|', c['commit']['author']['date'][:10])
"

# 서버 소스 로컬 이력
ssh root@zioinfo.co.kr "git -C /opt/zioinfo/src log --oneline -10"

5-2. 특정 버전으로 롤백

ssh root@zioinfo.co.kr

# 이전 커밋으로 체크아웃
cd /opt/zioinfo/src
git log --oneline -5        # 커밋 해시 확인
git checkout <커밋해시>     # 원하는 버전으로 변경

# 빌드 및 재배포
cd frontend && npm ci && npm run build
cd ../backend && mvn clean package -DskipTests -q
cp target/zioinfo-web-*.jar /opt/zioinfo/app/app.jar
cp -r src/main/resources/static/. /var/www/zioinfo/
systemctl restart zioinfo

# 최신 버전으로 복구
git checkout main

6. Jenkins 파이프라인 (심화 설정)

Jenkins 초기 설정 완료 후 사용 가능

6-1. Jenkinsfile 위치

workspace/zioinfo-web/Jenkinsfile   (홈페이지 파이프라인)
itsm/Jenkinsfile                    (GUARDiA ITSM 파이프라인)

6-2. 홈페이지 Jenkinsfile 주요 단계

pipeline {
    agent any
    stages {
        stage('Frontend Build') { /* npm ci + npm run build */ }
        stage('Backend Build')  { /* mvn clean package */      }
        stage('Test')           { /* mvn test */               }
        stage('Deploy') {
            when { branch 'main' }
            /* JAR 복사 + 정적파일 배포 + systemctl restart */
        }
    }
}

6-3. Jenkins Job 수동 트리거

# Jenkins API로 빌드 트리거 (초기 설정 완료 후)
CRUMB=$(curl -s -u admin:Admin@2026! \
  http://localhost:8080/crumbIssuer/api/json | python3 -c \
  "import json,sys; print(json.load(sys.stdin)['crumb'])")

curl -u admin:Admin@2026! -X POST \
  http://localhost:8080/job/zioinfo-web/build \
  -H "Jenkins-Crumb: $CRUMB"

7. 트러블슈팅

7-1. push 후 자동 배포가 안 될 때

# 1. 웹훅 서버 상태 확인
systemctl is-active zioinfo-deploy

# 2. 웹훅 서버 로그
journalctl -u zioinfo-deploy -n 20 --no-pager

# 3. 수동 트리거 테스트
curl -s -X POST http://localhost:9999/ \
  -H "Content-Type: application/json" -d '{}'

# 4. 배포 로그 실시간 확인
tail -f /var/log/zioinfo/deploy.log

7-2. 빌드 실패 시

# 빌드 로그에서 오류 확인
grep -i "error\|failed\|fail" /var/log/zioinfo/deploy.log | tail -20

# npm 빌드 오류 재현
cd /opt/zioinfo/src/frontend
npm ci --legacy-peer-deps
npm run build

# Maven 빌드 오류 재현
cd /opt/zioinfo/src/backend
mvn clean package -DskipTests

7-3. Spring Boot 재시작 실패

# 상세 로그 확인
journalctl -u zioinfo --since "5 minutes ago" --no-pager
tail -50 /var/log/zioinfo/spring.log

# 포트 충돌 확인 (8082)
ss -tlnp | grep 8082
kill -9 <PID>   # 기존 프로세스 강제 종료

# 수동 실행 (디버깅)
java -jar /opt/zioinfo/app/app.jar --server.port=8082

8. GUARDiA ITSM 배포

GUARDiA는 별도 Jenkinsfile 기반 파이프라인 사용

8-1. 수동 배포

# Gitea에서 최신 코드 반영
cd /opt/guardia/app
git pull http://zio:Zio%40Admin2026%21@localhost:3000/zio/guardia-itsm.git main

# 패키지 업데이트
/opt/guardia/venv/bin/pip install -r requirements.txt -q

# 서비스 재시작
systemctl restart guardia
sleep 3 && systemctl is-active guardia

# 헬스체크
curl -s http://localhost:8001/docs -o /dev/null -w "HTTP %{http_code}"

문서 버전: 1.0 | 최종 수정: 2026-05-30