Skip to content

feat(k8s): add Kubernetes deployment with Helm chart for GKE Autopilot#6

Merged
jmponcebe merged 4 commits into
mainfrom
feat/kubernetes-gke
Jun 3, 2026
Merged

feat(k8s): add Kubernetes deployment with Helm chart for GKE Autopilot#6
jmponcebe merged 4 commits into
mainfrom
feat/kubernetes-gke

Conversation

@jmponcebe

Copy link
Copy Markdown
Owner

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/)

  • API + UI Deployments, Services (ClusterIP + LoadBalancer), HPAs
  • ConfigMap, Secret example, optional Ingress with GKE ManagedCertificate
  • kustomization.yaml to apply everything at once
  • Probes tuned for the ~50s embedding-model cold start (startupProbe with 24 retries x 5s)

Helm chart (helm/pharmagraphrag/)

  • Parameterized values for image tags, resources, autoscaling, secrets
  • Separate ConfigMap / Secret with optional existingSecret reference
  • podSecurityContext (non-root), HPAs on CPU + memory
  • Optional Ingress with managed cert
  • NOTES.txt with post-install instructions

CI/CD

  • deploy-gke.yml: triggered on v*-k8s tags. Reuses ci.yml, downloads ChromaDB from GCS, builds API + UI images to GCR, runs helm upgrade --install.
  • ci.yml extended with helm-validate job: helm lint + kubeconform against rendered chart and raw manifests when helm/ or k8s/ changes.

Docs

  • README.md: new "Deployment Options" section comparing Cloud Run vs GKE.
  • k8s/README.md and helm/pharmagraphrag/README.md with deploy + cleanup commands.
  • .github/copilot-instructions.md updated.

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 failures
  • helm template demo helm/pharmagraphrag renders valid YAML
  • Kubeconform validation added to CI

Required 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

jmponcebe added 2 commits June 2, 2026 19:51
…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.
Copilot AI review requested due to automatic review settings June 2, 2026 17:52

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 thread k8s/api-deployment.yaml
Comment on lines +20 to +24
spec:
containers:
- name: api
image: gcr.io/pharmagraphrag/pharmagraphrag-api:latest
imagePullPolicy: IfNotPresent
Comment thread k8s/ui-deployment.yaml
Comment on lines +20 to +24
spec:
containers:
- name: ui
image: gcr.io/pharmagraphrag/pharmagraphrag-ui:latest
imagePullPolicy: IfNotPresent
Comment thread k8s/configmap.yaml Outdated
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 thread helm/pharmagraphrag/values.yaml Outdated
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 thread helm/pharmagraphrag/Chart.yaml Outdated
Comment on lines +5 to +6
version: 0.1.0
appVersion: "1.5.0"
jmponcebe added 2 commits June 2, 2026 20:37
…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.
@jmponcebe jmponcebe merged commit 3b17865 into main Jun 3, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants