#!/usr/bin/env python3 """KINTEX 서버 프로비저닝(멱등) — systemd 유닛·디렉터리·워커 venv·nginx vhost 설치. DB(kintex_db+PostGIS)·시크릿 env 는 provision.sh(별도, 시크릿 미출력)가 담당한다. 이 스크립트는 "코드로 유지되는" 서비스 구성만 다룬다(시크릿 없음 → 리포 커밋 가능). 전제: /opt/kintex/kintex.env·/opt/kintex/nanobanana.env 가 이미 존재(provision.sh 산출, root 600). 사용: sudo python3 deploy/setup_kintex_service.py # 유닛/디렉터리/venv/nginx 설치 sudo python3 deploy/setup_kintex_service.py --no-nginx # nginx 제외 배정 사실(2026-07-11 서버 survey): - 백엔드 포트 8021 (8003~8020 = 기존 GUARDiA 솔루션 예약, 8020=guardia-rag) - 개발 도메인 kintex.zioinfo.co.kr → 101.79.17.164 """ import argparse import os import shutil import subprocess import sys KINTEX_ROOT = "/opt/kintex" SRC = f"{KINTEX_ROOT}/src" WEB_ROOT = "/var/www/kintex" VENV = f"{KINTEX_ROOT}/worker/venv" HERE = os.path.dirname(os.path.abspath(__file__)) def sh(cmd, check=True): print(f"[setup] $ {cmd}") r = subprocess.run(cmd, shell=True, text=True) if check and r.returncode != 0: sys.exit(f"[setup] 실패(rc={r.returncode}): {cmd}") return r.returncode def main(): ap = argparse.ArgumentParser() ap.add_argument("--no-nginx", action="store_true") args = ap.parse_args() if os.geteuid() != 0: sys.exit("[setup] root 로 실행하세요(sudo).") # 1. 디렉터리 for d in (f"{KINTEX_ROOT}/app", SRC, f"{KINTEX_ROOT}/worker", f"{KINTEX_ROOT}/output/visualizations", WEB_ROOT, "/var/log/kintex"): os.makedirs(d, exist_ok=True) # 2. deploy_kintex.sh 설치(서버 표준 위치) sh(f"install -m 755 {HERE}/deploy_kintex.sh {KINTEX_ROOT}/deploy_kintex.sh") # 3. 워커 venv + 의존성(google-genai·Pillow·redis) if not os.path.exists(f"{VENV}/bin/python"): sh(f"python3 -m venv {VENV}") sh(f"{VENV}/bin/pip install -q --upgrade pip") sh(f"{VENV}/bin/pip install -q redis Pillow google-genai") # 4. systemd 유닛 설치 for unit in ("kintex.service", "kintex-nanobanana.service"): src = f"{HERE}/systemd/{unit}" shutil.copyfile(src, f"/etc/systemd/system/{unit}") os.chmod(f"/etc/systemd/system/{unit}", 0o644) print(f"[setup] 유닛 설치: {unit}") sh("systemctl daemon-reload") sh("systemctl enable kintex.service kintex-nanobanana.service", check=False) # 5. nginx vhost if not args.no_nginx: conf = "kintex.zioinfo.co.kr.conf" shutil.copyfile(f"{HERE}/nginx/{conf}", f"/etc/nginx/sites-available/{conf}") link = f"/etc/nginx/sites-enabled/{conf}" if not os.path.islink(link) and not os.path.exists(link): os.symlink(f"/etc/nginx/sites-available/{conf}", link) if sh("nginx -t", check=False) == 0: sh("systemctl reload nginx") else: print("[setup] WARN: nginx -t 실패 — vhost 반영 보류(타 사이트 무영향)") print("[setup] 완료. env(시크릿)는 provision.sh 산출물 사용. " "서비스 기동은 배포(deploy_kintex.sh)에서 jar 배치 후 수행.") if __name__ == "__main__": main()