# arko_renual — csv.wise.ai.kr 자동 배포 파이프라인 # # [개발 PC] git push → 이 워크플로가 자동 실행 # [웹서버] 빌드(JDK8/Maven) → WAR 을 WAS 로 전송 # [WAS] ROOT 재전개 + 환경설정 주입 + Tomcat 재기동 + 헬스체크(실패 시 자동 롤백) # [웹서버] SSH 터널 경유로 공개 확인 (https://csv.wise.ai.kr) # # 그 세 걸음이 곧 지정된 경로다: PC → git → web → was(db) # # ┌ 왜 웹서버에서 빌드하나 ────────────────────────────────────────────────┐ # │ WAS(27.255.76.2)는 64코어지만 llama-server 가 200G+ 를 점유해 가용 │ # │ 메모리가 3G 안팎이다. 거기서 Maven(힙 1G)을 돌리면 LLM 서비스가 OOM 될 │ # │ 수 있다. 웹서버(4코어/여유 4G)는 빌드 외 부하가 없어 여기서 빌드한다. │ # └────────────────────────────────────────────────────────────────────────┘ # # ※ Gitea 1.22.3 은 workflow_dispatch(수동 실행 버튼)를 지원하지 않는다 — # 넣으면 워크플로가 Actions 목록에 아예 뜨지 않는다. 트리거는 push 하나만 둔다. # 수동 재배포는 WAS 에서 직접: # ssh -J <웹서버> claudeops@27.255.76.2 \ # 'bash /opt/arko-app/deploy/arko-deploy.sh /opt/arko-app/incoming/arko.war' name: deploy-wise on: push: branches: - master # 현재 배포 대상은 이 브랜치다. master 는 7커밋 뒤처져 있고 이관된 DB 스키마와 # 맞지 않는다. master 로 병합한 뒤에는 아래 줄을 지워도 된다. - feature/privacy-access-control-policy paths-ignore: # 문서만 바뀐 커밋으로 재배포하지 않는다 - '**.md' - '**.docx' - '**.pptx' - '**.hwp' - 'docs/**' - '_workspace/**' - '_workspace_privacy/**' concurrency: group: arko-wise-deploy cancel-in-progress: false # 배포 도중 취소되면 ROOT 가 반쪽 상태로 남는다 env: JAVA_HOME: /usr/lib/jvm/java-1.8.0-openjdk MVN: /opt/maven/bin/mvn WAS_HOST: 27.255.76.2 WAS_USER: claudeops WAS_KEY: /root/.ssh/id_ed25519 APP_HOME: /opt/arko-app SITE_URL: https://csv.wise.ai.kr/ jobs: deploy: runs-on: arko-web timeout-minutes: 25 steps: # ⚠ lfs: true 를 주지 않는다 — 러너에 git-lfs 가 없으면 checkout 자체가 죽는다. - uses: actions/checkout@v4 - name: 사전 점검 run: | set -e df -h /opt | tail -1 free -h | head -2 # 터널이 살아 있어야 배포 후 확인이 가능하다 systemctl is-active arko-was-tunnel || echo "::warning::터널이 죽어 있다 — 배포 후 확인이 실패할 수 있다" - name: 빌드 (JDK 8) run: | set -e export JAVA_HOME="$JAVA_HOME" export MAVEN_OPTS="-Xmx1024m" # Maven 3.8+ 는 HTTP 저장소를 차단한다. eGov 2.7 은 HTTP 저장소(terracotta 등)를 # 쓰므로 3.6.3 을 고정해서 쓴다. 3.8 로 올리면 의존성 해석부터 실패한다. "$MVN" -B clean package -DskipTests ls -lh target/arko.war - name: 산출물 검증 run: | set -e # 바이트코드 major=51(Java 7). JDK 11/17 로 잘못 빌드되면 WAS 에서 못 뜬다. CLS=$(find target/classes -name '*.class' | head -1) VER=$(od -An -t d1 -j 7 -N 1 "$CLS" | tr -d ' ') echo "바이트코드 major=$VER (51이어야 정상)" [ "$VER" = "51" ] || { echo "::error::JDK 8 이 아닌 컴파일러로 빌드됐다"; exit 1; } # 파이프 없이 한 번만 읽어 검사한다(파이프+pipefail 조합이 정상 WAR 을 오판한 전례가 있다) WAR_LIST=$(unzip -l target/arko.war) grep -q "WEB-INF/web.xml" <<< "$WAR_LIST" || { echo "::error::정상 WAR 이 아니다"; exit 1; } - name: WAS 로 전송 run: | set -e SSH="ssh -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new -i $WAS_KEY" $SSH "$WAS_USER@$WAS_HOST" "mkdir -p $APP_HOME/incoming $APP_HOME/deploy" scp -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new -i "$WAS_KEY" \ target/arko.war "$WAS_USER@$WAS_HOST:$APP_HOME/incoming/arko.war" # 배포 스크립트도 매번 저장소본으로 덮어쓴다. # (이전 파이프라인에서 서버 사본이 저장소본과 갈라져 고친 내용이 반영되지 않는 # 사고가 있었다. 저장소를 유일한 원본으로 둔다.) scp -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new -i "$WAS_KEY" \ deploy/wise/arko-deploy.sh "$WAS_USER@$WAS_HOST:$APP_HOME/deploy/arko-deploy.sh" # 잘린 전송을 잡는다 — 전례가 있어 크기를 반드시 대조한다 LOCAL_MD5=$(md5sum target/arko.war | cut -d' ' -f1) REMOTE_MD5=$($SSH "$WAS_USER@$WAS_HOST" "md5sum $APP_HOME/incoming/arko.war | cut -d' ' -f1") echo "local=$LOCAL_MD5 remote=$REMOTE_MD5" [ "$LOCAL_MD5" = "$REMOTE_MD5" ] || { echo "::error::전송된 WAR 이 손상됐다"; exit 1; } - name: WAS 배포 run: | set -e ssh -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new -i "$WAS_KEY" \ "$WAS_USER@$WAS_HOST" "chmod +x $APP_HOME/deploy/arko-deploy.sh && bash $APP_HOME/deploy/arko-deploy.sh $APP_HOME/incoming/arko.war" - name: 공개 확인 run: | set -e # 터널 경유(웹서버 → WAS) TUN=$(curl -s -o /dev/null -w "%{http_code}" --max-time 30 http://127.0.0.1:11060/ || echo 000) echo "터널 127.0.0.1:11060 → HTTP $TUN" # 공개 URL. 첫 요청은 JSP 컴파일로 15초 이상 걸릴 수 있다. CODE=000 for _ in $(seq 1 6); do CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 60 "$SITE_URL" || echo 000) case "$CODE" in 200|302) break ;; esac sleep 5 done echo "$SITE_URL → HTTP $CODE" case "$CODE" in 200|302) echo "배포 정상" ;; *) echo "::error::공개 URL 응답 없음 (HTTP $CODE) — 터널(arko-was-tunnel) 상태를 확인할 것"; exit 1 ;; esac