Skip to content

Tilt Dev Loop

FractalOps는 실제 개발 경로를 위한 Tilt 워크플로를 가집니다.

로컬 워크스테이션 -> 로컬 이미지 빌더 -> Helm dev 릴리스 -> dev 네임스페이스 -> 브라우저 스모크

Tilt는 이 저장소 자신의 FractalOps API/worker/portal 이미지를 위한 로컬 컨트롤-플레인 이미지 빌드 / dev-릴리스 루프입니다. 프로젝트 dev 프리뷰와는 무관합니다(그건 Daytona 샌드박스에서 bare 프로세스로 돕니다 — Dev Preview Plane 참고).

Tilt를 돌리는 호스트는 라이브 k3s API를 직접 mutate하지 않습니다. 그래서 올바른 모양은 직접 k8s_resource(...)나 원격 데몬 엔드포인트가 아닙니다. Tilt는 다음을 하는 로컬 셸 리소스를 구동합니다.

  • 컨테이너 빌드 툴체인으로 런타임 이미지를 로컬 빌드
  • Nexus 빌드 캐시 평면으로 dev 이미지/캐시 push
  • dev 네임스페이스의 dev-only Helm 릴리스 upgrade
  • 실제 공개 라우트 스모크
flowchart LR
  subgraph dev["development mode (Tilt)"]
    d1["로컬 이미지 빌드"] --> d2["GHCR dev tag"]
    d2 --> d3["helm upgrade --install\n-> fractalops-dev"]
  end
  subgraph staging["staging mode"]
    s1["staging-tagged 이미지\n+ cache scope"] -.->|기본: live mutate 안 함| s2["(옵션) 라이브 적용"]
  end
  subgraph release["deployment mode"]
    r1["Git/CI -> immutable tag"] --> r2["Helm values 핀"]
    r2 --> r3["Argo sync\n(canonical live)"]
  end
  • development mode: Tilt가 이미지를 빌드하고 dev-only Helm 릴리스를 upgrade.
  • staging mode: staging-tagged 이미지와 캐시 스코프를 빌드하되, 기본적으로 라이브 워크로드를 mutate하지 않음.
  • deployment mode: Argo가 Helm-선언된 Git 상태를 화해.

절대로 Tilt로 릴리스를 승격하지 마세요. 라이브-클러스터 빠른 반복에만 쓰세요.

  • tilt 로컬 설치 — 공식 설치 문서: https://docs.tilt.dev/install.html
  • 로컬 컨테이너 이미지 빌드 툴체인
  • helm
  • repo 루트 /home/devuser/work/fractalops

dev 배포 mutation에는 로컬 kubectl필요 없습니다.

Terminal window
make tilt-up

이것이 하는 일:

  1. 로컬 Tilt 이미지 빌더로 런타임 이미지 빌드
    • tag 대상 기본값 ghcr.io/yamonco/...
    • Tilt가 dev push에 GitOps 머신 GHCR 자격증명을 자동 사용
    • 원격 캐시 import/export 기본 off — 이 호스트는 원격 빌드 캐시를 효율적으로 쓸 수 없어 라이브 dev 루프에 복잡도만 더함
  2. dev 네임스페이스에서 런타임 Helm 릴리스 upgrade
  3. 같은 방식으로 portal dev 릴리스 빌드 + 롤아웃

기본 리소스: api, portal.

선택 리소스:

Terminal window
make tilt-up TILT_ARGS="-- --worker --e2e"

개발 모드 떠나기 (Leave development mode)

Section titled “개발 모드 떠나기 (Leave development mode)”

로컬 Tilt 세션만 정지:

Terminal window
make tilt-down

이것은 로컬 dev 루프를 멈출 뿐, release/staging/prod 앱을 mutate하지 않습니다.

배포 모드로 완전히 돌아가 Argo 소유권을 재확립:

Terminal window
make deploy-mode

make deploy-mode가 하는 세 가지:

  1. Tilt가 설치돼 있으면 로컬 Tilt 세션 정지
  2. Argo CD에 canonical FractalOps 앱 sync 요청
  3. canonical 앱이 Synced/Healthy로 돌아올 때까지 대기

Tilt가 정의하는 것:

  • runtime
  • portal
  • 선택 portal-e2e-smoke
  • 수동 deploy-mode

Dev와 Release 경계 (Dev and Release Boundary)

Section titled “Dev와 Release 경계 (Dev and Release Boundary)”

