Skip to content

Commit 78abc39

Browse files
authored
Merge pull request #39 from IBM/helm-charts
Add helm charts and support for helm in Makefile and docs
2 parents c6a3b83 + 810916e commit 78abc39

25 files changed

+1004
-3
lines changed

.pre-commit-config.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ repos:
290290
name: ✅ Check YAML
291291
description: Checks YAML files for parseable syntax.
292292
types: [yaml]
293-
exclude: ^docs/
293+
exclude: ^(docs/|charts/mcp-stack/)
294294

295295
- id: check-toml
296296
name: ✅ Check TOML
@@ -314,6 +314,9 @@ repos:
314314
name: ✅ YAMLlint - YAML Linter
315315
description: A linter for YAML files.
316316
args: [-c, .yamllint]
317+
# Lint *.yml|*.yaml everywhere EXCEPT charts/mcp-stack/**
318+
files: ^.*\.(yml|yaml)$
319+
exclude: ^charts/mcp-stack/
317320

318321
# - repo: https://github.com/igorshubovych/markdownlint-cli
319322
# rev: v0.45.0

.yamllint

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
extends: relaxed # start from the built-in relaxed preset
22
rules:
33
line-length:
4-
max: 200 # allow lines up to 200 chars
4+
max: 400 # allow lines up to 400 chars
55
level: warning # keep it a warning (default); use "error" to fail
6+
7+
# Ignore every YAML (and *.tpl) file under the Helm chart directory.
8+
ignore: |
9+
charts/mcp-stack/**/*.yaml
10+
charts/mcp-stack/**/*.tpl # if you template using .tpl files
11+
charts/mcp-stack/**/values.yaml
12+
charts/mcp-stack/**/Chart.yaml

Makefile

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1289,14 +1289,15 @@ ibmcloud-ce-rm:
12891289
# =============================================================================
12901290
# help: 🧪 MINIKUBE LOCAL CLUSTER
12911291
# help: minikube-install - Install Minikube (macOS, Linux, or Windows via choco)
1292+
# help: helm-install - Install Helm CLI (macOS, Linux, or Windows)
12921293
# help: minikube-start - Start local Minikube cluster with Ingress + DNS + metrics-server
12931294
# help: minikube-stop - Stop the Minikube cluster
12941295
# help: minikube-delete - Delete the Minikube cluster
12951296
# help: minikube-image-load - Build and load ghcr.io/ibm/mcp-context-forge:latest into Minikube
12961297
# help: minikube-k8s-apply - Apply Kubernetes manifests from k8s/
12971298
# help: minikube-status - Show status of Minikube and ingress pods
12981299

1299-
.PHONY: minikube-install minikube-start minikube-stop minikube-delete \
1300+
.PHONY: minikube-install helm-install minikube-start minikube-stop minikube-delete \
13001301
minikube-image-load minikube-k8s-apply minikube-status
13011302

13021303
minikube-install:
@@ -1320,6 +1321,19 @@ minikube-install:
13201321
exit 1; \
13211322
fi
13221323

1324+
helm-install:
1325+
@echo "📦 Installing Helm CLI…"
1326+
@if [ "$$(uname)" = "Darwin" ]; then \
1327+
brew install helm; \
1328+
elif [ "$$(uname)" = "Linux" ]; then \
1329+
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash; \
1330+
elif command -v powershell.exe >/dev/null; then \
1331+
powershell.exe -Command "choco install -y kubernetes-helm"; \
1332+
else \
1333+
echo "❌ Unsupported OS. Please install Helm manually."; \
1334+
exit 1; \
1335+
fi
1336+
13231337
minikube-start:
13241338
@echo "🚀 Starting Minikube with profile 'mcpgw'..."
13251339
minikube start \
@@ -1381,3 +1395,45 @@ minikube-status:
13811395

