From 7d1182ecc3be8a6048b51ce19fc21043b613fef8 Mon Sep 17 00:00:00 2001 From: URP2026 Date: Wed, 29 Jul 2026 17:57:17 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B0=B0=ED=8F=AC=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=EB=AC=B8=EC=84=9C=ED=99=94=20=EB=B0=8F=20runner=20=EC=A7=81?= =?UTF-8?q?=EA=B2=B0=20=EC=9E=AC=EB=93=B1=EB=A1=9D=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit runner를 nginx 경유(https://git.zioinfo.co.kr)로 등록하면 declare까지는 되는데 작업을 가져오지 않고 재기동해야만 처리하는 문제가 있었다. long-poll이 nginx의 proxy_buffering(기본 on)에 물리는 것으로 보인다. Gitea가 같은 서버에 있으므로 127.0.0.1:9003 직결로 재등록해 해결했고, 재발 시 쓰도록 스크립트로 남긴다. deploy/README.md에 전체 구조(개발 WAS/DB 단일, 운영은 웹 티어 전용), 접속 방향이 양쪽으로 다른 이유(NAT), 키 제한 범위, 알려진 이슈를 정리했다. --- deploy/README.md | 112 +++++++++++++++++++++++++++++ deploy/dev/06-runner-reregister.sh | 43 +++++++++++ 2 files changed, 155 insertions(+) create mode 100644 deploy/README.md create mode 100644 deploy/dev/06-runner-reregister.sh diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 0000000..efb2c7f --- /dev/null +++ b/deploy/README.md @@ -0,0 +1,112 @@ +# arko_renual 배포 구성 + +## 전체 구조 + +``` + ┌──────────────────────────────────────────────────────────┐ + git push ─────>│ Gitea (git.zioinfo.co.kr) + act_runner │ + │ ※ runner는 nginx를 거치지 않고 127.0.0.1:9003 직결 │ + └────────────────────────┬─────────────────────────────────┘ + │ + ┌────────────────────────▼─────────────────────────────────┐ + │ 개발서버 zio-server (101.79.17.164, NAT 뒤) │ + │ Tomcat 9 :8088 (127.0.0.1) ← ROOT 전개 │ + │ MariaDB csv │ + │ nginx → https://csv.zioinfo.co.kr [개발 웹] │ + └───────┬──────────────────────────────┬───────────────────┘ + │ ① SSH 터널(운영→개발, 인바운드) │ ② rsync(개발→운영) + │ 8088 프록시 │ 정적 리소스 + ┌───────▼──────────────────────────────▼───────────────────┐ + │ 운영 웹서버 utimsurpai.cafe24.com (211.37.173.197) │ + │ nginx → https://csv.wise.ai.kr [운영 웹] │ + │ 정적: /var/www/csv.wise.ai.kr/static (로컬 서빙) │ + │ 그 외: 터널 통해 개발 WAS로 프록시 │ + └──────────────────────────────────────────────────────────┘ +``` + +**WAS와 DB는 개발서버 것 하나만 쓴다.** 운영 웹서버는 웹 티어 전용이다. + +## 배포 흐름 + +```bash +bash deploy/dev/build-and-upload.sh # ① 로컬 JDK8 빌드 + WAR 업로드 +git push origin master # ② 이하 자동 +``` + +``` +② push + → 개발 WAS 배포 (ROOT 재전개 + 환경설정 주입 + 재기동 + 헬스체크, 실패 시 자동 롤백) + → 개발 웹 확인 (csv.zioinfo.co.kr) + → 운영 웹 배포 (정적 리소스 rsync) + → 운영 웹 확인 (csv.wise.ai.kr) +``` + +개발 헬스체크를 통과한 뒤에만 운영으로 넘어간다. 문서(`**.md`)만 바뀐 커밋은 배포하지 않는다. + +## 왜 이런 구조인가 + +**빌드를 서버에서 하지 않는 이유** — 개발서버는 2코어에 가용 메모리 1G 안팎이고 40개 이상의 +서비스가 동거한다. 실제로 2026-07-29 하루에만 서버 전체가 응답 불능이 되어 두 번 재부팅됐다. +Maven(힙 1G)을 여기서 돌리지 않는다. + +**접속 방향** — 개발서버는 NAT 뒤라 외부에서 먼저 접속할 수 없다. 그래서 +- 웹→WAS 연결은 **운영 웹서버가 개발서버로 SSH 터널을 연다**(아웃바운드) +- 배포는 **개발서버가 운영 웹서버로 나간다**(운영은 공인망 SSH 9271이 열려 있음) + +**터널을 쓰는 이유** — WAS의 8088은 NAT에서 포워딩되지 않고 Tomcat도 127.0.0.1 바인딩이다. +포트를 인터넷에 여는 대신 터널을 쓴다. 양쪽 키 모두 `authorized_keys`에서 용도를 좁혀 두었다. + +| 키 | 위치 | 제한 | +|---|---|---| +| `id_arko_tunnel` | 운영 웹 → 개발 | `restrict,port-forwarding,permitopen="127.0.0.1:8088"` (셸 불가) | +| `id_arko_prodweb` | 개발 → 운영 웹 | `from="101.79.17.164",no-pty,no-port-forwarding,...` | + +**정적 리소스를 운영 웹이 직접 서빙하는 이유** — 릴리스마다 실제로 옮길 산출물이 생기고, +WAS 왕복과 터널 트래픽이 줄어든다. 아직 배포되지 않은 파일은 `@was` 폴백으로 나가므로 +전환 중에도 화면이 깨지지 않는다. + +## 디렉토리 + +| 경로 | 내용 | +|---|---| +| `deploy/dev/` | 개발서버(WAS) 구축·배포 — [상세](dev/README.md) | +| `deploy/web/` | 운영 웹서버 구축·배포 | +| `.gitea/workflows/deploy-dev.yml` | 파이프라인 정의 | + +### deploy/web + +| 파일 | 실행 위치 | 역할 | +|---|---|---| +| `01-web-server-setup.sh` | 운영 웹 | 터널 서비스 + nginx vhost + SSL 발급 | +| `03-was-tunnel-key.sh` | 개발서버 | 운영 웹의 터널 공개키를 제한 등록 | +| `04-prod-web-deploy.sh` | 개발서버 | 정적 리소스 rsync (CI가 호출) | +| `05-prodweb-prepare.sh` | 운영 웹 | 배포 키 등록 + 정적 경로 전환 | +| `arko-was-tunnel.service` | 운영 웹 | SSH 터널 (자동 재연결) | +| `csv.wise.ai.kr.conf` | 운영 웹 | nginx vhost | + +## 운영 명령 + +```bash +# 개발서버 +systemctl status arko-dev arko-dev-runner +tail -f /opt/arko-dev/logs/deploy.log +tail -f /opt/arko-dev/tomcat/logs/catalina.out + +# 운영 웹서버 (ssh -p 9271 root@211.37.173.197) +systemctl status arko-was-tunnel # 502가 나면 여기부터 확인 +tail -f /var/log/nginx/csv.wise.ai.kr.error.log +``` + +## 알려진 이슈 + +**runner가 작업을 가져오지 않는 경우** — act_runner를 nginx(`https://git.zioinfo.co.kr`)를 +경유해 등록하면 `declare successfully` 까지는 가는데 작업을 집어가지 않고, 재기동해야만 +대기 중이던 작업을 처리했다. long-poll이 nginx의 `proxy_buffering`(기본 on)에 물리는 것으로 +보인다. `deploy/dev/06-runner-reregister.sh` 로 Gitea에 직접(`127.0.0.1:9003`) 붙여 해결했다. +같은 증상이 재발하면 이 스크립트를 다시 실행할 것. + +**Gitea 1.22는 `workflow_dispatch`를 지원하지 않는다** — 넣으면 워크플로가 Actions 목록에 +아예 뜨지 않는다. 수동 재배포는 `git commit --allow-empty` 후 push 로 한다. + +**개발서버 자원** — 가용 메모리가 상시 1G 안팎이다. Tomcat 힙은 448m로 묶여 있고 +(`arko-dev.service`), 늘리기 전에 반드시 `free -h` 로 여유를 확인할 것. diff --git a/deploy/dev/06-runner-reregister.sh b/deploy/dev/06-runner-reregister.sh new file mode 100644 index 0000000..69746d5 --- /dev/null +++ b/deploy/dev/06-runner-reregister.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# act_runner를 Gitea에 직접(127.0.0.1:9003) 붙도록 재등록한다. +# +# 문제: nginx(https://git.zioinfo.co.kr)를 경유해 등록하면 runner가 "declare successfully" +# 까지는 가는데 작업을 가져오지 않고, 재기동해야만 대기 중이던 작업을 집어간다. +# act_runner의 작업 수신은 long-poll인데 그 앞의 nginx가 proxy_buffering 기본값(on)과 +# proxy_read_timeout 300s 로 서 있어 연결이 물린 채로 남는 것으로 보인다. +# +# 해결: runner와 Gitea가 같은 서버에 있으므로 nginx를 거칠 이유가 없다. +# 루프백으로 직접 붙이면 프록시 계층이 사라진다. +set -euo pipefail + +RUNNER_DIR=/opt/arko-dev/runner +INSTANCE=http://127.0.0.1:9003 +SCOPE=somang4819/arko_renual +GITEA_USER=$(stat -c %U /var/lib/gitea) + +echo "=== 1. runner 중지 ===" +systemctl stop arko-dev-runner || true + +echo "=== 2. 기존 등록 백업 ===" +TS=$(date +%Y%m%d_%H%M%S) +[ -f "$RUNNER_DIR/.runner" ] && mv "$RUNNER_DIR/.runner" "$RUNNER_DIR/.runner.bak_$TS" && echo "백업: .runner.bak_$TS" + +echo "=== 3. 등록 토큰 발급 ===" +TOKEN=$(su - "$GITEA_USER" -s /bin/bash -c \ + "gitea actions generate-runner-token --config /etc/gitea/app.ini --scope $SCOPE" 2>/dev/null | tr -d '\r\n ') +[ -n "$TOKEN" ] || { echo "토큰 발급 실패"; exit 1; } +echo "발급 완료" + +echo "=== 4. 직접 연결로 재등록 ($INSTANCE) ===" +cd "$RUNNER_DIR" +/usr/local/bin/act_runner register --no-interactive \ + --instance "$INSTANCE" \ + --token "$TOKEN" \ + --name arko-dev-runner \ + --labels "arko-dev:host" + +echo "=== 5. 기동 ===" +systemctl start arko-dev-runner +sleep 10 +systemctl is-active arko-dev-runner +journalctl -u arko-dev-runner -n 8 --no-pager | tail -8