FractalOps 런타임 API/worker/portal 앱은 하나의 배포 표면: Helm 차트를 씁니다. Tilt는 disposable dev 네임스페이스에 같은 차트를, Argo는 같은 차트 경로를 runtime 환경에 sync합니다.

Dev:
Tilt -> 로컬 이미지 빌드 -> GHCR dev tag -> helm upgrade --install -> fractalops-dev
Release:
Git/CI -> 이미지 빌드 -> GHCR immutable tag -> Helm values 이미지 핀 -> Argo sync

빌드 평면과 캐시 (Build plane and cache)

Section titled “빌드 평면과 캐시 (Build plane and cache)”

모든 이미지 빌더는 Kubernetes BuildKit 평면을 사용합니다.

Terminal window
pnpm verify

의도된 레지스트리 분리:

  • GHCR: 최종 이미지 레지스트리만
  • Nexus docker-group :8083: docker.io + ghcr.io pull-through 미러
  • GHCR HTTPS registry cache: CI OCI 빌드 캐시 import/export
  • Nexus buildcache (in-cluster docker-internal :8082): 내부 TLS/Gateway writer가 준비되기 전까지 topology evidence/reserved endpoint

Nexus buildcache_ref가 문서/토폴로지에 남아 있어도 plain-HTTP endpoint는 BuildKit registry cache writer로 자동 승격되지 않습니다. Gateway API/HTTPRoute 등으로 내부 HTTPS 경로를 만든 뒤 FRACTALOPS_BUILDCACHE_REGISTRY를 명시해야 Nexus writer가 됩니다. 기본 캐시 스코프는 stage + target 스코프:

nexus.nexus.svc.cluster.local:8082/fractalops/buildcache/dev/runtime
nexus.nexus.svc.cluster.local:8082/fractalops/buildcache/dev/portal
nexus.nexus.svc.cluster.local:8082/fractalops/buildcache/dev/daytona-workspace
nexus.nexus.svc.cluster.local:8082/fractalops/buildcache/staging/runtime
nexus.nexus.svc.cluster.local:8082/fractalops/buildcache/staging/portal

이렇게 하면 GHCR가 캐시 버킷이 되는 것을 막고, runtime/portal/workspace 빌드가 invalidation-무거운 하나의 캐시 태그를 공유하지 않게 합니다.

빌드/캐시/utilization 텔레메트리는 워크플로 테스트 스위트가 아니라 Build Plane에 속합니다. 새 이벤트 이름/싱크를 추가하기 전에 Build Plane Observability의 ubiquitous 용어를 보세요.

Tilt/CI build runner -> Telemetry Marker -> OTLP HTTP logs -> OpenTelemetry Collector -> ClickHouse

웨어하우스 자격증명이 있는 제어된 runner는 직접 ClickHouse emission이 옵션:

Terminal window
FRACTALOPS_BUILD_EVENTS_ENABLED=true
FRACTALOPS_BUILD_EVENTS_TABLE=build_events
FRACTALOPS_CLICKHOUSE_HOST_PORT=clickhouse.clickhouse.svc.cluster.local:8123
FRACTALOPS_CLICKHOUSE_DATABASE=warehouse

Tilt/GitHub build 래퍼는 Build Plane Event 레코드를 best-effort로 emit합니다. 싱크는 기본 non-blocking이며, 텔레메트리 경로 자체를 검증할 때만 FRACTALOPS_BUILD_EVENTS_STRICT=true를 설정하세요.

오토스케일링 경계 (Autoscaling boundary)

Section titled “오토스케일링 경계 (Autoscaling boundary)”

라이브 FractalOps 컨트롤-플레인 워크로드는 Kubernetes HPA를 씁니다.

  • fractalops-api: min 2, max 6
  • fractalops-portal: min 1, max 4
  • fractalops-worker: min 1, max 4

Daytona 프로젝트 샌드박스는 HPA-관리 Deployment가 아닙니다. 런타임-소유 워크스페이스 컨테이너이며, 라이프사이클은 Daytona 컨트롤 플레인과 프로젝트 리스 정책을 따릅니다. 정지된 샌드박스는 0으로 스케일되거나 샌드박스 TTL이 회수합니다.

플랫폼 CI 이미지 빌드는 Nexus 레지스트리/빌드 캐시를 쓰는 관리 build worker를 씁니다. 병렬 빌드 수요는 새 privileged 데몬 Deployment가 아니라 공유 build worker와 레지스트리 캐시를 거쳐야 합니다.

