Skip to content

Commit c6a3b83

Browse files
authored
Merge pull request #38 from IBM/add-minikube-docs
Add support for minikube in Makefile and update documentation
2 parents 0f07248 + d8cb3db commit c6a3b83

17 files changed

+537
-85
lines changed

Makefile

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,3 +1282,102 @@ ibmcloud-ce-status:
12821282
ibmcloud-ce-rm:
12831283
@echo "🗑️ Deleting Code Engine app: $(IBMCLOUD_CODE_ENGINE_APP)"
12841284
@ibmcloud ce application delete --name $(IBMCLOUD_CODE_ENGINE_APP) -f
1285+
1286+
1287+
# =============================================================================
1288+
# 🧪 MINIKUBE LOCAL CLUSTER
1289+
# =============================================================================
1290+
# help: 🧪 MINIKUBE LOCAL CLUSTER
1291+
# help: minikube-install - Install Minikube (macOS, Linux, or Windows via choco)
1292+
# help: minikube-start - Start local Minikube cluster with Ingress + DNS + metrics-server
1293+
# help: minikube-stop - Stop the Minikube cluster
1294+
# help: minikube-delete - Delete the Minikube cluster
1295+
# help: minikube-image-load - Build and load ghcr.io/ibm/mcp-context-forge:latest into Minikube
1296+
# help: minikube-k8s-apply - Apply Kubernetes manifests from k8s/
1297+
# help: minikube-status - Show status of Minikube and ingress pods
1298+
1299+
.PHONY: minikube-install minikube-start minikube-stop minikube-delete \
1300+
minikube-image-load minikube-k8s-apply minikube-status
1301+
1302+
minikube-install:
1303+
@echo "💻 Detecting OS and installing Minikube + kubectl…"
1304+
@if [ "$$(uname)" = "Darwin" ]; then \
1305+
echo "🍎 Installing via Homebrew…"; \
1306+
brew install minikube kubernetes-cli; \
1307+
elif [ "$$(uname)" = "Linux" ]; then \
1308+
echo "🐧 Installing via direct download…"; \
1309+
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && \
1310+
sudo install minikube-linux-amd64 /usr/local/bin/minikube && \
1311+
rm minikube-linux-amd64; \
1312+
echo "🔧 Installing kubectl…"; \
1313+
curl -LO "https://dl.k8s.io/release/$$(curl -sL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" && \
1314+
chmod +x kubectl && sudo mv kubectl /usr/local/bin/; \
1315+
elif command -v powershell.exe >/dev/null; then \
1316+
echo "🪟 Installing via Chocolatey…"; \
1317+
powershell.exe -Command "choco install -y minikube kubernetes-cli"; \
1318+
else \
1319+
echo "❌ Unsupported OS. Please install manually."; \
1320+
exit 1; \
1321+
fi
1322+
1323+
minikube-start:
1324+
@echo "🚀 Starting Minikube with profile 'mcpgw'..."
1325+
minikube start \
1326+
--driver=docker \
1327+
--cpus=4 --memory=6g \
1328+
--profile=mcpgw
1329+
@echo "🔌 (Re)enabling required addons…"
1330+
minikube addons enable ingress -p mcpgw
1331+
minikube addons enable ingress-dns -p mcpgw
1332+
minikube addons enable metrics-server -p mcpgw
1333+
1334+
minikube-stop:
1335+
@echo "🛑 Stopping Minikube cluster..."
1336+
minikube stop -p mcpgw
1337+
1338+
minikube-delete:
1339+
@echo "🗑 Deleting Minikube cluster..."
1340+
minikube delete -p mcpgw
1341+
1342+
minikube-image-load:
1343+
@echo "📦 Loading image into Minikube (must be pre-built)..."
1344+
@if ! docker image inspect ghcr.io/ibm/mcp-context-forge:latest >/dev/null 2>&1; then \
1345+
echo "❌ Image ghcr.io/ibm/mcp-context-forge:latest not found. Download or build it first."; \
1346+
exit 1; \
1347+
fi
1348+
minikube image load ghcr.io/ibm/mcp-context-forge:latest -p mcpgw
1349+
@echo "🔍 Verifying image presence inside Minikube..."
1350+
minikube ssh -p mcpgw "sudo crictl images | grep ghcr.io/ibm/mcp-context-forge || echo '❌ Image not found in Minikube runtime'"
1351+
1352+
minikube-k8s-apply:
1353+
@echo "🧩 Applying Kubernetes manifests..."
1354+
kubectl apply -f k8s/postgres-config.yaml || true
1355+
kubectl apply -f k8s/postgres-pv.yaml || true
1356+
kubectl apply -f k8s/postgres-pvc.yaml || true
1357+
kubectl apply -f k8s/postgres-deployment.yaml
1358+
kubectl apply -f k8s/postgres-service.yaml
1359+
kubectl apply -f k8s/redis-deployment.yaml
1360+
kubectl apply -f k8s/redis-service.yaml
1361+
kubectl apply -f k8s/mcp-context-forge-deployment.yaml
1362+
kubectl apply -f k8s/mcp-context-forge-service.yaml
1363+
kubectl apply -f k8s/mcp-context-forge-ingress.yaml
1364+
minikube status -p mcpgw
1365+
1366+
minikube-status:
1367+
@echo "📊 Minikube cluster status:"
1368+
minikube status -p mcpgw
1369+
1370+
@echo "\n📦 Addon status (ingress, ingress-dns, metrics-server):"
1371+
minikube addons list | grep -E 'ingress|ingress-dns|metrics-server'
1372+
1373+
@echo "\n🚦 Ingress controller pods:"
1374+
kubectl get pods -n ingress-nginx -o wide || true
1375+
1376+
@echo "\n🧭 Ingress-DNS pods (coredns):"
1377+
kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide || true
1378+
1379+
@echo "\n🧩 Application services:"
1380+
kubectl get svc || true
1381+
1382+
@echo "\n🌐 Application ingress:"
1383+
kubectl get ingress || true

