--- name: yakcloud-deploy description: Deploy a project to YakCloud — yakcloud CLI (local kind dev → managed val/prod) or Gitea Actions (v* tag push) → build/push image → reconcile data sources → deploy workloads → bind env → custom domain. Use when deploying this project to YakCloud, editing yakcloud.yaml, binding data sources, adding a domain, or starting a new project. --- # YakCloud 배포 스킬 `yakcloud` CLI 로 **로컬 kind 개발 → 관리형 검증/운영**을 한 줄기로 배포한다. 또는 `v*` 태그 push → Gitea Actions 가 이미지 빌드/푸시 + 콘솔 API 로 데이터소스 리컨실·워크로드 배포·바인딩을 자동 처리. ## 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 이미지엔 포함).