staging 이미지 채널 (Staging image channel)

Section titled “staging 이미지 채널 (Staging image channel)”

라이브 클러스터를 건드리지 않고 staging-tagged 런타임/portal 이미지를 발행하려면 staging 모드를 쓰세요.

Terminal window
make staging-mode

한 타깃만 빌드:

Terminal window
make staging-mode TILT_ARGS="runtime --build-only"
make staging-mode TILT_ARGS="portal --build-only"

명시적으로 라이브-클러스터 점검을 원할 때만 staging-tagged 이미지를 canonical 라이브 Deployment에 적용:

Terminal window
make staging-mode TILT_ARGS="runtime"
make staging-mode TILT_ARGS="portal"

Tilt는 수동 리소스 portal-e2e-smoke를 노출합니다. 포트-포워드된 portal에 실제 Playwright 스모크를 돌리고 output/playwright/tilt-portal-smoke.png를 씁니다. Tilt UI에서 트리거하거나:

Terminal window
make tilt-ci TILT_ARGS="-- --e2e"

스모크는 공개 라우트 https://portal.yamon.io/projects에 대해 돕니다.

이 워크플로는 Tilt의 local-resource 가이드를 실제 FractalOps 경계에 맞춘 것입니다.

  • 호스트가 라이브 kube API에 직접 말할 수 없다
  • 호스트는 로컬 빌드를 하고 Nexus 캐시 평면에 도달할 수 있다
  • Helm이 dev 릴리스 mutation을 소유한다
  • Argo가 canonical 릴리스 mutation을 소유한다
  • 그래서 개발 모드는 “Argo-소유 deployment 패치”가 아니라 “로컬 빌드 + Helm dev 릴리스”여야 한다

Tilt는 빌드/롤아웃/스모크/복원 스텝을 local_resource 파이프라인으로 모델링합니다.

공식 참조:

  • 이 루프는 빠른 개발자 반복용이지 GitOps 승격용이 아닙니다.
  • Argo는 main의 canonical 라이브 워크로드 배포 오너로 남습니다.
  • make deploy-mode가 Argo에 소유권을 넘기는 필수 방법입니다.

프로젝트 프리뷰는 Tilt가 아닙니다 (Project Previews Are Not Tilt)

Section titled “프로젝트 프리뷰는 Tilt가 아닙니다 (Project Previews Are Not Tilt)”

이 Tilt 루프는 이 저장소 자신의 컨트롤-플레인 이미지를 빌드합니다. 프로젝트 프리뷰 경로가 아닙니다. 관리되는 프로젝트는 Tilt나 샌드박스 안에서 빌드/ship하지 않습니다.

프로젝트 dev 프리뷰는 Daytona 샌드박스에서 bare 프로세스(vite / next / uvicorn, 0.0.0.0 바인드)로 돌고, dev-preview MCP로 daytona-proxy 서명 프리뷰 URL을 통해 노출됩니다. 프로젝트당 하나의 공개 호스트(<slug>.monstore.io)가 실행 중이면 라이브 dev 프리뷰를, 아니면 프로젝트의 Dokploy 딜리버리를 서빙합니다. Dev Preview Plane 참고.

Project dev preview:
Daytona 샌드박스 (docker 없음)
-> bare 개발 서버 프로세스
-> daytona-proxy 서명 프리뷰 URL
-> <slug>.monstore.io (라이브 프리뷰, 아니면 Dokploy 딜리버리)

규칙:

  • repo/branch/agent/preview 채널마다 Daytona 워크스페이스를 만들지 마세요.
  • 관리되는 프로젝트 프리뷰를 Tilt에서 ad-hoc k3s 네임스페이스로 배포하지 마세요.
  • Dokploy는 영구 backing 서비스 전용입니다(DB, 정적 사이트 / vercel-sim 호스팅, big-facility compose) — dev 서버가 아닙니다.
  • PlaywrightGrid는 로컬 Tilt 라우트가 아니라 프로젝트의 공개 프리뷰 호스트를 테스트합니다.

이로써 역할이 선명해집니다.

  • Daytona: source-attached 프로젝트 워크스페이스와 bare dev 프리뷰 프로세스
  • daytona-proxy: 서명 프리뷰 URL 표면
  • Dokploy: 영구 backing 서비스와 정적 딜리버리
  • PlaywrightGrid: 프로젝트 공개 프리뷰 호스트에 대한 브라우저 증명
  • FractalOps Studio: 컨트롤 플레인, 계보, 에이전트 UX