README.md

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ If you just want to run the gateway using the official image from GitHub Contain
102102
docker run -d --name mcpgateway \
103103
-p 4444:4444 \
104104
-e HOST=0.0.0.0 \
105-
-e JWT_SECRET_KEY=my-secret-key \
105+
-e JWT_SECRET_KEY=my-test-key \
106106
-e BASIC_AUTH_USER=admin \
107107
-e BASIC_AUTH_PASSWORD=changeme \
108108
-e AUTH_REQUIRED=true \
@@ -112,6 +112,8 @@ docker run -d --name mcpgateway \
112112
docker logs mcpgateway
113113
```
114114

115+
You can now access the UI at [http://localhost:4444/admin](http://localhost:4444/admin)
116+
115117
> 💡 You can also use `--env-file .env` if you have a config file already. See the provided [.env.example](.env.example)
116118
117119
### Optional: Mount a local volume for persistent SQLite storage
@@ -123,16 +125,19 @@ docker logs mcpgateway
123125
### Generate a token for API access
124126

125127
```bash
126-
export MCPGATEWAY_BEARER_TOKEN=$(docker exec mcpgateway python3 -m mcpgateway.utils.create_jwt_token --username admin --exp 10080 --secret my-test-key)
128+
export MCPGATEWAY_BEARER_TOKEN=$(docker exec mcpgateway python3 -m mcpgateway.utils.create_jwt_token --username admin --exp 100800 --secret my-test-key)
129+
echo ${MCPGATEWAY_BEARER_TOKEN}
127130
```
128131

129132
### Smoke-test the running container
130133

131134
```bash
132135
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
133-
http://localhost:4444/health
136+
http://localhost:4444/health | jq
134137
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
135138
http://localhost:4444/tools | jq
139+
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
140+
http://localhost:4444/version | jq
136141
```
137142

138143
### Running the mcpgateway-wrapper
@@ -210,19 +215,14 @@ make lint # optional: run style checks (ruff, mypy, etc.)
210215

211216
### Containerised (self-signed TLS)
212217

213-
```bash
214-
make podman # build production image
215-
make podman-run-ssl # run at https://localhost:4444
216-
```
217218

218-
### Generate an admin JWT
219+
> You can use docker or podman, ex:
219220
220221
```bash
221-
python -m mcpgateway.utils.create_jwt_token \
222-
-u admin \
223-
-e 10080 | tee token.txt # 7 days (minutes)
224-
225-
export MCPGATEWAY_BEARER_TOKEN=$(cat token.txt)
222+
make podman # build production image
223+
make podman-run-ssl # run at https://localhost:4444
224+
# or listen on port 4444 on your host directly, adds --network=host to podman
225+
make podman-run-ssl-host
226226
```
227227

228228
### Smoke-test the API
@@ -614,7 +614,7 @@ curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
614614
-d '{"jsonrpc":"2.0","id":1,"method":"ping"}' \
615615
http://localhost:4444/protocol/ping
616616
617-
# Completion for prompt/resource arguments
617+
# Completion for prompt/resource arguments (not implemented)
618618
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
619619
-H "Content-Type: application/json" \
620620
-d '{
@@ -623,7 +623,7 @@ curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
623623
}' \
624624
http://localhost:4444/protocol/completion/complete
625625
626-
# Sampling (streaming)
626+
# Sampling (streaming) (not implemented)
627627
curl -N -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
628628
-H "Content-Type: application/json" \
629629
-d '{
@@ -682,6 +682,8 @@ curl -X PUT -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
682682
# Toggle active status
683683
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
684684
http://localhost:4444/tools/1/toggle?activate=false
685+
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
686+
http://localhost:4444/tools/1/toggle?activate=true
685687
686688
# Delete tool
687689
curl -X DELETE -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" http://localhost:4444/tools/1
@@ -692,7 +694,7 @@ curl -X DELETE -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" http://localh
692694
### Gateway Management (`/gateways`)
693695
694696
```bash
695-
# Register a peer gateway
697+
# Register an MCP server as a new gateway provider
696698
curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
697699
-H "Content-Type: application/json" \
698700
-d '{"name":"peer_gateway","url":"http://peer:4444"}' \
@@ -896,7 +898,7 @@ curl -X POST -H "Content-Type: application/json" \
896898
## Testing
897899
898900
```bash
899-
make tests # Run unit tests
901+
make test # Run unit tests
900902
make lint # Run lint tools
901903
```
902904

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ services:
2424
# MCP Gateway - the main API server for the MCP stack
2525
# ──────────────────────────────────────────────────────────────────────
2626
gateway:
27-
image: mcpgateway/mcpgateway
27+
image: ghcr.io/ibm/mcp-context-forge:latest
2828
build:
2929
context: .
3030
dockerfile: Containerfile # Same one the Makefile builds

