diff --git a/README.md b/README.md index 49592bffc..365fbd041 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,7 @@ finmind/ - Frontend: Vercel. - Secrets: use environment variables (.env locally, platform secrets in cloud). - Kubernetes manifests for full stack deployment are available in `deploy/k8s/`. +- Tilt local Kubernetes development loop is available with `tilt up`; see `deploy/TILT.md`. ## Local Development 1) Prereqs: Docker, Docker Compose, Node 20+, Python 3.11+ diff --git a/Tiltfile b/Tiltfile new file mode 100644 index 000000000..d6bdceae7 --- /dev/null +++ b/Tiltfile @@ -0,0 +1,39 @@ +allow_k8s_contexts(["kind-kind", "kind-finmind", "minikube", "docker-desktop", "colima"]) + +local("test -f deploy/k8s/secrets.yaml || cp deploy/k8s/secrets.example.yaml deploy/k8s/secrets.yaml") + +docker_build( + "ghcr.io/rohitdash08/finmind-backend", + "packages/backend", + live_update=[ + sync("packages/backend/app", "/app/app"), + sync("packages/backend/tests", "/app/tests"), + sync("packages/backend/wsgi.py", "/app/wsgi.py"), + ], +) + +k8s_yaml([ + "deploy/k8s/namespace.yaml", + "deploy/k8s/secrets.yaml", + "deploy/k8s/app-stack.yaml", + "deploy/k8s/monitoring-stack.yaml", +]) + +k8s_resource( + "backend", + port_forwards=["8000:8000"], + resource_deps=["postgres", "redis"], +) + +k8s_resource("nginx", port_forwards=["8080:80"], resource_deps=["backend"]) +k8s_resource("grafana", port_forwards=["3000:3000"]) +k8s_resource("prometheus", port_forwards=["9090:9090"]) +k8s_resource("loki", port_forwards=["3100:3100"]) + +local_resource( + "frontend-dev", + cmd="cd app && npm install", + serve_cmd="cd app && npm run dev -- --host 0.0.0.0 --port 5173", + deps=["app/package.json", "app/package-lock.json", "app/src", "app/index.html"], + resource_deps=["backend"], +) diff --git a/deploy/TILT.md b/deploy/TILT.md new file mode 100644 index 000000000..55a15429d --- /dev/null +++ b/deploy/TILT.md @@ -0,0 +1,53 @@ +# Tilt Development Loop + +This repository includes Docker Compose and Kubernetes manifests. The root `Tiltfile` adds the missing local Kubernetes development loop for the universal deployment path. + +## Prerequisites + +- Docker +- A local Kubernetes cluster using one of: + - `kind-kind` + - `kind-finmind` + - `minikube` + - `docker-desktop` + - `colima` +- `kubectl` +- `tilt` +- Node 20 for the local frontend dev server + +## Start + +```bash +tilt up +``` + +The Tiltfile will: + +- create `deploy/k8s/secrets.yaml` from `deploy/k8s/secrets.example.yaml` when a local secrets file is missing +- build `ghcr.io/rohitdash08/finmind-backend` from `packages/backend` +- apply `deploy/k8s/namespace.yaml`, `deploy/k8s/secrets.yaml`, `deploy/k8s/app-stack.yaml`, and `deploy/k8s/monitoring-stack.yaml` +- live-sync backend source and tests into the backend container +- run the frontend Vite dev server as a Tilt local resource +- expose useful local ports + +## Local URLs + +- Frontend: http://localhost:5173 +- Backend API: http://localhost:8000 +- Nginx proxy: http://localhost:8080 +- Grafana: http://localhost:3000 +- Prometheus: http://localhost:9090 +- Loki: http://localhost:3100 + +## Validate + +```bash +kubectl get pods -n finmind +curl http://localhost:8000/health +``` + +For a clean teardown: + +```bash +tilt down +``` diff --git a/deploy/k8s/app-stack.yaml b/deploy/k8s/app-stack.yaml index 8ae7bcf11..f80e5b23e 100644 --- a/deploy/k8s/app-stack.yaml +++ b/deploy/k8s/app-stack.yaml @@ -296,8 +296,6 @@ spec: - name: postgres-exporter image: quay.io/prometheuscommunity/postgres-exporter:v0.16.0 env: - - name: DATA_SOURCE_NAME - value: postgresql://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@postgres:5432/$(POSTGRES_DB)?sslmode=disable - name: POSTGRES_USER valueFrom: secretKeyRef: @@ -313,6 +311,8 @@ spec: secretKeyRef: name: finmind-secrets key: POSTGRES_DB + - name: DATA_SOURCE_NAME + value: postgresql://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@postgres:5432/$(POSTGRES_DB)?sslmode=disable ports: - containerPort: 9187 --- diff --git a/deploy/k8s/monitoring-stack.yaml b/deploy/k8s/monitoring-stack.yaml index fa72ae14e..67816ed43 100644 --- a/deploy/k8s/monitoring-stack.yaml +++ b/deploy/k8s/monitoring-stack.yaml @@ -244,6 +244,34 @@ data: - action: labeldrop regex: filename --- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: promtail + namespace: finmind +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: finmind-promtail +rules: + - apiGroups: [""] + resources: [nodes, nodes/proxy, pods, services, endpoints] + verbs: [get, list, watch] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: finmind-promtail +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: finmind-promtail +subjects: + - kind: ServiceAccount + name: promtail + namespace: finmind +--- apiVersion: apps/v1 kind: DaemonSet metadata: @@ -258,6 +286,7 @@ spec: labels: app: promtail spec: + serviceAccountName: promtail containers: - name: promtail image: grafana/promtail:3.0.0 diff --git a/deploy/tilt-demo.mp4 b/deploy/tilt-demo.mp4 new file mode 100644 index 000000000..b6a2d514e Binary files /dev/null and b/deploy/tilt-demo.mp4 differ