13821396
@echo "\n🌐 Application ingress:"
13831397
kubectl get ingress || true
1398+
1399+
# -----------------------------------------------------------------------------
1400+
# 🛠️ HELM CHART TASKS
1401+
# -----------------------------------------------------------------------------
1402+
# help: 🛠️ HELM CHART TASKS
1403+
# help: helm-lint - Lint the Helm chart (static analysis)
1404+
# help: helm-package - Package the chart into dist/ as mcp-stack-<ver>.tgz
1405+
# help: helm-deploy - Upgrade/Install chart into Minikube (profile mcpgw)
1406+
# help: helm-delete - Uninstall the chart release from Minikube
1407+
# -----------------------------------------------------------------------------
1408+
1409+
.PHONY: helm-lint helm-package helm-deploy helm-delete
1410+
1411+
CHART_DIR ?= charts/mcp-stack
1412+
RELEASE_NAME ?= mcp-stack
1413+
NAMESPACE ?= mcp
1414+
VALUES ?= $(CHART_DIR)/values.yaml
1415+
1416+
helm-lint:
1417+
@echo "🔍 Helm lint..."
1418+
helm lint $(CHART_DIR)
1419+
1420+
helm-package:
1421+
@echo "📦 Packaging chart into ./dist ..."
1422+
@mkdir -p dist
1423+
helm package $(CHART_DIR) -d dist
1424+
1425+
helm-deploy: helm-lint
1426+
@echo "🚀 Deploying $(RELEASE_NAME) into Minikube (ns=$(NAMESPACE))..."
1427+
helm upgrade --install $(RELEASE_NAME) $(CHART_DIR) \
1428+
--namespace $(NAMESPACE) --create-namespace \
1429+
-f $(VALUES) \
1430+
--wait
1431+
@echo "✅ Deployed."
1432+
@echo "\n📊 Release status:"
1433+
helm status $(RELEASE_NAME) -n $(NAMESPACE)
1434+
@echo "\n📦 Pods:"
1435+
kubectl get pods -n $(NAMESPACE)
1436+
1437+
helm-delete:
1438+
@echo "🗑 Deleting $(RELEASE_NAME) release..."
1439+
helm uninstall $(RELEASE_NAME) -n $(NAMESPACE) || true

