Enhanced values.yaml with comprehensive documentation and better organization: Documentation improvements: - Added detailed inline comments for all API7 Gateway configuration sections - Documented Ingress routing behavior (gateway vs direct service routing) - Explained Service Discovery benefits and requirements - Added detailed plugin configuration documentation (rate limiting, CORS, auth) - Included usage examples and production recommendations Configuration enhancements: - Added gateway.gatewayNamespace for better organization - Added TLS certificate configuration options (duration, renewBefore, algorithm, size) - Added ADC resource limits configuration - Improved CORS and rate limiting documentation with parameter explanations - Added consumer/authentication documentation Template updates: - Updated certificate.yaml to use configurable TLS parameters - Updated job-adc-sync.yaml to use configurable ADC resources The values.yaml now serves as comprehensive documentation for all API7 Gateway features and configuration options, making it easier for users to understand and customize their deployment. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
API7 Enterprise Edition Demo
A comprehensive demo platform showcasing API7 Enterprise Edition (API7EE) as an API Gateway with two FastAPI microservices: a Web frontend with embedded documentation and an API backend with LLM integration. Features automated CI/CD via Gitea Actions, Helm-based deployment, and advanced API7 Gateway configurations including AI rate limiting.
📋 Table of Contents
- Overview
- Architecture
- Project Structure
- Features
- Quick Start
- CI/CD Pipeline
- Kubernetes Deployment
- API7 Gateway Configuration
- Development
- Troubleshooting
- Resources
🎯 Overview
This project demonstrates enterprise-grade API Gateway patterns using API7 Enterprise Edition, showcasing:
- Microservices Architecture: Web frontend + API backend
- AI Integration: LLM endpoints with OpenAI-compatible API
- Advanced Rate Limiting: Token-based AI rate limiting + IP-based rate limiting
- Service Discovery: Kubernetes-native service discovery via API7
- Automated Deployment: Gitea Actions CI/CD + Helm charts
- Production-Ready: TLS, monitoring, autoscaling, and security policies
Live Demo: https://commandware.it
🏗️ Architecture
┌─────────────────────────────────────────────────────────────┐
│ Internet / Users │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ NGINX Ingress Controller (TLS) │
│ cert-manager (Let's Encrypt) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ API7 Enterprise Gateway │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Routes & Plugins: │ │
│ │ • / → Web Service (Apache/Nginx) │ │
│ │ • /api → API Backend (Rate: 100 req/60s) │ │
│ │ • /api/llm → LLM Endpoints (Rate: 100 tokens/60s) │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌────────────┴────────────┐
▼ ▼
┌─────────────────────┐ ┌──────────────────────┐
│ Web Service │ │ API Service │
│ (apache/nginx) │ │ (nginx) │
│ │ │ │
│ • Frontend UI │ │ • REST API │
│ • Documentation │ │ • LLM Integration │
│ • API Proxy │ │ • Swagger Docs │
│ Replicas: 2-10 │ │ Replicas: 3-20 │
└─────────────────────┘ └──────────────────────┘
│
▼
┌──────────────────────┐
│ Open WebUI (LLM) │
│ OpenAI-Compatible │
└──────────────────────┘
Service Naming
Important: The Helm chart names services as apache-service and nginx-service for API7 routing:
- Web Service: Deployed as
apache-service(serves frontend and docs) - API Service: Deployed as
nginx-service(serves REST API and LLM endpoints)
This naming convention is used in ADC configuration for consistent routing.
📁 Project Structure
api7ee/
├── web/ # Web frontend application
│ ├── main.py # FastAPI app with templates & API proxy
│ ├── Dockerfile # Multi-stage build with MkDocs
│ ├── requirements.txt # Dependencies: fastapi, httpx, mkdocs
│ ├── templates/ # Jinja2 HTML templates
│ │ ├── base.html # Base template
│ │ ├── index.html # Dashboard
│ │ ├── items.html # Items page
│ │ ├── users.html # Users page
│ │ └── llm.html # LLM chat interface
│ ├── static/ # CSS and JavaScript assets
│ ├── docs/ # MkDocs documentation source
│ │ ├── index.md
│ │ ├── getting-started.md
│ │ ├── architecture.md
│ │ ├── api7-configuration.md
│ │ ├── kubernetes-resources.md
│ │ ├── cicd-pipeline.md
│ │ └── troubleshooting.md
│ └── mkdocs.yml # MkDocs configuration
├── api/ # API backend application
│ ├── main.py # FastAPI app with REST + LLM endpoints
│ ├── Dockerfile # Container image
│ ├── requirements.txt # Dependencies: fastapi, httpx, pydantic
│ └── db.json # Sample data file
├── helm/ # Helm chart for Kubernetes
│ └── api7ee-demo-k8s/
│ ├── Chart.yaml # Chart metadata (v0.1.0)
│ ├── values.yaml # Default configuration
│ ├── values-dev.yaml # Development overrides
│ ├── values-production.yaml # Production overrides
│ └── templates/ # Kubernetes manifests
│ ├── deployment-web.yaml
│ ├── deployment-api.yaml
│ ├── service-web.yaml
│ ├── service-api.yaml
│ ├── ingress.yaml
│ ├── configmap-adc.yaml # API7 ADC configuration
│ ├── job-adc-sync.yaml # ADC sync job
│ ├── certificate.yaml # cert-manager certificate
│ ├── hpa-web.yaml # Horizontal Pod Autoscaler
│ ├── hpa-api.yaml
│ └── ...
├── .gitea/
│ └── workflows/
│ ├── build.yml # Docker image builds
│ └── helm-build.yml # Helm chart packaging
├── adc.yaml # Standalone API7 ADC configuration
└── README.md # This file
✨ Features
Web Application (web/)
- Interactive Dashboard: Modern UI with real-time stats
- Embedded Documentation: MkDocs Material theme at
/docs - API Proxy: Proxies requests to API backend
- LLM Chat Interface: Chat with videogame expert AI
- Health Checks:
/healthendpoint - Static Assets: Custom CSS and JavaScript
API Application (api/)
- REST API: Items and Users CRUD operations
- LLM Integration: OpenAI-compatible chat endpoint
- Swagger Documentation: Auto-generated at
/docs - Data Validation: Pydantic models
- Health Endpoints:
/healthand/llm/health - Model Management:
/llm/modelsendpoint
API7 Gateway Features
- Advanced Rate Limiting:
- Standard: 100 requests/60s per IP for
/api/* - AI: 100 tokens/60s for
/api/llm/*(token-based)
- Standard: 100 requests/60s per IP for
- Service Discovery: Kubernetes-native discovery
- TLS/SSL: Automatic certificate management
- HTTP → HTTPS Redirect: Enforced on all routes
- Prometheus Metrics: Built-in monitoring
- Route Prioritization: LLM routes (priority 20) > API (10) > Web (1)
DevOps Features
- CI/CD: Gitea Actions for automated builds
- Helm Packaging: Automated chart publishing
- Horizontal Autoscaling: HPA for both services
- Pod Disruption Budgets: High availability
- Security: Non-root containers, read-only root filesystem
- Multi-Environment: Dev and production value files
🚀 Quick Start
Prerequisites
- Docker (for local development)
- Kubernetes cluster (v1.19+)
- Helm 3.8.0+
- API7 Enterprise Edition installed
- kubectl configured
Local Development
Run Web Application
cd web
pip install -r requirements.txt
# Set API backend URL (optional)
export API_BASE_URL="http://localhost:8001"
python main.py
Access:
- Dashboard: http://localhost:8000
- Documentation: http://localhost:8000/docs
Run API Application
cd api
pip install -r requirements.txt
# Configure LLM endpoint (optional)
export OPENAI_API_BASE="http://localhost:11434/api"
export OPENAI_API_KEY="your-api-key"
export DEFAULT_LLM_MODEL="videogame-expert"
python main.py
Access:
- API Docs: http://localhost:8001/docs
- Health: http://localhost:8001/health
Docker Development
# Build images
docker build -t web-app ./web
docker build -t api-app ./api
# Run containers
docker run -d -p 8000:8000 --name web web-app
docker run -d -p 8001:8001 --name api api-app
# With environment variables
docker run -d -p 8001:8001 \
-e OPENAI_API_BASE="http://host.docker.internal:11434/api" \
-e OPENAI_API_KEY="sk-xxx" \
--name api api-app
🔄 CI/CD Pipeline
Docker Image Builds
Workflow: .gitea/workflows/build.yml
Triggers:
- Push to any branch
- Pull requests
- Manual dispatch
Process:
- Checkout code
- Set up Docker Buildx
- Login to Gitea container registry
- Build and push images:
git.commandware.com/demos/api7-demo/web:<branch-name>git.commandware.com/demos/api7-demo/api:<branch-name>
Helm Chart Publishing
Workflow: .gitea/workflows/helm-build.yml
Triggers:
- Push to
mainbranch (publishes) - Pull requests (lint only)
- Manual dispatch
Process:
- Extract version from
Chart.yaml - Lint Helm chart
- Update image registries in values
- Package chart as
.tgz - Push to Gitea Helm registry:
https://git.commandware.com/api/packages/demos/helm
Chart Versioning: Version is defined in helm/api7ee-demo-k8s/Chart.yaml (single source of truth)
Setup CI/CD
-
Create Gitea Secrets:
Repository Settings → Secrets → Add Secret - Name: USERNAME - Value: your-gitea-username - Name: TOKEN - Value: <gitea-token-with-write:package> -
Generate Token:
- User Settings → Applications → Generate New Token
- Scopes:
write:package,read:package
-
Push to Trigger:
git push origin main
☸️ Kubernetes Deployment
Using Helm (Recommended)
Add Helm Repository
# Add the Helm repository
helm repo add api7ee https://git.commandware.com/api/packages/demos/helm
# Update repositories
helm repo update
# Search for available versions
helm search repo api7ee
Install
# Install with default values
helm install api7ee-demo api7ee/api7ee-demo-k8s \
--namespace api7ee \
--create-namespace
# Install with custom values
helm install api7ee-demo api7ee/api7ee-demo-k8s \
--namespace api7ee \
-f custom-values.yaml
# Install specific version with custom image tags
helm install api7ee-demo api7ee/api7ee-demo-k8s \
--version 0.1.0 \
--set web.image.tag=main \
--set api.image.tag=main \
--set api7.gateway.adminKey="your-admin-key" \
--namespace api7ee
Configuration
Key values to customize:
# Custom domain
api7:
hosts:
- your-domain.com
# API7 Gateway connection
api7:
gateway:
adminUrl: http://api7ee3-0-xxx-dp-manager.api7ee.svc.cluster.local:7900
adminKey: "your-admin-key"
gatewayService: gateway-0-xxx-gateway
# Image tags
web:
image:
tag: "v1.0.0"
api:
image:
tag: "v1.0.0"
# Scaling
web:
replicaCount: 3
api:
replicaCount: 5
autoscaling:
enabled: true
maxReplicas: 30
# TLS
api7:
tls:
certManager:
enabled: true
issuer: cloudflare-acme-prod
Manage Deployment
# Check status
helm list -n api7ee
kubectl get pods -n api7ee
# Upgrade
helm upgrade api7ee-demo api7ee/api7ee-demo-k8s \
--namespace api7ee \
--reuse-values \
--set api.replicaCount=5
# Rollback
helm rollback api7ee-demo -n api7ee
# Uninstall
helm uninstall api7ee-demo -n api7ee
Using Local Helm Chart
# Install from local directory
helm install api7ee-demo ./helm/api7ee-demo-k8s \
--namespace api7ee \
--create-namespace
# Use production values
helm install api7ee-demo ./helm/api7ee-demo-k8s \
-f ./helm/api7ee-demo-k8s/values-production.yaml \
--namespace api7ee
Environment-Specific Deployments
Development:
helm install api7ee-dev ./helm/api7ee-demo-k8s \
-f ./helm/api7ee-demo-k8s/values-dev.yaml \
--namespace api7ee-dev
Production:
helm install api7ee-prod ./helm/api7ee-demo-k8s \
-f ./helm/api7ee-demo-k8s/values-production.yaml \
--namespace api7ee-prod
🔌 API7 Gateway Configuration
ADC (API7 Declarative CLI) Configuration
The Helm chart automatically configures API7 Gateway using ADC. Configuration is in helm/api7ee-demo-k8s/templates/configmap-adc.yaml.
Route Structure
1. Web Route (Priority: 1)
- name: apache-route
uris: [/*]
vars:
- [uri, "~~", "^(?!/api)"] # Match all except /api/*
plugins:
redirect:
http_to_https: true
2. API Route (Priority: 10)
- name: nginx-api-route
uris: [/api, /api/*]
plugins:
redirect:
http_to_https: true
limit-count:
count: 100
time_window: 60
key_type: "var"
key: "remote_addr"
3. LLM Route (Priority: 20)
- name: nginx-api-llm-route
uris: [/api/llm, /api/llm/*]
plugins:
redirect:
http_to_https: true
ai-rate-limiting:
limit: 100
time_window: 60
limit_strategy: "total_tokens"
Manual ADC Sync
If you need to manually sync ADC configuration:
# Using standalone adc.yaml file
adc sync -f adc.yaml \
--backend api7ee \
--server https://api7-dashboard.commandware.it \
--token <YOUR_API7_TOKEN> \
--gateway-group default \
--tls-skip-verify
# Publish routes via Dashboard
# Navigate to: Services → Routes → Click "Publish" → Select "default" gateway group
Service Discovery
API7 automatically discovers Kubernetes services:
upstream:
type: roundrobin
discovery_type: kubernetes # Helm uses direct node configuration
nodes:
- host: apache-service.api7ee.svc.cluster.local
port: 80
weight: 100
When pods scale, API7 automatically updates the upstream nodes.
Rate Limiting Configuration
Standard Rate Limiting (IP-based):
- Plugin:
limit-count - Limit: 100 requests per 60 seconds per IP
- Applies to:
/api/*routes (excluding/api/llm/*)
AI Rate Limiting (Token-based):
- Plugin:
ai-rate-limiting - Limit: 100 tokens per 60 seconds
- Strategy:
total_tokens(counts input + output tokens) - Applies to:
/api/llm/*routes
TLS/SSL Configuration
Option 1: cert-manager (Recommended)
api7:
tls:
certManager:
enabled: true
issuer: cloudflare-acme-prod
issuerKind: ClusterIssuer
Option 2: Existing Secret
api7:
tls:
enabled: true
secretName: my-tls-secret
Option 3: Direct Certificates (Not recommended for production)
api7:
tls:
enabled: true
certificate: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
key: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
🛠️ Development
Environment Variables
Web Application:
API_BASE_URL=http://localhost:8001 # API backend URL
API Application:
OPENAI_API_BASE=http://localhost:11434/api # LLM API endpoint
OPENAI_API_KEY=your-api-key # LLM API key
DEFAULT_LLM_MODEL=videogame-expert # Default model
Testing Endpoints
# Web health
curl http://localhost:8000/health
# API health
curl http://localhost:8001/health
# LLM health
curl http://localhost:8001/llm/health
# Get items
curl http://localhost:8001/items
# LLM chat
curl -X POST http://localhost:8001/llm/chat \
-H "Content-Type: application/json" \
-d '{
"prompt": "What is Zelda?",
"max_tokens": 150,
"model": "videogame-expert"
}'
Building Documentation
cd web
# Serve documentation locally
mkdocs serve
# Build static site
mkdocs build -d site
🔧 Troubleshooting
Common Issues
1. Routes Return 404
Symptom: Routes synced but returning 404
Cause: Routes not published to gateway group
Solution:
# Check route status in API7 Dashboard
# Services → Select service → Routes → Check publication status
# Publish via Dashboard:
# Click "Publish" → Select "default" gateway group → Confirm
# Or enable autoPublish in Helm:
api7:
autoPublish: true
2. ADC Sync Job Fails
Symptom: ADC sync job shows error status
Check logs:
kubectl logs -n api7ee -l app.kubernetes.io/component=adc-sync
# Common issues:
# - Incorrect adminKey
# - Wrong adminUrl (should point to dp-manager service)
# - Network connectivity to API7 Gateway
Verify API7 connection:
# Test API7 admin API
kubectl run -it --rm debug --image=curlimages/curl --restart=Never -- \
curl -H "X-API-KEY: your-admin-key" \
http://api7ee3-0-xxx-dp-manager.api7ee.svc.cluster.local:7900/apisix/admin/routes
3. Service Discovery Not Working
Check:
# Verify service exists
kubectl get svc -n api7ee apache-service nginx-service
# Check service endpoints
kubectl get endpoints -n api7ee
# Verify service has named ports
kubectl get svc apache-service -n api7ee -o yaml | grep -A5 ports
Ensure ports are named:
spec:
ports:
- port: 80
targetPort: 8000
name: http # ← Name is required
4. LLM Endpoints Failing
Check API configuration:
# Verify environment variables
kubectl get deployment nginx-service -n api7ee -o yaml | grep -A10 env
# Check API logs
kubectl logs -n api7ee -l app=nginx-service --tail=50
# Test LLM backend directly
curl http://localhost:11434/api/chat/completions \
-H "Authorization: Bearer your-key" \
-d '{"model":"videogame-expert","messages":[{"role":"user","content":"test"}]}'
5. Image Pull Errors
Solution:
# Create registry secret
kubectl create secret docker-registry gitea-registry \
--docker-server=git.commandware.com \
--docker-username=<USERNAME> \
--docker-password=<TOKEN> \
-n api7ee
# Add to Helm values
global:
imagePullSecrets:
- name: gitea-registry
6. Certificate Issues
Check cert-manager:
# Check certificate status
kubectl get certificate -n api7ee
# Check certificate details
kubectl describe certificate api7ee-tls -n api7ee
# Check cert-manager logs
kubectl logs -n cert-manager -l app=cert-manager --tail=50
# Check challenge status (for ACME)
kubectl get challenge -n api7ee
Getting Help
-
Check logs:
kubectl logs -n api7ee -l app.kubernetes.io/name=api7ee-demo-k8s --tail=100 -
Check events:
kubectl get events -n api7ee --sort-by='.lastTimestamp' -
Verify Helm installation:
helm status api7ee-demo -n api7ee helm get values api7ee-demo -n api7ee -
Test connectivity:
kubectl run -it --rm debug --image=nicolaka/netshoot --restart=Never -n api7ee -- bash # Inside pod: curl http://apache-service curl http://nginx-service
📚 Resources
Documentation
- API7 Enterprise: https://docs.api7.ai/
- APISIX: https://apisix.apache.org/docs/
- FastAPI: https://fastapi.tiangolo.com/
- Helm: https://helm.sh/docs/
- Gitea Actions: https://docs.gitea.com/usage/actions/overview
Project Links
- Repository: https://git.commandware.com/demos/api7-demo
- Helm Registry: https://git.commandware.com/api/packages/demos/helm
- Container Registry: https://git.commandware.com/demos/-/packages/container
- Live Demo: https://commandware.it
Support
📄 License
Demo project for API7 Enterprise Gateway evaluation.
Version: 0.1.0 | Last Updated: 2025-10-07