diff --git a/.claude/rules/stack.md b/.claude/rules/stack.md index e6b0be4..6c8a4f5 100644 --- a/.claude/rules/stack.md +++ b/.claude/rules/stack.md @@ -6,7 +6,7 @@ | 패키지 | **pnpm** (npm/yarn 금지) | | 상태 머신 | **XState v5** | | 스키마 | **Zod** | -| 영속화 | **MariaDB** (Prisma ORM, Dev 서버 10.10.10.146:33006) | +| 영속화 | **MariaDB** (Prisma ORM) | | 프로세스 | **execa + AbortController** | | CLI | **citty** | | 로그 | **pino** (구조화 JSON) | diff --git a/.plans/design/deployment.md b/.plans/design/deployment.md index 38bf796..5fb0142 100644 --- a/.plans/design/deployment.md +++ b/.plans/design/deployment.md @@ -1,126 +1,86 @@ # Design — Deployment (rails 배포 위치) -> **결정**: Rails orchestrator 는 **VM 200 "dev" SSOT 서버 (10.10.10.169)** 에서 PM2 로 가동. +> **결정**: Rails orchestrator 는 **SSOT / Dev 서버**에서 PM2 로 가동. -## 왜 Dev/SSOT 서버? +## 왜 SSOT 서버? | 이유 | 상세 | |---|---| -| **모든 프로젝트가 여기서 가동** | arang, hanarang-dashboard, halangmi, halang-voice, reloop — PM2 12+ 프로세스 | -| **SSOT** | `/home/dev/hanarang/` 에 shared 자산 | -| **Node 22 이미 설치됨** | v22.22.1 | +| **모든 프로젝트가 여기서 가동** | PM2 로 12+ 프로세스 관리 | +| **SSOT** | 프로젝트 shared 자산 보관 | +| **Node 22 이미 설치됨** | 추가 세팅 불필요 | | **PM2 이미 가동 중** | 일관된 프로세스 관리 | -| **중립 위치** | 4자매 어느 LXC 에도 속하지 않음 — orchestrator 역할에 적합 | -| **같은 vmbr1** | 4자매 LXC + Gitea(LXC 103) 전부 접근 가능 | -| **Gitea webhook** | 같은 내부 네트워크 → 즉시 도달 | - -## 서버 스펙 (현재) - -``` -VM 200 "dev" (mailu-dev) -- OS: Ubuntu 24.04, Linux 6.8 -- IP: 10.10.10.169 (vmbr1) -- CPU: 4 cores / RAM: 8GB -- Disk: 57GB (21GB 여유, 62% 사용) -- Node: v22.22.1 -- PM2: 12+ 프로세스 가동 중 -- Docker: reloop-postgres, redis -- SSH: dev@10.10.10.169 -``` +| **중립 위치** | agent 어느 호스트에도 속하지 않음 — orchestrator 역할에 적합 | +| **같은 내부 네트워크** | 모든 agent 호스트 + Gitea 접근 가능 | +| **Gitea webhook** | 같은 네트워크 → 즉시 도달 | ## 배포 경로 ``` -/home/dev/ +/ ├── hanarang/ # 기존 SSOT │ ├── shared/ │ ├── sisters/ │ └── scripts/ ├── hanarang-rails/ # ← NEW: rails 설치 위치 │ ├── src/ -│ ├── data/rails.db # SQLite +│ ├── data/ # 로그 등 │ ├── .env │ └── ... -├── arang/ # 기존 프로젝트 -├── hanarang-dashboard/ # 기존 -├── reloop/ # 기존 +├── / # 기존 프로젝트 +├── / # 기존 └── ... ``` ## PM2 설정 ```js -// ecosystem.config.js +// ecosystem.config.cjs module.exports = { apps: [{ name: 'hanarang-rails', script: 'dist/cli/index.js', args: 'serve', - cwd: '/home/dev/hanarang-rails', + cwd: __dirname, env: { NODE_ENV: 'production', - RAILS_DATA_DIR: '/home/dev/hanarang-rails/data', - DISCORD_TOKEN: '...', - DISCORD_GUILD_ID: '...', - GITEA_WEBHOOK_SECRET: '...', }, - // 크래시 시 자동 재시작 max_restarts: 10, restart_delay: 5000, - // 로그 - error_file: '/home/dev/hanarang-rails/logs/error.log', - out_file: '/home/dev/hanarang-rails/logs/out.log', + error_file: './logs/error.log', + out_file: './logs/out.log', merge_logs: true, log_date_format: 'YYYY-MM-DD HH:mm:ss Z', }] } ``` -## 설치 순서 (Sprint 001 또는 007) +## 설치 ```bash -# 1. Dev 서버에 pnpm 설치 (아직 없음) -ssh dev@10.10.10.169 -npm install -g pnpm +# install.sh 사용 (권장) +bash install.sh --dir /path/to/hanarang-rails -# 2. repo clone -cd /home/dev -git clone https://git.nabomhalang.co.kr/hanarang/hanarang-rails.git -cd hanarang-rails - -# 3. 의존성 설치 + 빌드 -pnpm install -pnpm build - -# 4. .env 작성 -cp .env.example .env -# DISCORD_TOKEN, GUILD_ID, GITEA_WEBHOOK_SECRET 등 채우기 - -# 5. PM2 등록 -pm2 start ecosystem.config.js -pm2 save - -# 6. 확인 -pm2 list -curl http://localhost:PORT/health -rails status +# 또는 원격 +curl -fsSL /install.sh | bash ``` -## 네트워크 접근 매트릭스 +상세는 `install.sh --help` 참조. -``` -Dev 서버 (10.10.10.169) - → 하랑 (10.10.10.112) ✅ (같은 vmbr1) - → 나랑 (10.10.10.216) ✅ - → 다랑 (10.10.10.136) ✅ - → 이랑 (10.10.10.163) ✅ - → Gitea (10.10.10.146:3030) ✅ - → Discord (cloud) ✅ (OPNsense → 외부) -``` +## 네트워크 요구사항 + +Rails 서버에서 다음 접근이 필요: + +| 대상 | 프로토콜 | 용도 | +|---|---|---| +| Agent 호스트들 | Discord 또는 SSH | SisterTransport | +| Gitea 서버 | HTTPS | webhook 수신 + API 호출 | +| Discord API | HTTPS (외부) | 봇 통신 | +| MariaDB | TCP (3306) | 상태 저장 | ## 범용성 (다른 사용자) -다른 사용자는 Dev 서버가 아닌 자기 환경에 맞게: +다른 사용자는 자기 환경에 맞게: ```yaml # rails.config.yaml @@ -128,16 +88,17 @@ deployment: mode: standalone # or pm2, docker, systemd dataDir: ./data logDir: ./logs - port: 18800 # webhook receiver + status API + port: 18800 # webhook receiver + status API ``` +지원 배포 모드: - `standalone`: 단일 프로세스 (`rails serve`) -- `pm2`: ecosystem.config.js 생성 자동화 +- `pm2`: ecosystem.config.cjs 자동 생성 - `docker`: Dockerfile + docker-compose.yml 제공 - `systemd`: .service 파일 생성 ## 참고 -- `infra_network.md` 메모리 — 전체 네트워크 토폴로지 - `OVERVIEW.md` — 프로젝트 범위 - `transports.md` — SisterTransport 추상화 +- `install.sh` — 원클릭 설치 스크립트 diff --git a/.plans/migration/from-hanarang-harness.md b/.plans/migration/from-hanarang-harness.md index a3304da..1ca8273 100644 --- a/.plans/migration/from-hanarang-harness.md +++ b/.plans/migration/from-hanarang-harness.md @@ -67,10 +67,10 @@ 4. `rails migrate from-hanarang-harness /home/erang/hanarang-harness-archive` 실행 → 포팅 레포트 ### Step 2 — 4자매 배포 -1. 하랑이(LXC 104): `rails install --role planner` -2. 나랑이(LXC 105): `rails install --role generator` -3. 다랑이(LXC 106): `rails install --role evaluator` -4. 이랑이(LXC 107): `rails install --role infra` (본 머신에서도) +1. Planner 호스트: `rails install --role planner` +2. Generator 호스트: `rails install --role generator` +3. Evaluator 호스트: `rails install --role evaluator` +4. Infra 호스트: `rails install --role infra` 5. 각 자매의 `openclaw.json` 에 rails skill 등록 6. 각 자매에 `rails doctor --role ` 로 확인 diff --git a/.plans/sprints/SPRINT-004-handoff.md b/.plans/sprints/SPRINT-004-handoff.md index af3dd9e..753e352 100644 --- a/.plans/sprints/SPRINT-004-handoff.md +++ b/.plans/sprints/SPRINT-004-handoff.md @@ -59,7 +59,7 @@ - Timeout 시나리오는 일단 ERROR (Sprint 005 에서 retry 추가) ### 수동 -- [ ] 실제 OpenClaw 자매 (LXC 104~107) 1회 연결 테스트 (환경 허용 시) +- [ ] 실제 OpenClaw agent 호스트 1회 연결 테스트 (환경 허용 시) - [ ] 디스코드 포럼 포스트 한 번 수동 확인 - [ ] 멘션 스킵/실행 시나리오 수동 검증 diff --git a/install.sh b/install.sh index 43222e5..3fb0b6b 100755 --- a/install.sh +++ b/install.sh @@ -20,7 +20,7 @@ die() { err "$*"; exit 1; } # ────────────────────────────────────────────── # 설정 # ────────────────────────────────────────────── -REPO_URL="${RAILS_REPO_URL:-https://git.nabomhalang.co.kr/hanarang/hanarang-rails.git}" +REPO_URL="${RAILS_REPO_URL:-}" INSTALL_DIR="${RAILS_INSTALL_DIR:-$(pwd)/hanarang-rails}" DEV_MODE=false @@ -94,6 +94,9 @@ if [[ -d "$INSTALL_DIR/.git" ]]; then log "git pull 로 업데이트..." git -C "$INSTALL_DIR" pull --ff-only || warn "git pull 실패 — 수동 확인 필요" else + if [[ -z "$REPO_URL" ]]; then + die "RAILS_REPO_URL 환경변수 또는 --repo 을 지정하세요" + fi log "repo clone: $REPO_URL → $INSTALL_DIR" git clone "$REPO_URL" "$INSTALL_DIR" || die "git clone 실패" fi