docs/docs/deployment/compose.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,28 @@
11
# 🧩 Docker Compose
22

33
Running **MCP Gateway** with **Compose** spins up a full stack (Gateway, Postgres, Redis, optional MPC servers) behind a single YAML file.
4-
The Makefile detects Podman or Docker automatically, and you can override it with `COMPOSE_ENGINE=`.
4+
The Makefile detects Podman or Docker automatically, and you can override it with `COMPOSE_CMD=`.
55
Health-checks (`service_healthy`) gate the Gateway until the database is ready, preventing race conditions.
66

77
---
88

9+
## Configure the compose command to use
10+
11+
For example, install and use Docker Compose v2:
12+
13+
```bash
14+
sudo apt install docker-buildx docker-compose-v2
15+
export COMPOSE_CMD="docker compose"
16+
```
17+
918
## 🐳/🦭 Build the images
1019

20+
```bash
21+
docker pull ghcr.io/ibm/mcp-context-forge:latest
22+
```
23+
24+
## 🐳/🦭 Build the images (when doing local development)
25+
1126
### Using Make (preferred)
1227

1328
| Target | Image | Dockerfile | Notes |
@@ -17,6 +32,8 @@ Health-checks (`service_healthy`) gate the Gateway until the database is ready,
1732
| `make docker` | `mcpgateway:latest` | **Containerfile** | Docker Desktop / CI runners |
1833
| `make docker-prod` | `mcpgateway:latest` | **Containerfile.lite** | Same multi-stage "lite" build |
1934

35+
Remember to tag the image or configure the correct image in `docker-compose.yml`
36+
2037
### Manual equivalents
2138

2239
```bash

docs/docs/deployment/container.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# 📦 Container Deployment
22

3-
You can run MCP Gateway as a fully self-contained container. This is the recommended method for production or platform-agnostic deployments.
3+
You can run MCP Gateway as a fully self-contained container. This is the recommended method for production or platform-agnostic deployments. You can use any container engine (ex: Docker or Podman).
44

55
---
66

0 commit comments

Comments
 (0)