charts/README.md

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# MCP Context Forge - MCP Gateway Stack Helm Chart
2+
3+
Deploy a complete **MCP Gateway stack** - gateway, PostgreSQL, Redis,
4+
and optional PgAdmin + Redis-Commander UIs-in one command.
5+
6+
> **Why Helm?**
7+
> * Consistent, repeatable installs across Minikube, kind, AKS/EKS/GKE, Rancher, etc.
8+
> * One `values.yaml` drives all environments-tune images, resources, ingress, TLS, persistence, and more.
9+
> * Rolling upgrades & easy rollbacks (`helm history`, `helm rollback`).
10+
11+
---
12+
13+
## Contents
14+
15+
| Folder / File | Purpose |
16+
| --------------------------------- | ----------------------------------------------------------- |
17+
| `Chart.yaml` | Chart metadata |
18+
| `values.yaml` | All configurable parameters |
19+
| `templates/` | Kubernetes manifests (templated) |
20+
| `README.md` | **← you are here** |
21+
22+
---
23+
24+
## 1 - Prerequisites
25+
26+
| Requirement | Notes |
27+
| ------------------ | -------------------------------------------------------------------------- |
28+
| **Kubernetes ≥ 1.23** | Tested on Minikube, kind, AKS, EKS |
29+
| **Helm 3** | `brew install helm` / `chocolatey install kubernetes-helm` |
30+
| **Ingress** | Any NGINX-compatible controller for `gateway.local` (or disable Ingress) |
31+
| **PV provisioner** | Host-path (Minikube) or dynamic RWX volume class for PostgreSQL persistence |
32+
33+
---
34+
35+
## 2 - Quick Start (local sandbox)
36+
37+
```bash
38+
# Clone or untar the chart
39+
git clone https://github.com/<org>/mcp-stack-chart.git
40+
cd mcp-stack-chart
41+
42+
# Optional: tweak values
43+
cp values.yaml my-values.yaml
44+
vim my-values.yaml
45+
46+
# Install
47+
helm install mcp ./mcp-stack \
48+
--create-namespace -n mcp \
49+
-f my-values.yaml
50+
```
51+
52+
Verify:
53+
54+
```bash
55+
kubectl get all -n mcp
56+
kubectl get ingress -n mcp
57+
curl http://gateway.local/health
58+
```
59+
60+
> **DNS tip (Minikube):** Enable the `ingress-dns` addon *or* add
61+
> `$(minikube ip) gateway.local` to `/etc/hosts`.
62+
63+
---
64+
65+
## 3 - Architecture
66+
67+
```
68+
┌─────────────────────────────┐
69+
│ NGINX Ingress │
70+
└──────────┬───────────┬──────┘
71+
│/ │/
72+
┌──────────────▼─────┐ ┌────▼───────────┐
73+
│ MCP Context Forge │ │ PgAdmin (opt.) │
74+
└─────────┬──────────┘ └────┬───────────┘
75+
│ │
76+
┌────────────▼──────┐ ┌────────▼────────────┐
77+
│ PostgreSQL │ │ Redis Commander(opt)│
78+
└────────┬──────────┘ └────────┬────────────┘
79+
│ │
80+
┌─────▼────┐ ┌─────▼────┐
81+
│ PV │ │ Redis │
82+
└──────────┘ └──────────┘
83+
```
84+
85+
---
86+
87+
## 4 - Configuration (`values.yaml`)
88+
89+
| Key | Default | Description |
90+
| ------------------------------------ | ------------------------------- | --------------------------- |
91+
| **global.nameOverride** | `""` | Shorten resource names |
92+
| **mcpContextForge.image.repository** | `ghcr.io/ibm/mcp-context-forge` | Container image |
93+
| **mcpContextForge.service.port** | `80` | Exposed port inside cluster |
94+
| **mcpContextForge.ingress.enabled** | `true` | Creates an Ingress |
95+
| **mcpContextForge.ingress.host** | `gateway.local` | Virtual host |
96+
| **postgres.enabled** | `true` | Deploy PostgreSQL |
97+
| **postgres.persistence.size** | `5Gi` | PVC size |
98+
| **postgres.credentials.user** | `admin` | DB user (stored in Secret) |
99+
| **redis.enabled** | `true` | Deploy Redis |
100+
| **pgadmin.enabled** | `false` | Deploy PgAdmin UI |
101+
| **redisCommander.enabled** | `false` | Deploy Redis-Commander UI |
102+
103+
*(See `values.yaml` for the full, annotated list.)*
104+
105+
---
106+
107+
## 5 - Common Tweaks
108+
109+
### Use a private registry
110+
111+
```yaml
112+
global:
113+
imagePullSecrets:
114+
- name: regcred
115+
mcpContextForge:
116+
image:
117+
repository: my-registry.local/mcp-context-forge
118+
tag: v2.0.0
119+
```
120+
121+
### Enable PgAdmin & Redis-Commander
122+
123+
```yaml
124+
pgadmin:
125+
enabled: true
126+
redisCommander:
127+
enabled: true
128+
```
129+
130+
### Disable persistence (ephemeral DB)
131+
132+
```yaml
133+
postgres:
134+
persistence:
135+
enabled: false
136+
```
137+
138+
---
139+
140+
## 6 - Upgrading / Rollback
141+
142+
```bash
143+
# Upgrade with new image
144+
helm upgrade mcp ./mcp-stack \
145+
--set mcpContextForge.image.tag=v1.1.0
146+
147+
# Roll back to previous revision
148+
helm rollback mcp 1
149+
```
150+
151+
---
152+
153+
## 7 - Uninstall
154+
155+
```bash
156+
helm uninstall mcp -n mcp
157+
```
158+
159+
Persistent volumes created with host-path remain; delete them manually if desired.
160+
161+
---
162+
163+
## 8 - Development & Testing
164+
165+
* Lint: `helm lint ./mcp-stack`
166+
* Dry-run template rendering: `helm template mcp ./mcp-stack | less`
167+
* Continuous reload (skaffold / tilt) possible-see `examples/dev/`.
168+
169+
---
170+
171+
## 9 - Contributing
172+
173+
1. Fork & create a branch.
174+
2. Update templates or `values.yaml`.
175+
3. Run `helm lint` and `helm template` against Minikube.
176+
4. Submit a PR-thanks!

