feat(k8s): add Kubernetes deployment with Helm chart for GKE Autopilot#6
Merged
Conversation
…ment - k8s/: API + UI Deployments, Services (ClusterIP + LoadBalancer), HPAs, ConfigMap, Secret example, optional Ingress with GKE ManagedCertificate, kustomization.yaml. Probes tuned for ~50s embedding-model cold start. - helm/pharmagraphrag/: production-grade chart with parameterized values, separate ConfigMap/Secret, podSecurityContext (non-root), HPAs, optional Ingress. NOTES.txt with post-install instructions. - .github/workflows/deploy-gke.yml: CD pipeline on v*-k8s tags, downloads ChromaDB from GCS, builds API+UI images to GCR, deploys via Helm upgrade.
- ci.yml: new helm-validate job runs helm lint + kubeconform on rendered chart and raw k8s/ manifests when helm/ or k8s/ files change. - README.md: add Deployment Options section comparing Cloud Run vs GKE+Helm. - .github/copilot-instructions.md: add K8s/Helm row to status table and document new deploy-gke.yml workflow.
There was a problem hiding this comment.
Pull request overview
This PR adds a second, Kubernetes-based deployment option for PharmaGraphRAG (alongside the existing Cloud Run path) by introducing raw k8s/ manifests, a parameterized Helm chart, and CI/CD validation + a tag-triggered GKE deploy workflow.
Changes:
- Added production-oriented Kubernetes manifests (
k8s/) for API/UI Deployments, Services, HPAs, and optional GKE Ingress + ManagedCertificate. - Introduced a Helm 3 chart (
helm/pharmagraphrag/) to package/configure API+UI with autoscaling, probes, secrets, and optional ingress. - Extended GitHub Actions with Helm/K8s validation in CI and added a dedicated GKE deploy workflow.
Reviewed changes
Copilot reviewed 31 out of 31 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents the two deployment options (Cloud Run vs GKE/Helm). |
| k8s/ui-service.yaml | Adds LoadBalancer Service for UI exposure. |
| k8s/ui-hpa.yaml | Adds UI HorizontalPodAutoscaler (CPU-based). |
| k8s/ui-deployment.yaml | Adds UI Deployment with probes/resources and config injection. |
| k8s/secret.example.yaml | Provides a template Secret manifest for local/demo usage. |
| k8s/README.md | Documents raw-manifest deployment/cleanup and kind validation. |
| k8s/namespace.yaml | Introduces a dedicated pharmagraphrag namespace. |
| k8s/kustomization.yaml | Adds a kustomize entrypoint to apply resources in one go. |
| k8s/ingress.yaml | Adds optional GKE Ingress + ManagedCertificate configuration. |
| k8s/configmap.yaml | Adds non-secret runtime config for API/UI via ConfigMap. |
| k8s/api-service.yaml | Adds ClusterIP Service for API internal access. |
| k8s/api-hpa.yaml | Adds API autoscaling policy (CPU + memory). |
| k8s/api-deployment.yaml | Adds API Deployment with probes/resources and secret injection. |
| helm/pharmagraphrag/values.yaml | Defines Helm chart values for images, scaling, probes, config, and security contexts. |
| helm/pharmagraphrag/templates/ui-service.yaml | Helm template for UI Service (optionally LoadBalancer). |
| helm/pharmagraphrag/templates/ui-hpa.yaml | Helm template for UI HPA. |
| helm/pharmagraphrag/templates/ui-deployment.yaml | Helm template for UI Deployment with probes/security context. |
| helm/pharmagraphrag/templates/secret.yaml | Helm template for optionally creating the Secret. |
| helm/pharmagraphrag/templates/NOTES.txt | Post-install operational instructions for the chart. |
| helm/pharmagraphrag/templates/ingress.yaml | Helm template for optional Ingress + ManagedCertificate. |
| helm/pharmagraphrag/templates/configmap.yaml | Helm template for ConfigMap (including default internal API_URL). |
| helm/pharmagraphrag/templates/api-service.yaml | Helm template for API Service. |
| helm/pharmagraphrag/templates/api-hpa.yaml | Helm template for API HPA (CPU + optional memory). |
| helm/pharmagraphrag/templates/api-deployment.yaml | Helm template for API Deployment with probes/security context and secret reference. |
| helm/pharmagraphrag/templates/_helpers.tpl | Adds shared helpers for labels, selectors, image naming, and secret resolution. |
| helm/pharmagraphrag/README.md | Helm chart usage and value documentation. |
| helm/pharmagraphrag/Chart.yaml | Defines chart metadata (name/version/appVersion/etc.). |
| helm/pharmagraphrag/.helmignore | Configures Helm packaging ignore patterns. |
| .github/workflows/deploy-gke.yml | Adds tag-triggered workflow to build/push images and deploy to GKE via Helm. |
| .github/workflows/ci.yml | Adds helm-validate job (helm lint/template + kubeconform) when helm/ or k8s/ change. |
| .github/copilot-instructions.md | Updates project documentation to include Kubernetes/Helm as “Complete”. |
Comment on lines
+20
to
+24
| spec: | ||
| containers: | ||
| - name: api | ||
| image: gcr.io/pharmagraphrag/pharmagraphrag-api:latest | ||
| imagePullPolicy: IfNotPresent |
Comment on lines
+20
to
+24
| spec: | ||
| containers: | ||
| - name: ui | ||
| image: gcr.io/pharmagraphrag/pharmagraphrag-ui:latest | ||
| imagePullPolicy: IfNotPresent |
Comment on lines
+6
to
+19
| data: | ||
| # Non-secret application configuration | ||
| LLM_PROVIDER: "gemini" | ||
| LLM_MODEL: "gemini-2.5-flash" | ||
| NEO4J_USER: "neo4j" | ||
| CHROMA_PERSIST_DIR: "/app/data/chroma" | ||
| API_HOST: "0.0.0.0" | ||
| API_PORT: "8000" | ||
| STREAMLIT_PORT: "8501" | ||
| # UI uses the internal service DNS to reach the API | ||
| API_URL: "http://pharmagraphrag-api.pharmagraphrag.svc.cluster.local:8000" | ||
| # Langfuse (opt-in) | ||
| LANGFUSE_ENABLED: "false" | ||
| LANGFUSE_HOST: "https://cloud.langfuse.com" |
Comment on lines
+78
to
+88
| # -- Non-secret application configuration (mounted as env vars via ConfigMap) | ||
| config: | ||
| LLM_PROVIDER: "gemini" | ||
| LLM_MODEL: "gemini-2.5-flash" | ||
| NEO4J_USER: "neo4j" | ||
| CHROMA_PERSIST_DIR: "/app/data/chroma" | ||
| API_HOST: "0.0.0.0" | ||
| API_PORT: "8000" | ||
| STREAMLIT_PORT: "8501" | ||
| LANGFUSE_ENABLED: "false" | ||
| LANGFUSE_HOST: "https://cloud.langfuse.com" |
Comment on lines
+8
to
+12
| {{- range $key, $value := .Values.config }} | ||
| {{ $key }}: {{ $value | quote }} | ||
| {{- end }} | ||
| # Inter-service DNS for the UI to reach the API | ||
| API_URL: "http://{{ .Release.Name }}-api:{{ .Values.api.service.port }}" |
Comment on lines
+9
to
+11
| spec: | ||
| domains: | ||
| - {{ .Values.ingress.host | quote }} |
Comment on lines
+28
to
+31
| spec: | ||
| rules: | ||
| - host: {{ .Values.ingress.host | quote }} | ||
| http: |
Comment on lines
+5
to
+6
| version: 0.1.0 | ||
| appVersion: "1.5.0" |
…ess validation Addresses Copilot review on PR #6: - k8s/api-deployment.yaml, ui-deployment.yaml: add pod + container securityContext (runAsNonRoot, drop ALL capabilities) to match Helm chart posture and pass Pod Security Admission 'restricted'. - k8s/configmap.yaml, helm/.../values.yaml: remove keys not read by Settings (LLM_MODEL, API_HOST, API_PORT, STREAMLIT_PORT) and rename LANGFUSE_HOST -> LANGFUSE_BASE_URL (matches Settings attribute). - helm/.../templates/configmap.yaml: only auto-inject API_URL when not already provided via .Values.config to avoid duplicate keys. - helm/.../templates/ingress.yaml: use 'required' to fail fast when ingress.enabled=true but ingress.host is empty. - helm/.../Chart.yaml: align appVersion (1.5.0 -> 0.1.0) with src/pharmagraphrag/__init__.py.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a production-grade Kubernetes deployment path for PharmaGraphRAG, complementing the existing Cloud Run deployment. The project now ships two deployment options: serverless (Cloud Run) and orchestrated (GKE Autopilot + Helm), letting users pick based on traffic patterns and ops preferences.
What's included
Raw manifests (
k8s/)kustomization.yamlto apply everything at onceHelm chart (
helm/pharmagraphrag/)existingSecretreferenceNOTES.txtwith post-install instructionsCI/CD
deploy-gke.yml: triggered onv*-k8stags. Reuses ci.yml, downloads ChromaDB from GCS, builds API + UI images to GCR, runshelm upgrade --install.ci.ymlextended withhelm-validatejob:helm lint+kubeconformagainst rendered chart and raw manifests whenhelm/ork8s/changes.Docs
README.md: new "Deployment Options" section comparing Cloud Run vs GKE.k8s/README.mdandhelm/pharmagraphrag/README.mdwith deploy + cleanup commands..github/copilot-instructions.mdupdated.Cost strategy
GKE Autopilot is on-demand only for this project: cluster is created for demos / screenshots and destroyed afterwards (
gcloud container clusters delete). Cloud Run remains the always-on path.Validation
helm lint helm/pharmagraphrag-> 0 failureshelm template demo helm/pharmagraphragrenders valid YAMLRequired GitHub secrets for CD
GCP_SA_KEY,GKE_CLUSTER_NAME,GKE_CLUSTER_LOCATION,GKE_PROJECT_ID,PGRAG_NEO4J_URI,PGRAG_NEO4J_PASSWORD,PGRAG_GEMINI_API_KEY