// KINTEX 자동전시시스템 — CI/CD 파이프라인 (git push → Gitea webhook → 빌드 → 배포 → 헬스체크) // 실행 노드: 서버(101.79.17.164) Jenkins. 프론트(vite)→/var/www/kintex, 백엔드(bootJar)→/opt/kintex/app/app.jar, // kintex.service + kintex-nanobanana.service 재기동. 배포 단계는 sudo(deploy_kintex.sh) 위임. // ※ 상시 자동배포는 deploy_server.py(webhook, 포트 9999)의 kintex 블록이 1차 경로. 본 파이프라인은 Jenkins 병행 트랙. pipeline { agent any options { timeout(time: 40, unit: 'MINUTES') timestamps() buildDiscarder(logRotator(numToKeepStr: '10')) } environment { WEB_ROOT = '/var/www/kintex' APP_JAR = '/opt/kintex/app/app.jar' BACKEND_PORT = '8021' } stages { stage('Checkout') { steps { checkout scm } } stage('Frontend Build') { steps { dir('src/frontend') { sh 'npm ci --silent || npm install --silent' sh 'NODE_OPTIONS=--max-old-space-size=4096 npm run build' } } } stage('Backend Build') { steps { dir('src/backend') { sh 'chmod +x gradlew' sh './gradlew clean bootJar -x test -q --no-daemon' } } } stage('Verify Jar') { steps { sh ''' JAR=$(ls -1 src/backend/build/libs/kintex-backend-*.jar | grep -v plain | head -1) [ -n "$JAR" ] || { echo "jar not found"; exit 1; } unzip -l "$JAR" | grep -q 'BOOT-INF/classes/com/zioinfo/kintex/KintexApplication.class' \ || { echo "invalid jar (no main class)"; exit 1; } echo "jar OK: $JAR" ''' } } stage('Deploy') { steps { // 권한 필요한 배포는 deploy_kintex.sh 로 위임(sudo NOPASSWD 권장). sh 'sudo /opt/kintex/deploy_kintex.sh "$WORKSPACE"' } } stage('Health Check') { steps { sh ''' for i in $(seq 1 15); do code=$(curl -s -m 6 -o /dev/null -w '%{http_code}' http://127.0.0.1:'"$BACKEND_PORT"'/health || true) echo "health try $i: $code" if [ "$code" = "200" ]; then exit 0; fi sleep 5 done echo "health check failed"; systemctl is-active kintex.service || true; exit 1 ''' } } } post { success { echo 'KINTEX 배포 성공 (kintex.zioinfo.co.kr, 백엔드 8021)' } failure { echo 'KINTEX 빌드/배포 실패 — 롤백은 deploy_kintex.sh 가 수행' } } }