--- name: yakcloud-deploy description: Develop, verify, and deploy this project via the yakcloud CLI (local kind dev → managed val/prod) — never docker-compose. Build/push image → reconcile data sources → deploy workloads → bind env → custom domain. Use when running/testing/verifying the app locally, setting up a local dev environment, deploying to YakCloud, editing yakcloud.yaml, binding data sources, adding a domain, or starting a new project. If tempted to use docker-compose / docker run to run this app, use `yakcloud project deploy` (local kind) instead. --- # YakCloud 배포 스킬 `yakcloud` CLI 로 **로컬 kind 개발 → 관리형 검증/운영**을 한 줄기로 배포한다. 또는 `v*` 태그 push → Gitea Actions 가 이미지 빌드/푸시 + 콘솔 API 로 데이터소스 리컨실·워크로드 배포·바인딩을 자동 처리. ## 개발·검증도 yakcloud — docker-compose 금지 (원칙) 이 프로젝트의 앱은 **로컬 개발·검증부터 운영까지 전 구간을 yakcloud 로** 진행한다. - **로컬 실행·검증 = `yakcloud project deploy`** (로컬 kind 자동 생성, 오프라인·무료, 운영과 동일한 바인딩 env·데이터소스). - **`docker compose` / `docker-compose` / `docker run` 으로 앱을 띄우지 마라** — 프로젝트 `.claude/settings.json` 이 이를 차단하고, `Dockerfile` 은 yakcloud 의 이미지 빌드 전용이다. compose 스택은 운영과 환경이 달라져 파리티가 깨진다. - 데이터소스는 손으로 컨테이너를 띄우지 말고 `yakcloud.yaml` 의 `requires` 로 선언한다. (각 프로젝트 루트 `CLAUDE.md` 에 같은 규칙이 항상 로드되도록 심겨 있다 — `yakcloud project init` 이 생성.) ## 실행 규약 (패스스루) — 최우선 `/yakcloud ` 로 호출되면 **`yakcloud ` 를 Bash 로 그대로 실행하고 출력만 보여준다.** 사전점검(설치/폴더/설정 확인)·결과 재검증·부연설명을 붙이지 말 것 — 터미널에서 직접 친 것과 동일하게 동작. CLI 가 스스로 전제조건을 검사하고 오류를 안내하므로, 실패하면 그 출력을 그대로 전달하고 필요한 만큼만 후속 조치. **안전장치 — 아래 "되돌리기 어렵거나 외부로 나가는" 서브커맨드만 실행 전 1줄로 확인**하고 승인 시 실행: `project deploy` · `project confirm` · `project promote` · `domain` · `cluster create` · `dev down` · `source add` · `datasource migrate apply` (그 외 `project init/info/check` · `dev up/deploy/status` · `datasource ls`/`capture` · `cluster ls` · `config`/`login` 등 읽기·로컬·멱등 명령은 확인 없이 즉시 실행.) **⚠ 운영 승격 게이트 — `project confirm` 은 사람이 dev 검증을 마쳤다는 사인오프다. 에이전트가 임의로 실행하지 마라.** `project promote --to prod ` 는 그 버전의 `project confirm` 이 선행돼야 통과한다(val 은 자유). 사람의 명시적 검증 확인이 없으면 confirm/prod-promote 를 실행하지 말고, "dev 에서 확인 후 confirm 하라"고 안내만 한다. ## CLI (권장) 설치: `curl -fsSL https://gitea.yakenator.io/yakenator/yakcloud-starter/raw/branch/main/install.sh | sh` (전역 `/yakcloud` 슬래시 명령도 설치됨. `yakcloud upgrade` 로 최신화.) 자격 저장 = `yakcloud login`. **라이프사이클** - `yakcloud project init [name]` — 빈 폴더에 스캐폴딩(앱·CI·매니페스트·엔진). - `yakcloud cluster create [--template S|M] [--nodes N] [--golden]` · `yakcloud cluster ls`. - **로컬 dev**(반복 루프) — `yakcloud dev up`(최초 1회, 로컬 kind+인그레스) → `yakcloud dev deploy`. `requires` 소스+`workloads` 가 로컬에 **관리형과 동일한 바인딩 env**로 뜬다(오프라인). `dev status/clean/down`. 로그인 시 콘솔 '내 로컬 클러스터'에 자동 등록/해제. 상세 `docs/local-dev-cluster.md`. - **배포/승격** — `yakcloud project deploy` (v* 태그 push → CI → 개발 클러스터) · `--local`(러너 없이 로컬 build+push+리컨실) · `yakcloud project promote [vX.Y.Z] --to val|prod` (같은 이미지, 재빌드 없이 승격). - **앱 설정** — `domain [wl]` · `scale ` · `set --image/--port/--health/--cpu/--mem/--path/--rewrite` · `env KEY=VAL [--secret K] [--unset K]` · `datasource ls` · `source add [plan] [--shared]` · `bind|unbind `. ## 매니페스트 (`yakcloud.yaml`) - `project` — 이름(이미지 경로). - `environments.{dev,val,prod}.cluster` — 대상 클러스터 이름/id (val 선택, +`prod.domains`). 로컬 dev 는 `yakcloud dev`. - `requires[]` — `{ name, type, plan | mode: shared }`. type ∈ postgresql·mysql·mariadb·mongodb·redis·minio·rabbitmq·solr·oracle. 이름이 클러스터의 READY 소스와 일치하면 스킵, 없으면 프로비저닝(shared=공유 외부, 백엔드가 격리 DB 민팅). - `workloads[]` — `build`(도커 컨텍스트)·`image`(`gitea.yakenator.io//-:${TAG}`)·`port`· `health`·`replicas`(≥2 무중단)·`resources{cpu,mem}`·`expose{path,rewrite,host|hosts}`·`binds[]{alias,source}`. ## 데이터소스 바인딩 env (앱은 하드코딩 말고 이 env 로 접속) `binds: {alias, source}` → `alias`(대문자, 하이픈→언더스코어)가 env 프리픽스. 공통 `_HOST`·`_PORT`. | type | 추가 키 | `_URL` | |---|---|---| | postgresql | `_USERNAME _PASSWORD _DB` | `postgresql://u:pw@host:port/db` | | mysql·mariadb | `_USERNAME _PASSWORD _DB` | `mysql://u:pw@host:port/db` | | mongodb | `_USERNAME _PASSWORD _DB` | `mongodb://u:pw@host:port/db?authSource=db` | | redis | `_USERNAME`(빈) `_PASSWORD _DB` | `redis://:pw@host:port/db` | | minio | `_ACCESS_KEY _SECRET_KEY _ENDPOINT _BUCKET _REGION` | =`_ENDPOINT` | 비밀번호/키는 인클러스터 Secret 으로 주입되고 브라우저/포털에 노출되지 않는다. ## 1회 준비 (CI 배포 시 — 사용자가 설정, 에이전트 대행 불가) 1. **배포 토큰**(콘솔 → 설정 → 배포 토큰, `yakd_…`) · **Gitea 토큰**(`read:repository`+`write:package`+`read:package`). 2. 레포 시크릿(Gitea → Settings → Actions → Secrets): `YAKCLOUD_URL`=`https://console.yakenator.io` · `YAKCLOUD_TOKEN`=배포토큰 · `YAKCLOUD_CLUSTER`=대상 이름/id · `REGISTRY_TOKEN`=Gitea 토큰. 3. 러너: 전용 러너(라벨 `ci-polyglot`)가 공유로 떠 있으면 레포 Actions 만 켠다. (러너 없이 확실히 하려면 `yakcloud project deploy --local` — 로컬 build/push/리컨실.) ## 배포 / 도메인 ```sh yakcloud project deploy # 또는: git tag v0.1.0 && git push origin v0.1.0 yakcloud domain app.example.com web # 관리형 도메인=즉시 Active, 외부=TXT 검증 ``` 사전 점검: `yakcloud project check`. 성공 시 콘솔 앱 탭 / 데이터 소스 / 도메인에 반영. ## 규약 / 트러블슈팅 - 트리거 = `v*` 태그 push 만(일반 커밋 배포 안 함). 기존 배포는 이미지 PATCH 롤링(replicas≥2+health=무중단). - 소스 프로비저닝 `405` → 콘솔에서 소스 먼저 만들거나 `mode: shared`(소용량 S). `yakcloud project check` 로 사전 확인. - 태그 push 후 무반응 → 레포 러너 0개. `yakcloud project deploy --local`. - 헬스 `/healthz` 404 → 엣지가 가로챔. 배포 검증은 앱 실제 경로(`/`)로(컨테이너 readiness 엔 `health:` OK). - `ModuleNotFoundError: yaml`(직접 배포) → `pip install pyyaml`(CI 이미지엔 포함).