charts/mcp-stack/Chart.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: v2
2+
name: mcp-stack
3+
description: |
4+
A complete Helm chart for MCP Gateway stack (Context Forge) including:
5+
* MCP Application
6+
* PostgreSQL database with persistence
7+
* Redis cache
8+
* Optional PgAdmin & Redis Commander UIs
9+
type: application
10+
version: 0.1.0
11+
appVersion: "1.0.0"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{{- define "mcp-stack.fullname" -}}
2+
{{- if .Values.global.fullnameOverride }}
3+
{{ .Values.global.fullnameOverride }}
4+
{{- else -}}
5+
{{- $name := default .Chart.Name .Values.global.nameOverride }}
6+
{{- if contains $name .Release.Name }}
7+
{{- printf "%s" .Release.Name }}
8+
{{- else }}
9+
{{- printf "%s-%s" .Release.Name $name }}
10+
{{- end }}
11+
{{- end }}
12+
{{- end }}
13+
14+
{{- define "mcp-stack.labels" -}}
15+
app.kubernetes.io/name: {{ include "mcp-stack.fullname" . }}
16+
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
17+
app.kubernetes.io/managed-by: {{ .Release.Service }}
18+
{{- end }}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: postgres-config
5+
data:
6+
POSTGRES_DB: {{ .Values.postgres.credentials.database }}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: {{ include "mcp-stack.fullname" . }}-app
5+
labels:
6+
{{- include "mcp-stack.labels" . | nindent 4 }}
7+
spec:
8+
replicas: {{ .Values.mcpContextForge.replicaCount }}
9+
selector:
10+
matchLabels:
11+
app: {{ include "mcp-stack.fullname" . }}-app
12+
template:
13+
metadata:
14+
labels:
15+
app: {{ include "mcp-stack.fullname" . }}-app
16+
spec:
17+
containers:
18+
- name: mcp-context-forge
19+
image: "{{ .Values.mcpContextForge.image.repository }}:{{ .Values.mcpContextForge.image.tag }}"
20+
imagePullPolicy: {{ .Values.mcpContextForge.image.pullPolicy }}
21+
ports:
22+
- containerPort: {{ .Values.mcpContextForge.containerPort }}
23+
env:
24+
- name: HOST
25+
value: "{{ .Values.mcpContextForge.env.host }}"
26+
- name: POSTGRES_HOST
27+
value: "{{ .Values.mcpContextForge.env.postgres.host }}"
28+
- name: POSTGRES_PORT
29+
value: "{{ .Values.mcpContextForge.env.postgres.port }}"
30+
- name: POSTGRES_DB
31+
value: "{{ .Values.mcpContextForge.env.postgres.db }}"
32+
- name: POSTGRES_USER
33+
valueFrom:
34+
secretKeyRef:
35+
name: postgres-secret
36+
key: user
37+
- name: POSTGRES_PASSWORD
38+
valueFrom:
39+
secretKeyRef:
40+
name: postgres-secret
41+
key: password
42+
- name: REDIS_HOST
43+
value: "{{ .Values.mcpContextForge.env.redis.host }}"
44+
- name: REDIS_PORT
45+
value: "{{ .Values.mcpContextForge.env.redis.port }}"
46+
resources: {{- toYaml .Values.mcpContextForge.resources | nindent 12 }}

0 commit comments

Comments
 (0)