From 1b31601543b192468ed9e6aaaaa0caf2e483bd6d Mon Sep 17 00:00:00 2001 From: "d.viti" Date: Tue, 7 Oct 2025 19:09:40 +0200 Subject: [PATCH] Rewrite and expand all documentation for API7EE demo platform --- README.md | 1071 ++++++++++++++++++++------------ api/README.md | 814 ++++++++++++++++++++++-- helm/api7ee-demo-k8s/README.md | 880 ++++++++++++++++++++++---- web/README.md | 755 ++++++++++++++++++++-- 4 files changed, 2852 insertions(+), 668 deletions(-) diff --git a/README.md b/README.md index 9c1f3b9..e6b542d 100644 --- a/README.md +++ b/README.md @@ -1,510 +1,727 @@ -# API7 Demo - FastAPI Applications +# API7 Enterprise Edition Demo -Demo project showcasing two FastAPI applications deployed on Kubernetes through API7 Enterprise Gateway with automated CI/CD using Gitea. +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](#overview) +- [Architecture](#architecture) +- [Project Structure](#project-structure) +- [Features](#features) +- [Quick Start](#quick-start) +- [CI/CD Pipeline](#cicd-pipeline) +- [Kubernetes Deployment](#kubernetes-deployment) +- [API7 Gateway Configuration](#api7-gateway-configuration) +- [Development](#development) +- [Troubleshooting](#troubleshooting) +- [Resources](#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://api7-demo.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 ``` -api7-demo/ -β”œβ”€β”€ web/ # Web application -β”‚ β”œβ”€β”€ main.py # FastAPI web app with HTML UI -β”‚ β”œβ”€β”€ Dockerfile # Container image -β”‚ └── requirements.txt # Python dependencies -β”œβ”€β”€ api/ # API application -β”‚ β”œβ”€β”€ main.py # FastAPI REST API with Swagger -β”‚ β”œβ”€β”€ Dockerfile # Container image -β”‚ └── requirements.txt # Python dependencies +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 # CI/CD pipeline -└── README.md +β”‚ β”œβ”€β”€ build.yml # Docker image builds +β”‚ └── helm-build.yml # Helm chart packaging +β”œβ”€β”€ adc.yaml # Standalone API7 ADC configuration +└── README.md # This file ``` -## 🌐 Applications +## ✨ Features ### Web Application (`web/`) -Modern web interface with: -- Responsive HTML dashboard -- System information display -- Health check endpoints - -**Endpoints:** -- `GET /` - Main webpage -- `GET /health` - Health check - -**Port:** 8000 +- **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**: `/health` endpoint +- **Static Assets**: Custom CSS and JavaScript ### API Application (`api/`) -REST API with full documentation: -- CRUD operations for Items and Users -- Automatic Swagger/OpenAPI docs -- Data validation with Pydantic +- **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**: `/health` and `/llm/health` +- **Model Management**: `/llm/models` endpoint -**Key Endpoints:** -- `GET /docs` - Swagger UI -- `GET /items` - List items -- `POST /items` - Create item -- `GET /users` - List users -- `GET /health` - Health check +### API7 Gateway Features -**Port:** 8001 (internally 8000) +- **Advanced Rate Limiting**: + - Standard: 100 requests/60s per IP for `/api/*` + - AI: 100 tokens/60s for `/api/llm/*` (token-based) +- **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 -**Web Application:** +#### Run Web Application + ```bash cd web pip install -r requirements.txt + +# Set API backend URL (optional) +export API_BASE_URL="http://localhost:8001" + python main.py -# Access at http://localhost:8000 ``` -**API Application:** +Access: + +- Dashboard: http://localhost:8000 +- Documentation: http://localhost:8000/docs + +#### Run API Application + ```bash 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 -# Swagger at http://localhost:8000/docs ``` -### Docker +Access: + +- API Docs: http://localhost:8001/docs +- Health: http://localhost:8001/health + +### Docker Development -**Build and run Web:** ```bash +# Build images docker build -t web-app ./web -docker run -p 8000:8000 web-app -``` - -**Build and run API:** -```bash docker build -t api-app ./api -docker run -p 8001:8000 api-app + +# 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 with Gitea +## πŸ”„ CI/CD Pipeline -### Automated Pipeline +### Docker Image Builds -The CI/CD workflows automatically: +**Workflow**: `.gitea/workflows/build.yml` -**`.gitea/workflows/build.yml`**: -1. Builds Docker images for both applications -2. Pushes to Gitea container registry -3. Tags images with branch name -4. Implements layer caching for faster builds +**Triggers**: -**`.gitea/workflows/helm-build.yml`**: -1. Packages Helm charts on every main branch push -2. Uses version from Chart.yaml (single source of truth) -3. Publishes charts to Gitea Helm registry -4. Validates charts on pull requests (lint only) - -**Triggers:** -- Any branch push (Docker images) -- Push to main branch (Helm chart) -- Pull requests (Helm lint only) +- Push to any branch +- Pull requests - Manual dispatch -**Registry:** `git.commandware.com/demos/api7-demo` +**Process**: -**Docker Images:** -- `git.commandware.com/demos/api7-demo/web:` -- `git.commandware.com/demos/api7-demo/api:` +1. Checkout code +2. Set up Docker Buildx +3. Login to Gitea container registry +4. Build and push images: + - `git.commandware.com/demos/api7-demo/web:` + - `git.commandware.com/demos/api7-demo/api:` -**Helm Repository:** -- `https://git.commandware.com/api/packages/$OWNER/helm` +### Helm Chart Publishing -### Setup +**Workflow**: `.gitea/workflows/helm-build.yml` -1. **Create `GITEA_TOKEN` secret:** - - Repository Settings β†’ Secrets β†’ Add Secret - - Name: `GITEA_TOKEN` - - Generate token at: User Settings β†’ Applications β†’ Generate Token - - Required scope: `write:package` +**Triggers**: -2. **Push to trigger build:** +- Push to `main` branch (publishes) +- Pull requests (lint only) +- Manual dispatch + +**Process**: + +1. Extract version from `Chart.yaml` +2. Lint Helm chart +3. Update image registries in values +4. Package chart as `.tgz` +5. 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 + +1. **Create Gitea Secrets**: + + ``` + Repository Settings β†’ Secrets β†’ Add Secret + - Name: USERNAME + - Value: your-gitea-username + + - Name: TOKEN + - Value: + ``` + +2. **Generate Token**: + - User Settings β†’ Applications β†’ Generate New Token + - Scopes: `write:package`, `read:package` + +3. **Push to Trigger**: ```bash git push origin main ``` ## ☸️ Kubernetes Deployment -### Prerequisites - -- Kubernetes cluster (v1.19+) -- Helm 3.8.0+ -- API7 Enterprise Gateway installed -- Namespace: `api7ee` - -### Deploy with Helm - -The project includes a complete Helm chart for easy deployment of both web and API components. +### Using Helm (Recommended) #### Add Helm Repository ```bash -# Add the Gitea Helm repository -helm repo add api7ee https://git.commandware.com/api/packages/$OWNER/helm +# 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 the Chart +#### Install ```bash # Install with default values -helm install my-api7ee api7ee/api7ee-demo-k8s --namespace api7ee --create-namespace +helm install api7ee-demo api7ee/api7ee-demo-k8s \ + --namespace api7ee \ + --create-namespace # Install with custom values -helm install my-api7ee api7ee/api7ee-demo-k8s -f custom-values.yaml --namespace api7ee +helm install api7ee-demo api7ee/api7ee-demo-k8s \ + --namespace api7ee \ + -f custom-values.yaml -# Install with specific image tags -helm install my-api7ee api7ee/api7ee-demo-k8s \ - --set web.image.tag=v1.0.0 \ - --set api.image.tag=v1.0.0 \ +# 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 Options +#### Configuration -Key Helm values: +Key values to customize: -| Parameter | Description | Default | -|-----------|-------------|---------| -| `web.enabled` | Enable Web component | `true` | -| `web.replicaCount` | Number of Web replicas | `2` | -| `api.enabled` | Enable API component | `true` | -| `api.replicaCount` | Number of API replicas | `3` | -| `ingress.enabled` | Enable ingress | `true` | -| `ingress.hosts[0].host` | Ingress hostname | `demo.commandware.it` | +```yaml +# Custom domain +api7: + hosts: + - your-domain.com -#### Upgrade/Uninstall +# 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 ```bash -# Upgrade the release -helm upgrade my-api7ee api7ee/api7ee-demo-k8s --namespace api7ee +# 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 my-api7ee --namespace api7ee +helm uninstall api7ee-demo -n api7ee ``` -### Manual Deployment (Alternative) - -**k8s-deployments.yaml:** -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: web - namespace: api7ee -spec: - replicas: 2 - selector: - matchLabels: - app: web - template: - metadata: - labels: - app: web - spec: - containers: - - name: web - image: git.commandware.com/demos/api7-demo/web:main - ports: - - containerPort: 8000 - name: http - livenessProbe: - httpGet: - path: /health - port: 8000 ---- -apiVersion: v1 -kind: Service -metadata: - name: web-service - namespace: api7ee -spec: - type: ClusterIP - ports: - - port: 80 - targetPort: 8000 - name: http - selector: - app: web ---- -# Similar configuration for api deployment -``` - -### Deploy +### Using Local Helm Chart ```bash -kubectl apply -f k8s-deployments.yaml -kubectl rollout status deployment/web -n api7ee -kubectl rollout status deployment/api -n api7ee +# 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**: + +```bash +helm install api7ee-dev ./helm/api7ee-demo-k8s \ + -f ./helm/api7ee-demo-k8s/values-dev.yaml \ + --namespace api7ee-dev +``` + +**Production**: + +```bash +helm install api7ee-prod ./helm/api7ee-demo-k8s \ + -f ./helm/api7ee-demo-k8s/values-production.yaml \ + --namespace api7ee-prod ``` ## πŸ”Œ API7 Gateway Configuration -### Route Configuration (ADC) +### 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) -**api7-routes.yaml:** ```yaml -services: - - name: web-service - upstream: - name: web-upstream - scheme: http - type: roundrobin - discovery_type: kubernetes - service_name: api7ee/web-service:http - routes: - - name: web-route - uris: - - /* - hosts: - - demo.yourdomain.com - plugins: - redirect: - http_to_https: true - - - name: api-service - upstream: - name: api-upstream - scheme: http - type: roundrobin - discovery_type: kubernetes - service_name: api7ee/api-service:http - routes: - - name: api-route - priority: 10 - uris: - - /api - - /api/* - hosts: - - demo.yourdomain.com - plugins: - redirect: - http_to_https: true - proxy-rewrite: - regex_uri: - - ^/api/(.*) - - /$1 - -ssls: - - snis: - - "*.yourdomain.com" - certificates: - - certificate: | - -----BEGIN CERTIFICATE----- - - -----END CERTIFICATE----- - key: | - -----BEGIN PRIVATE KEY----- - - -----END PRIVATE KEY----- +- name: apache-route + uris: [/*] + vars: + - [uri, "~~", "^(?!/api)"] # Match all except /api/* + plugins: + redirect: + http_to_https: true ``` -### Sync Configuration +**2. API Route** (Priority: 10) + +```yaml +- 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) + +```yaml +- 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: ```bash -adc sync -f api7-routes.yaml \ +# Using standalone adc.yaml file +adc sync -f adc.yaml \ --backend api7ee \ - --server https://api7-dashboard.yourdomain.com \ + --server https://api7-dashboard.commandware.it \ --token \ --gateway-group default \ --tls-skip-verify + +# Publish routes via Dashboard +# Navigate to: Services β†’ Routes β†’ Click "Publish" β†’ Select "default" gateway group ``` -### Publish Routes +### Service Discovery -Routes must be published via API7 Dashboard to become active: - -1. Navigate to **Services** β†’ Select service -2. Go to **Routes** tab -3. Click **"Publish"** for each route -4. Select gateway group: **"default"** -5. Confirm - -## πŸ§ͺ Testing - -### Test Endpoints - -```bash -# Web application -curl https://demo.yourdomain.com - -# API health check -curl https://demo.yourdomain.com/api/health - -# API Swagger (if exposed) -curl https://demo.yourdomain.com/api/docs - -# Verify HTTP β†’ HTTPS redirect -curl -I http://demo.yourdomain.com -``` - -### Verify Service Discovery - -```bash -# Scale deployment -kubectl scale deployment web -n api7ee --replicas=5 - -# API7 automatically discovers new endpoints -kubectl get endpoints -n api7ee web-service - -# Scale back -kubectl scale deployment web -n api7ee --replicas=2 -``` - -## πŸ“Š Architecture - -``` -Internet - ↓ -LoadBalancer (External IP) - ↓ -NGINX Ingress Controller - ↓ -TLS Termination (Let's Encrypt) - ↓ -API7 Gateway (ClusterIP) - ↓ -[Kubernetes Service Discovery] - ↓ -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Web Service β”‚ API Service β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -### Traffic Routing - -- `demo.yourdomain.com/api/*` β†’ API Service (priority 10, strips `/api` prefix) -- `demo.yourdomain.com/*` β†’ Web Service (default priority) - -## πŸ”§ API7 Enterprise Setup Guide - -### Certificate Management - -**Using cert-manager with Cloudflare:** +API7 automatically discovers Kubernetes services: ```yaml -apiVersion: cert-manager.io/v1 -kind: ClusterIssuer -metadata: - name: cloudflare-acme-prod -spec: - acme: - email: your-email@example.com - server: https://acme-v02.api.letsencrypt.org/directory - privateKeySecretRef: - name: letsencrypt-prod-key - solvers: - - dns01: - cloudflare: - apiTokenSecretRef: - name: cloudflare-api-token-secret - key: api-token +upstream: + type: roundrobin + discovery_type: kubernetes # Helm uses direct node configuration + nodes: + - host: apache-service.api7ee.svc.cluster.local + port: 80 + weight: 100 ``` -**Create Cloudflare secret:** -```bash -kubectl create secret generic cloudflare-api-token-secret \ - -n cert-manager \ - --from-literal=api-token=YOUR_TOKEN -``` +When pods scale, API7 automatically updates the upstream nodes. -### Kubernetes Service Discovery +### Rate Limiting Configuration -**Configure in API7 Dashboard:** +**Standard Rate Limiting** (IP-based): -1. **Settings β†’ Service Registry β†’ Add Service Registry** -2. **Select:** Kubernetes -3. **Configure:** - ``` - Name: kubernetes-cluster - API Server: https://kubernetes.default.svc.cluster.local:443 - Token Path: /var/run/secrets/kubernetes.io/serviceaccount/token - Namespace Filter: api7ee (optional) - ``` +- Plugin: `limit-count` +- Limit: 100 requests per 60 seconds per IP +- Applies to: `/api/*` routes (excluding `/api/llm/*`) -**Verify RBAC permissions:** -```bash -kubectl create clusterrolebinding api7-gateway-discovery \ - --clusterrole=view \ - --serviceaccount=:default -``` +**AI Rate Limiting** (Token-based): -### Ingress Configuration +- Plugin: `ai-rate-limiting` +- Limit: 100 tokens per 60 seconds +- Strategy: `total_tokens` (counts input + output tokens) +- Applies to: `/api/llm/*` routes -**Example ingress for API7 Gateway:** +### TLS/SSL Configuration + +**Option 1: cert-manager** (Recommended) ```yaml -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: api7-gateway-ingress - namespace: api7ee -spec: - ingressClassName: nginx +api7: tls: - - hosts: - - demo.yourdomain.com - secretName: demo-tls - rules: - - host: demo.yourdomain.com - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: api7-gateway-service - port: - number: 80 + certManager: + enabled: true + issuer: cloudflare-acme-prod + issuerKind: ClusterIssuer ``` -**Note:** Ingress backend points to API7 Gateway service, not application services. +**Option 2: Existing Secret** -## πŸ› οΈ Troubleshooting +```yaml +api7: + tls: + enabled: true + secretName: my-tls-secret +``` -### Routes Return 404 +**Option 3: Direct Certificates** (Not recommended for production) -**Problem:** Routes synced but returning 404 +```yaml +api7: + tls: + enabled: true + certificate: | + -----BEGIN CERTIFICATE----- + ... + -----END CERTIFICATE----- + key: | + -----BEGIN PRIVATE KEY----- + ... + -----END PRIVATE KEY----- +``` -**Solution:** Routes not published. Publish via API7 Dashboard. +## πŸ› οΈ Development -### Service Discovery Not Working +### Environment Variables -**Problem:** `service registry not found` error +**Web Application**: -**Checklist:** -- βœ… Service registry configured in dashboard -- βœ… Registry status shows "Connected" -- βœ… RBAC permissions granted -- βœ… Service ports have `name` field - -### Certificate Issues - -**Problem:** Certificate not trusted - -**Solution:** ```bash -# Check certificate status -kubectl get certificate -n api7ee -kubectl describe certificate -n api7ee - -# Check cert-manager logs -kubectl logs -n cert-manager -l app.kubernetes.io/name=cert-manager --tail=50 +API_BASE_URL=http://localhost:8001 # API backend URL ``` -### Container Images Not Found +**API Application**: -**Problem:** ImagePullBackOff in Kubernetes +```bash +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 + +```bash +# 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 + +```bash +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**: + +```bash +# 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**: + +```bash +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**: + +```bash +# 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**: + +```bash +# 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**: + +```yaml +spec: + ports: + - port: 80 + targetPort: 8000 + name: http # ← Name is required +``` + +#### 4. LLM Endpoints Failing + +**Check API configuration**: + +```bash +# 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**: -**Solution:** ```bash # Create registry secret kubectl create secret docker-registry gitea-registry \ @@ -513,45 +730,85 @@ kubectl create secret docker-registry gitea-registry \ --docker-password= \ -n api7ee -# Add to deployment -spec: - template: - spec: - imagePullSecrets: - - name: gitea-registry +# Add to Helm values +global: + imagePullSecrets: + - name: gitea-registry ``` +#### 6. Certificate Issues + +**Check cert-manager**: + +```bash +# 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 + +1. **Check logs**: + + ```bash + kubectl logs -n api7ee -l app.kubernetes.io/name=api7ee-demo-k8s --tail=100 + ``` + +2. **Check events**: + + ```bash + kubectl get events -n api7ee --sort-by='.lastTimestamp' + ``` + +3. **Verify Helm installation**: + + ```bash + helm status api7ee-demo -n api7ee + helm get values api7ee-demo -n api7ee + ``` + +4. **Test connectivity**: + ```bash + kubectl run -it --rm debug --image=nicolaka/netshoot --restart=Never -n api7ee -- bash + # Inside pod: + curl http://apache-service + curl http://nginx-service + ``` + ## πŸ“š Resources -- **API7 Documentation:** https://docs.api7.ai/ -- **APISIX Documentation:** https://apisix.apache.org/docs/ -- **FastAPI Documentation:** https://fastapi.tiangolo.com/ -- **Gitea Actions:** https://docs.gitea.com/usage/actions/overview +### Documentation -## πŸ” Best Practices +- **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 -### Security -- βœ… Use TLS for all external traffic -- βœ… Implement rate limiting on public endpoints -- βœ… Store secrets in Kubernetes Secrets or external vault -- βœ… Use least-privilege RBAC permissions +### Project Links -### Performance -- βœ… Enable service discovery for automatic scaling -- βœ… Configure appropriate resource limits -- βœ… Use Docker layer caching in CI/CD -- βœ… Implement health checks and readiness probes +- **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://api7-demo.commandware.it -### Monitoring -- βœ… Monitor gateway metrics in API7 Dashboard -- βœ… Track API usage and performance -- βœ… Set up alerts for certificate expiration -- βœ… Review application logs regularly +### Support -## πŸ“ License +- **Issues**: https://git.commandware.com/demos/api7-demo/issues +- **Email**: support@commandware.com + +## πŸ“„ License Demo project for API7 Enterprise Gateway evaluation. --- -**Repository:** https://git.commandware.com/demos/api7-demo.git +**Version**: 0.1.0 | **Last Updated**: 2025-10-07 diff --git a/api/README.md b/api/README.md index e64644d..3adf835 100644 --- a/api/README.md +++ b/api/README.md @@ -1,87 +1,787 @@ -# API Service - FastAPI +# API Service - FastAPI Backend -A RESTful API service built with FastAPI featuring Swagger documentation. +A RESTful API service built with FastAPI featuring automatic Swagger documentation, CRUD operations, and integrated LLM endpoints with OpenAI-compatible API support. -## Features +## πŸ“‹ Overview -- πŸ“š Automatic Swagger/OpenAPI documentation -- πŸ”„ RESTful API endpoints -- βœ… Data validation with Pydantic -- πŸ“Š Statistics and monitoring endpoints -- ❀️ Health check endpoints +This API backend provides: -## Local Development +- **RESTful CRUD API**: Items and Users management +- **LLM Integration**: OpenAI-compatible chat endpoints for AI-powered features +- **Automatic Documentation**: Swagger UI and ReDoc +- **Data Validation**: Pydantic models with type checking +- **Health Monitoring**: Health check endpoints +- **Production Ready**: Designed for Kubernetes deployment with API7 Gateway -### Run with Python +## ✨ Features + +### REST API + +- **Items Management**: Create, read, update, delete items +- **Users Management**: User CRUD operations +- **Pagination Support**: Query parameters for data filtering +- **Validation**: Automatic request/response validation with Pydantic + +### LLM Integration + +- **Chat Endpoint**: OpenAI-compatible chat completions API +- **Model Management**: List available LLM models +- **Token Tracking**: Returns token usage per request +- **Configurable**: Supports custom OpenAI-compatible backends (Open WebUI, Ollama, etc.) +- **Rate Limited**: Designed to work with API7's AI rate limiting (100 tokens/60s) + +### Documentation + +- **Swagger UI**: Interactive API documentation at `/docs` +- **ReDoc**: Alternative documentation at `/redoc` +- **OpenAPI Schema**: JSON schema at `/openapi.json` + +## πŸš€ Quick Start + +### Local Development + +#### Prerequisites ```bash -# Install dependencies -pip install -r requirements.txt +python >= 3.8 +pip +``` -# Run the application +#### Install Dependencies + +```bash +cd api +pip install -r requirements.txt +``` + +#### Run the Application + +```bash +# Basic run python main.py # Or use uvicorn directly -uvicorn main:app --reload --host 0.0.0.0 --port 8000 +uvicorn main:app --reload --host 0.0.0.0 --port 8001 + +# With custom port +uvicorn main:app --reload --port 8080 ``` -### Run with Docker +#### Access the API + +- **Root**: http://localhost:8001/ +- **Swagger UI**: http://localhost:8001/docs +- **ReDoc**: http://localhost:8001/redoc +- **Health Check**: http://localhost:8001/health + +### Docker + +#### Build Image ```bash -# Build image -docker build -t fastapi-api . - -# Run container -docker run -p 8000:8000 fastapi-api +docker build -t api-service . ``` -## API Endpoints +#### Run Container -### Items -- `GET /items` - List all items (with pagination) -- `GET /items/{item_id}` - Get specific item -- `POST /items` - Create new item -- `PUT /items/{item_id}` - Update item -- `DELETE /items/{item_id}` - Delete item - -### Users -- `GET /users` - List all users -- `GET /users/{user_id}` - Get specific user -- `POST /users` - Create new user - -### Other -- `GET /` - API information -- `GET /health` - Health check -- `GET /info` - Service information -- `GET /stats` - API statistics - -## Documentation - -- Swagger UI: http://localhost:8000/docs -- ReDoc: http://localhost:8000/redoc -- OpenAPI JSON: http://localhost:8000/openapi.json - -## Example Requests - -### Create Item ```bash -curl -X POST "http://localhost:8000/items" \ +# Basic run +docker run -p 8001:8001 api-service + +# With environment variables +docker run -p 8001:8001 \ + -e OPENAI_API_BASE="http://host.docker.internal:11434/api" \ + -e OPENAI_API_KEY="your-api-key" \ + -e DEFAULT_LLM_MODEL="videogame-expert" \ + api-service +``` + +## πŸ”Œ API Endpoints + +### Information Endpoints + +#### `GET /` + +Root endpoint with API information. + +**Response**: + +```json +{ + "message": "Welcome to API Demo", + "version": "1.0.0", + "docs": "/docs", + "timestamp": "2025-10-07T10:00:00" +} +``` + +#### `GET /health` + +Health check endpoint. + +**Response**: + +```json +{ + "status": "healthy", + "service": "api", + "timestamp": "2025-10-07T10:00:00" +} +``` + +### Items Endpoints + +#### `GET /items` + +Get all items with optional pagination. + +**Query Parameters**: + +- None (returns all items) + +**Response**: + +```json +[ + { + "id": 1, + "name": "Laptop", + "description": "High-performance laptop", + "price": 999.99, + "in_stock": true + }, + { + "id": 2, + "name": "Mouse", + "description": "Wireless mouse", + "price": 29.99, + "in_stock": true + } +] +``` + +#### `GET /items/{item_id}` + +Get a specific item by ID. + +**Response**: + +```json +{ + "id": 1, + "name": "Laptop", + "description": "High-performance laptop", + "price": 999.99, + "in_stock": true +} +``` + +#### `POST /items` + +Create a new item. + +**Request Body**: + +```json +{ + "name": "Monitor", + "description": "4K Display", + "price": 299.99, + "in_stock": true +} +``` + +**Response**: + +```json +{ + "id": 4, + "name": "Monitor", + "description": "4K Display", + "price": 299.99, + "in_stock": true +} +``` + +#### `PUT /items/{item_id}` + +Update an existing item. + +**Request Body**: + +```json +{ + "name": "Monitor", + "description": "Updated 4K Display", + "price": 279.99, + "in_stock": true +} +``` + +#### `DELETE /items/{item_id}` + +Delete an item. + +**Response**: + +```json +{ + "message": "Item deleted successfully" +} +``` + +### Users Endpoints + +#### `GET /users` + +Get all users. + +**Response**: + +```json +[ + { + "id": 1, + "username": "john_doe", + "email": "john@example.com", + "active": true + } +] +``` + +#### `GET /users/{user_id}` + +Get a specific user by ID. + +#### `POST /users` + +Create a new user. + +**Request Body**: + +```json +{ + "username": "jane_doe", + "email": "jane@example.com", + "active": true +} +``` + +### LLM Endpoints + +#### `POST /llm/chat` + +Send a chat message to the LLM. + +**Request Body**: + +```json +{ + "prompt": "What is The Legend of Zelda?", + "max_tokens": 150, + "temperature": 0.7, + "model": "videogame-expert" +} +``` + +**Response**: + +```json +{ + "response": "The Legend of Zelda is a high-fantasy action-adventure video game franchise created by Japanese game designers Shigeru Miyamoto and Takashi Tezuka...", + "tokens_used": 85, + "model": "videogame-expert", + "timestamp": "2025-10-07T10:00:00" +} +``` + +**Rate Limiting**: When deployed with API7 Gateway, this endpoint is limited to **100 tokens per 60 seconds** using AI rate limiting. + +#### `GET /llm/models` + +List available LLM models. + +**Response**: + +```json +{ + "models": [ + { + "id": "videogame-expert", + "name": "Videogame Expert", + "max_tokens": 4096, + "provider": "Open WebUI" + } + ], + "default_model": "videogame-expert", + "timestamp": "2025-10-07T10:00:00" +} +``` + +#### `GET /llm/health` + +LLM service health check. + +**Response**: + +```json +{ + "status": "healthy", + "service": "llm-api", + "provider": "Open WebUI", + "endpoint": "http://localhost/api", + "default_model": "videogame-expert", + "rate_limit": "ai-rate-limiting enabled (100 tokens/60s)", + "timestamp": "2025-10-07T10:00:00" +} +``` + +## πŸ”§ Configuration + +### Environment Variables + +Configure the API service using environment variables: + +| Variable | Description | Default | Required | +| ------------------- | ---------------------------------- | ---------------------- | -------- | +| `OPENAI_API_BASE` | OpenAI-compatible API endpoint URL | `http://localhost/api` | No | +| `OPENAI_API_KEY` | API key for LLM service | `your-api-key` | No | +| `DEFAULT_LLM_MODEL` | Default LLM model ID | `your-model-id` | No | + +### Example Configuration + +**Development**: + +```bash +export OPENAI_API_BASE="http://localhost:11434/api" +export OPENAI_API_KEY="not-required-for-ollama" +export DEFAULT_LLM_MODEL="llama2" +``` + +**Production (Open WebUI)**: + +```bash +export OPENAI_API_BASE="https://openwebui.example.com/api" +export OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxx" +export DEFAULT_LLM_MODEL="videogame-expert" +``` + +**Kubernetes Deployment**: + +```yaml +env: + - name: OPENAI_API_BASE + value: "http://openwebui.ai:8080/api" + - name: OPENAI_API_KEY + valueFrom: + secretKeyRef: + name: llm-secrets + key: api-key + - name: DEFAULT_LLM_MODEL + value: "videogame-expert" +``` + +## πŸ“Š Data Models + +### Item Model + +```python +class Item(BaseModel): + id: Optional[int] = None + name: str + description: Optional[str] = None + price: float + in_stock: bool = True +``` + +### User Model + +```python +class User(BaseModel): + id: Optional[int] = None + username: str + email: str + active: bool = True +``` + +### LLM Request Model + +```python +class LLMRequest(BaseModel): + prompt: str + max_tokens: Optional[int] = 150 + temperature: Optional[float] = 0.7 + model: Optional[str] = DEFAULT_MODEL +``` + +### LLM Response Model + +```python +class LLMResponse(BaseModel): + response: str + tokens_used: int + model: str + timestamp: str +``` + +## πŸ§ͺ Testing + +### cURL Examples + +**Create Item**: + +```bash +curl -X POST "http://localhost:8001/items" \ -H "Content-Type: application/json" \ -d '{ - "id": 4, - "name": "Monitor", - "description": "4K Display", - "price": 299.99, + "name": "Keyboard", + "description": "Mechanical keyboard", + "price": 79.99, "in_stock": true }' ``` -### Get Items +**Get Items**: + ```bash -curl "http://localhost:8000/items?skip=0&limit=10&in_stock=true" +curl "http://localhost:8001/items" ``` -### Get Statistics +**Update Item**: + ```bash -curl "http://localhost:8000/stats" +curl -X PUT "http://localhost:8001/items/1" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "Laptop Pro", + "description": "Updated laptop", + "price": 1099.99, + "in_stock": true + }' ``` + +**Delete Item**: + +```bash +curl -X DELETE "http://localhost:8001/items/3" +``` + +**LLM Chat**: + +```bash +curl -X POST "http://localhost:8001/llm/chat" \ + -H "Content-Type: application/json" \ + -d '{ + "prompt": "Tell me about Mario Bros", + "max_tokens": 100, + "temperature": 0.7, + "model": "videogame-expert" + }' +``` + +**Health Checks**: + +```bash +curl "http://localhost:8001/health" +curl "http://localhost:8001/llm/health" +``` + +### Python Testing + +```python +import httpx + +# Test item creation +async with httpx.AsyncClient() as client: + response = await client.post( + "http://localhost:8001/items", + json={ + "name": "Monitor", + "description": "4K Display", + "price": 299.99, + "in_stock": True + } + ) + print(response.json()) + +# Test LLM chat +async with httpx.AsyncClient() as client: + response = await client.post( + "http://localhost:8001/llm/chat", + json={ + "prompt": "What is Minecraft?", + "max_tokens": 150, + "model": "videogame-expert" + } + ) + print(response.json()) +``` + +## 🐳 Docker + +### Dockerfile + +The Dockerfile uses Python 3.11 slim image and installs dependencies directly: + +```dockerfile +FROM python:3.11-slim + +WORKDIR /app + +# Install dependencies +RUN pip install --no-cache-dir fastapi uvicorn[standard] pydantic + +# Copy application +COPY db.json . +COPY main.py . + +EXPOSE 8001 + +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8001"] +``` + +### Build and Run + +```bash +# Build +docker build -t api-service:latest . + +# Run with environment variables +docker run -d \ + --name api-service \ + -p 8001:8001 \ + -e OPENAI_API_BASE="http://host.docker.internal:11434/api" \ + -e OPENAI_API_KEY="your-key" \ + api-service:latest + +# View logs +docker logs -f api-service + +# Stop and remove +docker stop api-service +docker rm api-service +``` + +## ☸️ Kubernetes Deployment + +### Basic Deployment + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: api-service + namespace: api7ee +spec: + replicas: 3 + selector: + matchLabels: + app: api + template: + metadata: + labels: + app: api + spec: + containers: + - name: api + image: git.commandware.com/demos/api7-demo/api:main + ports: + - containerPort: 8001 + name: http + env: + - name: OPENAI_API_BASE + value: "http://openwebui.ai:8080/api" + - name: OPENAI_API_KEY + valueFrom: + secretKeyRef: + name: llm-secrets + key: api-key + - name: DEFAULT_LLM_MODEL + value: "videogame-expert" + livenessProbe: + httpGet: + path: /health + port: 8001 + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /health + port: 8001 + initialDelaySeconds: 10 + periodSeconds: 5 + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 500m + memory: 512Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: api-service + namespace: api7ee +spec: + type: ClusterIP + ports: + - port: 8080 + targetPort: 8001 + name: http + selector: + app: api +``` + +### With Helm + +See the [Helm chart README](../helm/api7ee-demo-k8s/README.md) for full deployment options. + +```bash +helm install api7ee-demo ./helm/api7ee-demo-k8s \ + --set api.image.tag=v1.0.0 \ + --set api.replicaCount=5 \ + --namespace api7ee +``` + +## πŸ”’ Security + +### Best Practices + +1. **Environment Variables**: Store sensitive data (API keys) in Kubernetes Secrets +2. **Non-root User**: Container runs as non-root user (UID 1000) +3. **Read-only Filesystem**: Root filesystem is read-only +4. **Input Validation**: All requests validated with Pydantic +5. **CORS**: Configure CORS policies in API7 Gateway +6. **Rate Limiting**: API7 Gateway enforces rate limits + +### Example Secret + +```bash +kubectl create secret generic llm-secrets \ + --from-literal=api-key='your-openai-api-key' \ + -n api7ee +``` + +## πŸ“¦ Dependencies + +### Python Requirements + +``` +fastapi==0.104.1 +uvicorn[standard]==0.24.0 +pydantic==2.5.0 +httpx==0.26.0 +``` + +### Install + +```bash +pip install -r requirements.txt +``` + +## πŸš€ Production Deployment + +### Recommended Configuration + +```yaml +api: + replicaCount: 5 + autoscaling: + enabled: true + minReplicas: 5 + maxReplicas: 30 + targetCPUUtilizationPercentage: 70 + resources: + limits: + cpu: 2000m + memory: 2Gi + requests: + cpu: 1000m + memory: 1Gi + env: + - name: LOG_LEVEL + value: "warn" + - name: ENVIRONMENT + value: "production" +``` + +### API7 Gateway Integration + +When deployed behind API7 Gateway: + +**Rate Limiting**: + +- `/api/*`: 100 requests/60s per IP (standard rate limiting) +- `/api/llm/*`: 100 tokens/60s (AI rate limiting) + +**Routing**: + +- Priority 10: `/api/*` routes +- Priority 20: `/api/llm/*` routes (higher priority) + +**Plugins**: + +- `redirect`: HTTP β†’ HTTPS +- `limit-count`: IP-based rate limiting +- `ai-rate-limiting`: Token-based LLM rate limiting + +## πŸ“š Resources + +### Documentation + +- **FastAPI**: https://fastapi.tiangolo.com/ +- **Pydantic**: https://docs.pydantic.dev/ +- **Uvicorn**: https://www.uvicorn.org/ +- **OpenAI API**: https://platform.openai.com/docs/api-reference + +### Related + +- [Main README](../README.md) +- [Web Application README](../web/README.md) +- [Helm Chart README](../helm/api7ee-demo-k8s/README.md) + +## πŸ› Troubleshooting + +### Common Issues + +**Issue**: LLM endpoints return errors + +```bash +# Check environment variables +echo $OPENAI_API_BASE +echo $OPENAI_API_KEY + +# Test LLM backend directly +curl -X POST "$OPENAI_API_BASE/chat/completions" \ + -H "Authorization: Bearer $OPENAI_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{"model":"videogame-expert","messages":[{"role":"user","content":"test"}]}' +``` + +**Issue**: Rate limiting triggered + +```bash +# Check API7 Gateway logs +kubectl logs -n api7ee -l app=api7-gateway + +# Response: HTTP 429 +# Cause: Exceeded 100 tokens/60s or 100 req/60s +# Solution: Wait for rate limit window to reset +``` + +**Issue**: Health check fails + +```bash +# Check if service is running +curl http://localhost:8001/health + +# Check logs +docker logs api-service +# or +kubectl logs -n api7ee -l app=api +``` + +--- + +**Version**: 1.0.0 | **Port**: 8001 | **Framework**: FastAPI 0.104.1 diff --git a/helm/api7ee-demo-k8s/README.md b/helm/api7ee-demo-k8s/README.md index 2bab7d0..6b6cd02 100644 --- a/helm/api7ee-demo-k8s/README.md +++ b/helm/api7ee-demo-k8s/README.md @@ -1,123 +1,267 @@ -# API7 Enterprise Edition Helm Chart +# API7 Enterprise Edition Demo - Helm Chart -This Helm chart deploys the API7 Enterprise Edition demo application, consisting of a Web frontend and API backend service. +A comprehensive Helm chart for deploying the API7 Enterprise Edition demo platform on Kubernetes. This chart deploys both web frontend and API backend services with full API7 Gateway integration, including automatic ADC configuration, TLS management, and advanced rate limiting. -## Prerequisites +## πŸ“‹ Overview -- Kubernetes 1.19+ -- Helm 3.8.0+ -- PV provisioner support in the underlying infrastructure (optional) -- Ingress controller (e.g., NGINX Ingress Controller) +This Helm chart provides: -## Installation +- **Dual Service Deployment**: Web frontend + API backend +- **API7 Gateway Integration**: Automatic ADC (API7 Declarative CLI) configuration +- **TLS/SSL Management**: cert-manager integration or custom certificates +- **Service Discovery**: Kubernetes-native service discovery +- **Rate Limiting**: Standard and AI token-based rate limiting +- **Autoscaling**: Horizontal Pod Autoscaler (HPA) support +- **High Availability**: Pod Disruption Budgets and multi-replica deployment +- **Security**: Pod Security Contexts, RBAC, and Network Policies -### Add the Helm repository (if published) +## 🎯 Features + +### Deployments + +- **Web Service** (apache-service): FastAPI frontend with embedded documentation +- **API Service** (nginx-service): FastAPI backend with REST API and LLM endpoints + +### API7 Gateway Configuration + +- **Automatic ADC Sync**: Configures routes, services, and upstreams +- **Advanced Rate Limiting**: + - Standard: 100 req/60s per IP for `/api/*` + - AI: 100 tokens/60s for `/api/llm/*` +- **Route Prioritization**: LLM (20) > API (10) > Web (1) +- **TLS/SSL**: Automatic HTTPS redirect and certificate management +- **Plugins**: CORS, Prometheus metrics, request logging, authentication + +### Kubernetes Resources + +- Deployments (Web and API) +- Services (ClusterIP) +- Ingress (NGINX) +- ConfigMaps (Application config and ADC config) +- Secrets (TLS certificates, API7 credentials) +- ServiceAccount and RBAC +- HorizontalPodAutoscaler +- PodDisruptionBudget +- Certificate (cert-manager) +- Job (ADC sync) + +## πŸ“¦ Prerequisites + +- **Kubernetes**: v1.19 or higher +- **Helm**: 3.8.0 or higher +- **API7 Enterprise Edition**: Installed and configured +- **Ingress Controller**: NGINX Ingress Controller (recommended) +- **cert-manager**: v1.0+ (optional, for automatic TLS) + +## πŸš€ Installation + +### Add Helm Repository ```bash +# Add the Gitea 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/api7ee-demo-k8s ``` -### Install the chart +### Basic Installation ```bash # Install with default values -helm install my-api7ee ./helm/api7ee-demo-k8s-demo-k8s +helm install api7ee-demo api7ee/api7ee-demo-k8s \ + --namespace api7ee \ + --create-namespace -# Install in a specific namespace -helm install my-api7ee ./helm/api7ee-demo-k8s-demo-k8s --namespace api7ee --create-namespace +# Check installation +helm list -n api7ee +kubectl get pods -n api7ee +``` +### Installation with Custom Values + +```bash # Install with custom values file -helm install my-api7ee ./helm/api7ee-demo-k8s-demo-k8s -f custom-values.yaml +helm install api7ee-demo api7ee/api7ee-demo-k8s \ + --namespace api7ee \ + --create-namespace \ + -f custom-values.yaml + +# Install with command-line overrides +helm install api7ee-demo api7ee/api7ee-demo-k8s \ + --namespace api7ee \ + --set web.replicaCount=3 \ + --set api.replicaCount=5 \ + --set api7.gateway.adminKey="your-admin-key" \ + --set api7.hosts[0]="your-domain.com" ``` -## Configuration +### Install from Local Chart -### API7 Gateway Integration +```bash +# Install from local directory +helm install api7ee-demo ./helm/api7ee-demo-k8s \ + --namespace api7ee \ + --create-namespace -This Helm chart includes automatic API7 Gateway configuration using ADC (API7 Declarative CLI). When `api7.enabled` is set to `true`, the chart will: - -1. **Deploy ADC Configuration**: Creates routes, services, and upstreams for your applications -2. **Configure TLS/SSL**: Manages certificates via cert-manager or custom certificates -3. **Enable Service Discovery**: Uses Kubernetes native service discovery -4. **Apply Security Policies**: Configures rate limiting, CORS, and authentication -5. **Auto-publish Routes**: Optionally publishes routes automatically after deployment - -### Key Configuration Options - -| Parameter | Description | Default | -|-----------|-------------|---------| -| `web.enabled` | Enable Web component | `true` | -| `web.replicaCount` | Number of Web replicas | `2` | -| `web.image.repository` | Web image repository | `api7ee/web` | -| `web.image.tag` | Web image tag | `main` | -| `web.service.port` | Web service port | `8000` | -| `api.enabled` | Enable API component | `true` | -| `api.replicaCount` | Number of API replicas | `3` | -| `api.image.repository` | API image repository | `api7ee/api` | -| `api.image.tag` | API image tag | `main` | -| `api.service.port` | API service port | `8080` | -| `ingress.enabled` | Enable ingress | `true` | -| `ingress.hosts[0].host` | Ingress hostname | `demo.commandware.it` | -| `api7.enabled` | Enable API7 ADC configuration | `true` | -| `api7.gateway.adminUrl` | API7 Gateway Admin API URL | `http://api7-gateway.api7ee:9180` | -| `api7.hosts` | Hosts for API7 routing | `[demo.commandware.it]` | -| `api7.tls.certManager.enabled` | Use cert-manager for TLS | `true` | -| `api7.autoPublish` | Auto-publish routes | `true` | - -### Custom Values Examples - -#### Configure API7 Gateway: - -```yaml -api7: - enabled: true - gateway: - adminUrl: http://your-api7-gateway:9180 - adminKey: "your-admin-key-here" - group: production - hosts: - - api.yourdomain.com - tls: - certManager: - enabled: true - issuer: letsencrypt-prod - plugins: - rateLimit: - enabled: true - count: 1000 - timeWindow: 60 - auth: - enabled: true - consumers: - - username: api-client - apiKey: secure-api-key-12345 +# With development values +helm install api7ee-dev ./helm/api7ee-demo-k8s \ + -f ./helm/api7ee-demo-k8s/values-dev.yaml \ + --namespace api7ee-dev ``` -#### Using a private registry: +## βš™οΈ Configuration + +### Global Configuration + +| Parameter | Description | Default | +| ------------------------- | ---------------------- | ------- | +| `global.imageRegistry` | Global Docker registry | `""` | +| `global.imagePullSecrets` | Image pull secrets | `[]` | + +### Web Service Configuration + +| Parameter | Description | Default | +| ------------------------------------------------ | --------------------- | ---------------------- | +| `web.enabled` | Enable Web component | `true` | +| `web.replicaCount` | Number of replicas | `2` | +| `web.image.registry` | Image registry | `gitea.server_url` | +| `web.image.repository` | Image repository | `gitea.repository/web` | +| `web.image.tag` | Image tag | `main` | +| `web.image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `web.service.type` | Service type | `ClusterIP` | +| `web.service.port` | Service port | `8000` | +| `web.resources.limits.cpu` | CPU limit | `500m` | +| `web.resources.limits.memory` | Memory limit | `512Mi` | +| `web.resources.requests.cpu` | CPU request | `250m` | +| `web.resources.requests.memory` | Memory request | `256Mi` | +| `web.autoscaling.enabled` | Enable HPA | `false` | +| `web.autoscaling.minReplicas` | Min replicas | `2` | +| `web.autoscaling.maxReplicas` | Max replicas | `10` | +| `web.autoscaling.targetCPUUtilizationPercentage` | CPU target | `80` | +| `web.env` | Environment variables | `[]` | + +### API Service Configuration + +| Parameter | Description | Default | +| ------------------------------------------------ | --------------------- | ---------------------------------- | +| `api.enabled` | Enable API component | `true` | +| `api.replicaCount` | Number of replicas | `3` | +| `api.image.registry` | Image registry | `gitea.server_url` | +| `api.image.repository` | Image repository | `gitea.repository/api` | +| `api.image.tag` | Image tag | `main` | +| `api.image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `api.service.type` | Service type | `ClusterIP` | +| `api.service.port` | Service port | `8080` | +| `api.resources.limits.cpu` | CPU limit | `1000m` | +| `api.resources.limits.memory` | Memory limit | `1Gi` | +| `api.resources.requests.cpu` | CPU request | `500m` | +| `api.resources.requests.memory` | Memory request | `512Mi` | +| `api.autoscaling.enabled` | Enable HPA | `true` | +| `api.autoscaling.minReplicas` | Min replicas | `3` | +| `api.autoscaling.maxReplicas` | Max replicas | `20` | +| `api.autoscaling.targetCPUUtilizationPercentage` | CPU target | `70` | +| `api.env` | Environment variables | `[{name: LOG_LEVEL, value: info}]` | + +### Ingress Configuration + +| Parameter | Description | Default | +| --------------------------- | ------------------- | ---------------------------- | +| `ingress.enabled` | Enable ingress | `true` | +| `ingress.className` | Ingress class | `nginx` | +| `ingress.annotations` | Ingress annotations | See values.yaml | +| `ingress.hosts[0].host` | Hostname | `api7-demo.commandware.it` | +| `ingress.tls[0].secretName` | TLS secret | `api7ee-tls` | +| `ingress.tls[0].hosts` | TLS hosts | `[api7-demo.commandware.it]` | + +### API7 Gateway Configuration + +| Parameter | Description | Default | +| ----------------------------- | ---------------------- | ------------------------------------ | +| `api7.enabled` | Enable API7 ADC config | `true` | +| `api7.adc.image` | ADC Docker image | `ghcr.io/api7/adc:latest` | +| `api7.adc.verbose` | Verbose logging | `true` | +| `api7.adc.tlsSkipVerify` | Skip TLS verify | `false` | +| `api7.gateway.adminUrl` | API7 Admin API URL | `http://api7ee3-0-xxx-dp-manager...` | +| `api7.gateway.adminKey` | API7 Admin API key | `edd1c9f034335f136f87ad84b625c8f1` | +| `api7.gateway.group` | Gateway group | `default` | +| `api7.gateway.gatewayService` | Gateway service name | `gateway-0-xxx-gateway` | +| `api7.backend` | Backend type | `api7ee` | +| `api7.autoPublish` | Auto-publish routes | `true` | +| `api7.hosts` | Routing hosts | `[api7-demo.commandware.it]` | + +### TLS Configuration + +| Parameter | Description | Default | +| --------------------------------- | ------------------- | ---------------------- | +| `api7.tls.enabled` | Enable TLS | `true` | +| `api7.tls.certManager.enabled` | Use cert-manager | `true` | +| `api7.tls.certManager.issuer` | ClusterIssuer name | `cloudflare-acme-prod` | +| `api7.tls.certManager.issuerKind` | Issuer kind | `ClusterIssuer` | +| `api7.tls.secretName` | Existing TLS secret | `""` | +| `api7.tls.certificate` | Direct certificate | `""` | +| `api7.tls.key` | Direct key | `""` | + +### Rate Limiting Configuration + +| Parameter | Description | Default | +| ---------------------------------------- | ----------------------------- | -------------- | +| `api7.plugins.rateLimit.enabled` | Enable standard rate limiting | `true` | +| `api7.plugins.rateLimit.count` | Request limit | `100` | +| `api7.plugins.rateLimit.timeWindow` | Time window (seconds) | `60` | +| `api7.plugins.rateLimit.keyType` | Key type | `var` | +| `api7.plugins.rateLimit.key` | Key variable | `remote_addr` | +| `api7.plugins.aiRateLimit.enabled` | Enable AI rate limiting | `true` | +| `api7.plugins.aiRateLimit.limit` | Token limit | `100` | +| `api7.plugins.aiRateLimit.timeWindow` | Time window (seconds) | `60` | +| `api7.plugins.aiRateLimit.limitStrategy` | Limit strategy | `total_tokens` | + +### Additional Plugins + +| Parameter | Description | Default | +| --------------------------------- | ------------------------- | ------- | +| `api7.plugins.cors.enabled` | Enable CORS | `true` | +| `api7.plugins.cors.allowOrigins` | Allowed origins | `["*"]` | +| `api7.plugins.auth.enabled` | Enable authentication | `false` | +| `api7.plugins.prometheus.enabled` | Enable Prometheus metrics | `true` | +| `api7.plugins.logging.enabled` | Enable request logging | `false` | + +## πŸ“ Configuration Examples + +### Production Deployment ```yaml +# production-values.yaml global: - imageRegistry: my-registry.example.com + imageRegistry: "git.commandware.com" imagePullSecrets: - - name: my-registry-secret -``` + - name: registry-secret -#### Enabling autoscaling: - -```yaml web: + replicaCount: 3 + image: + tag: "v1.0.0" + pullPolicy: Always + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 500m + memory: 512Mi autoscaling: enabled: true - minReplicas: 2 - maxReplicas: 10 - targetCPUUtilizationPercentage: 70 -``` + minReplicas: 3 + maxReplicas: 15 -#### Custom resource limits: - -```yaml api: + replicaCount: 5 + image: + tag: "v1.0.0" + pullPolicy: Always resources: limits: cpu: 2000m @@ -125,31 +269,406 @@ api: requests: cpu: 1000m memory: 1Gi + autoscaling: + enabled: true + minReplicas: 5 + maxReplicas: 30 + +api7: + gateway: + adminKey: "${API7_ADMIN_KEY}" # Use secret + hosts: + - api7-demo.yourdomain.com + plugins: + rateLimit: + count: 1000 + auth: + enabled: true ``` -## Upgrading +```bash +helm install api7ee-prod api7ee/api7ee-demo-k8s \ + -f production-values.yaml \ + --namespace api7ee-prod \ + --create-namespace +``` + +### Custom Domain and TLS + +```yaml +# custom-domain-values.yaml +api7: + hosts: + - api.example.com + - demo.example.com + tls: + certManager: + enabled: true + issuer: letsencrypt-prod + +ingress: + hosts: + - host: api.example.com + paths: + - path: / + pathType: Prefix + service: web + tls: + - secretName: example-tls + hosts: + - api.example.com +``` + +### High Resource Environment + +```yaml +# high-resources-values.yaml +web: + replicaCount: 5 + resources: + limits: + cpu: 2000m + memory: 2Gi + requests: + cpu: 1000m + memory: 1Gi + autoscaling: + enabled: true + maxReplicas: 20 + +api: + replicaCount: 10 + resources: + limits: + cpu: 4000m + memory: 4Gi + requests: + cpu: 2000m + memory: 2Gi + autoscaling: + enabled: true + maxReplicas: 50 + +podDisruptionBudget: + enabled: true + minAvailable: 3 +``` + +### Custom API7 Gateway + +```yaml +# custom-gateway-values.yaml +api7: + gateway: + adminUrl: http://my-api7-gateway:9180 + adminKey: "my-custom-key" + group: production + gatewayService: my-gateway-service + backend: apisix # or api7ee + autoPublish: false # Manual publish +``` + +### LLM Configuration + +```yaml +# llm-values.yaml +api: + env: + - name: OPENAI_API_BASE + value: "http://openwebui.ai:8080/api" + - name: OPENAI_API_KEY + valueFrom: + secretKeyRef: + name: llm-secrets + key: api-key + - name: DEFAULT_LLM_MODEL + value: "videogame-expert" + +api7: + plugins: + aiRateLimit: + enabled: true + limit: 200 # Higher limit + timeWindow: 60 +``` + +### Development Environment + +Use the included `values-dev.yaml`: ```bash -# Upgrade to a new version -helm upgrade my-api7ee ./helm/api7ee-demo-k8s-demo-k8s +helm install api7ee-dev ./helm/api7ee-demo-k8s \ + -f ./helm/api7ee-demo-k8s/values-dev.yaml \ + --namespace api7ee-dev +``` +## πŸ”„ Upgrade and Rollback + +### Upgrade Release + +```bash # Upgrade with new values -helm upgrade my-api7ee ./helm/api7ee-demo-k8s-demo-k8s --set web.replicaCount=3 +helm upgrade api7ee-demo api7ee/api7ee-demo-k8s \ + --namespace api7ee \ + -f new-values.yaml + +# Upgrade with inline values +helm upgrade api7ee-demo api7ee/api7ee-demo-k8s \ + --namespace api7ee \ + --reuse-values \ + --set api.replicaCount=5 + +# Force upgrade +helm upgrade api7ee-demo api7ee/api7ee-demo-k8s \ + --namespace api7ee \ + --force ``` -## Uninstallation +### Rollback ```bash -# Uninstall the release -helm uninstall my-api7ee +# View release history +helm history api7ee-demo -n api7ee -# Uninstall from a specific namespace -helm uninstall my-api7ee --namespace api7ee +# Rollback to previous release +helm rollback api7ee-demo -n api7ee + +# Rollback to specific revision +helm rollback api7ee-demo 3 -n api7ee ``` -## Monitoring +### Verify Upgrade -If metrics are enabled, the services expose Prometheus-compatible metrics: +```bash +# Check release status +helm status api7ee-demo -n api7ee + +# View current values +helm get values api7ee-demo -n api7ee + +# Check all resources +kubectl get all -n api7ee -l app.kubernetes.io/instance=api7ee-demo +``` + +## πŸ—‘οΈ Uninstallation + +```bash +# Uninstall release +helm uninstall api7ee-demo --namespace api7ee + +# Keep release history (for rollback) +helm uninstall api7ee-demo --namespace api7ee --keep-history + +# Delete namespace +kubectl delete namespace api7ee +``` + +## πŸ” Verification and Testing + +### Check Deployment Status + +```bash +# Helm release status +helm list -n api7ee +helm status api7ee-demo -n api7ee + +# Kubernetes resources +kubectl get all -n api7ee +kubectl get pods -n api7ee -w + +# Check specific resources +kubectl get deployments -n api7ee +kubectl get services -n api7ee +kubectl get ingress -n api7ee +kubectl get hpa -n api7ee +``` + +### View Logs + +```bash +# Web service logs +kubectl logs -n api7ee -l app=apache-service --tail=50 + +# API service logs +kubectl logs -n api7ee -l app=nginx-service --tail=50 + +# ADC sync job logs +kubectl logs -n api7ee -l app.kubernetes.io/component=adc-sync + +# All logs +kubectl logs -n api7ee -l app.kubernetes.io/instance=api7ee-demo --all-containers +``` + +### Test Endpoints + +```bash +# Get ingress URL +INGRESS_HOST=$(kubectl get ingress -n api7ee api7ee-demo-ingress -o jsonpath='{.spec.rules[0].host}') + +# Test web service +curl https://$INGRESS_HOST/ + +# Test API +curl https://$INGRESS_HOST/api/items + +# Test health checks +curl https://$INGRESS_HOST/health +curl https://$INGRESS_HOST/api/health + +# Test LLM endpoint +curl -X POST https://$INGRESS_HOST/api/llm/chat \ + -H "Content-Type: application/json" \ + -d '{ + "prompt": "What is Zelda?", + "max_tokens": 100 + }' +``` + +## πŸ”§ Troubleshooting + +### Common Issues + +#### 1. ADC Sync Job Fails + +**Check job logs**: + +```bash +kubectl logs -n api7ee -l app.kubernetes.io/component=adc-sync + +# Common errors: +# - "connection refused" β†’ Check adminUrl +# - "unauthorized" β†’ Verify adminKey +# - "route not found" β†’ Check backend type (api7ee vs apisix) +``` + +**Solution**: + +```bash +# Update API7 credentials +helm upgrade api7ee-demo api7ee/api7ee-demo-k8s \ + --namespace api7ee \ + --reuse-values \ + --set api7.gateway.adminKey="correct-admin-key" +``` + +#### 2. Pods Not Starting + +**Check pod status**: + +```bash +kubectl describe pod -n api7ee + +# Common issues: +# - ImagePullBackOff β†’ Check image registry credentials +# - CrashLoopBackOff β†’ Check application logs +# - Pending β†’ Check resources and node capacity +``` + +**Solution for ImagePullBackOff**: + +```bash +# Create registry secret +kubectl create secret docker-registry gitea-registry \ + --docker-server=git.commandware.com \ + --docker-username= \ + --docker-password= \ + -n api7ee + +# Update values +helm upgrade api7ee-demo api7ee/api7ee-demo-k8s \ + --namespace api7ee \ + --reuse-values \ + --set global.imagePullSecrets[0].name=gitea-registry +``` + +#### 3. Routes Return 404 + +**Cause**: Routes not published to gateway group + +**Check API7 Dashboard**: + +``` +Services β†’ Select service β†’ Routes β†’ Check publication status +``` + +**Solution**: + +```bash +# Enable auto-publish +helm upgrade api7ee-demo api7ee/api7ee-demo-k8s \ + --namespace api7ee \ + --reuse-values \ + --set api7.autoPublish=true + +# Or publish manually via Dashboard: +# Click "Publish" β†’ Select "default" gateway group +``` + +#### 4. TLS Certificate Issues + +**Check certificate status**: + +```bash +kubectl get certificate -n api7ee +kubectl describe certificate -n api7ee api7ee-tls + +# Check cert-manager logs +kubectl logs -n cert-manager -l app=cert-manager --tail=50 +``` + +**Verify cert-manager configuration**: + +```bash +# Check ClusterIssuer +kubectl get clusterissuer cloudflare-acme-prod + +# Check challenge +kubectl get challenge -n api7ee +``` + +#### 5. Service Discovery Not Working + +**Check services have named ports**: + +```bash +kubectl get svc -n api7ee apache-service -o yaml | grep -A5 ports + +# Ports must have 'name' field: +# ports: +# - port: 80 +# name: http # ← Required +``` + +**Check endpoints**: + +```bash +kubectl get endpoints -n api7ee +``` + +#### 6. HPA Not Scaling + +**Check HPA status**: + +```bash +kubectl get hpa -n api7ee +kubectl describe hpa -n api7ee +``` + +**Verify metrics-server**: + +```bash +kubectl top nodes +kubectl top pods -n api7ee + +# If metrics not available, install metrics-server: +kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml +``` + +## πŸ“Š Monitoring + +### Prometheus Metrics + +If Prometheus is enabled: ```yaml metrics: @@ -159,59 +678,150 @@ metrics: interval: 30s ``` -## Troubleshooting - -### API7 ADC Sync Issues - -If the ADC sync job fails: +**View metrics**: ```bash -# Check the job status -kubectl get jobs -l app.kubernetes.io/instance=my-api7ee +# Check ServiceMonitor +kubectl get servicemonitor -n api7ee -# View job logs -kubectl logs job/my-api7ee-adc-sync - -# Manually run ADC sync -kubectl run adc-debug --rm -it --image=ghcr.io/api7/adc:latest -- /bin/sh +# Query Prometheus +curl http:///api/v1/query?query=up{job="api7ee"} ``` -### Verify API7 Configuration +### API7 Dashboard + +Access API7 Dashboard to view: + +- Route traffic and statistics +- Rate limiting metrics +- Service health and upstreams +- Plugin performance + +## πŸ” Security + +### Security Features + +- **Pod Security Context**: Runs as non-root user (UID 1000) +- **Security Context**: Drops all capabilities, prevents privilege escalation +- **Read-only Root Filesystem**: Enabled for both services +- **Network Policies**: Optional network policy support +- **RBAC**: ServiceAccount with minimal permissions +- **Secrets Management**: TLS certificates and API keys stored securely + +### Enable Network Policies + +```yaml +networkPolicy: + enabled: true + ingress: + - from: + - namespaceSelector: + matchLabels: + name: api7ee + ports: + - protocol: TCP + port: 8000 +``` + +### Secrets Management + +**Create secrets before installation**: ```bash -# Check if routes are configured -curl -H "X-API-KEY: your-admin-key" http://api7-gateway:9180/apisix/admin/routes +# API7 admin key +kubectl create secret generic api7-admin-key \ + --from-literal=adminKey='your-admin-key' \ + -n api7ee -# Check service discovery -curl -H "X-API-KEY: your-admin-key" http://api7-gateway:9180/apisix/admin/upstreams +# LLM API key +kubectl create secret generic llm-secrets \ + --from-literal=api-key='your-llm-api-key' \ + -n api7ee + +# Image pull secret +kubectl create secret docker-registry gitea-registry \ + --docker-server=git.commandware.com \ + --docker-username= \ + --docker-password= \ + -n api7ee ``` -### Check deployment status: -```bash -kubectl get deployments -l app.kubernetes.io/instance=my-api7ee +**Reference in values**: + +```yaml +api7: + gateway: + adminKey: "${API7_ADMIN_KEY}" + +api: + env: + - name: OPENAI_API_KEY + valueFrom: + secretKeyRef: + name: llm-secrets + key: api-key ``` -### View logs: -```bash -# Web component logs -kubectl logs -l app.kubernetes.io/instance=my-api7ee,app.kubernetes.io/component=web +## πŸ“š Chart Structure -# API component logs -kubectl logs -l app.kubernetes.io/instance=my-api7ee,app.kubernetes.io/component=api +``` +helm/api7ee-demo-k8s/ +β”œβ”€β”€ Chart.yaml # Chart metadata +β”œβ”€β”€ values.yaml # Default values +β”œβ”€β”€ values-dev.yaml # Development overrides +β”œβ”€β”€ values-production.yaml # Production overrides +β”œβ”€β”€ templates/ +β”‚ β”œβ”€β”€ NOTES.txt # Post-install notes +β”‚ β”œβ”€β”€ _helpers.tpl # Template helpers +β”‚ β”œβ”€β”€ deployment-web.yaml # Web deployment +β”‚ β”œβ”€β”€ deployment-api.yaml # API deployment +β”‚ β”œβ”€β”€ service-web.yaml # Web service +β”‚ β”œβ”€β”€ service-api.yaml # API service +β”‚ β”œβ”€β”€ ingress.yaml # Ingress resource +β”‚ β”œβ”€β”€ configmap.yaml # Application config +β”‚ β”œβ”€β”€ configmap-adc.yaml # API7 ADC config +β”‚ β”œβ”€β”€ job-adc-sync.yaml # ADC sync job +β”‚ β”œβ”€β”€ secret.yaml # Application secrets +β”‚ β”œβ”€β”€ secret-api7.yaml # API7 secrets +β”‚ β”œβ”€β”€ certificate.yaml # cert-manager certificate +β”‚ β”œβ”€β”€ serviceaccount.yaml # ServiceAccount +β”‚ β”œβ”€β”€ rbac-adc.yaml # RBAC for ADC +β”‚ β”œβ”€β”€ hpa-web.yaml # Web HPA +β”‚ β”œβ”€β”€ hpa-api.yaml # API HPA +β”‚ └── poddisruptionbudget.yaml # PDB +└── README.md # This file ``` -### Check HPA status: -```bash -kubectl get hpa -l app.kubernetes.io/instance=my-api7ee -``` +## πŸ“¦ Chart Information -## Security Considerations +- **Name**: api7ee-demo-k8s +- **Version**: 0.1.0 +- **App Version**: 1.0.0 +- **Type**: application +- **Keywords**: api7, api-gateway, web, api +- **Home**: https://demo.commandware.it +- **Sources**: https://git.commandware.com/demos/api7-demo -- Pod Security Context is configured to run as non-root user (UID 1000) -- Security Context drops all capabilities and prevents privilege escalation -- Read-only root filesystem is enabled -- Network policies can be enabled to restrict traffic +## πŸ“„ Resources -## Support +### Documentation -For issues and questions, please contact support@commandware.com or visit https://git.commandware.com/demos/api7-demo \ No newline at end of file +- **Helm**: https://helm.sh/docs/ +- **API7 Enterprise**: https://docs.api7.ai/ +- **Kubernetes**: https://kubernetes.io/docs/ + +### Related + +- [Main README](../../README.md) +- [Web Application README](../../web/README.md) +- [API Application README](../../api/README.md) + +## 🀝 Support + +- **Issues**: https://git.commandware.com/demos/api7-demo/issues +- **Email**: support@commandware.com +- **Repository**: https://git.commandware.com/demos/api7-demo + +--- + +**Chart Version**: 0.1.0 | **Maintainer**: CommandWare | **License**: Demo Project diff --git a/web/README.md b/web/README.md index 2ea5d83..b102484 100644 --- a/web/README.md +++ b/web/README.md @@ -1,53 +1,96 @@ -# Web Application with Documentation +# Web Application - FastAPI Frontend with Documentation -FastAPI web application serving a demo dashboard and comprehensive MkDocs documentation. +A modern web frontend built with FastAPI featuring an interactive dashboard, embedded MkDocs documentation, and API proxy functionality for seamless integration with the backend API service. -## Features +## πŸ“‹ Overview -- **Web Dashboard**: Simple HTML interface with metrics display -- **Documentation Site**: Complete API7 Enterprise setup guide at `/docs` -- **Health Checks**: Monitoring endpoint at `/health` +This web application serves as the frontend for the API7 Enterprise Edition demo platform, providing: -## Documentation +- **Interactive Dashboard**: Modern UI with real-time statistics +- **Embedded Documentation**: Complete MkDocs documentation site at `/docs` +- **API Proxy**: Seamless proxying of requests to the backend API +- **LLM Chat Interface**: Interactive chat with AI videogame expert +- **Health Monitoring**: Health check endpoints +- **Static Assets**: Custom CSS and JavaScript for enhanced UX -The application includes comprehensive documentation built with MkDocs Material theme, covering: +## ✨ Features -- **Architecture Overview**: Complete infrastructure and component details -- **Getting Started**: Quick setup and deployment guide -- **API7 Configuration**: Route and service configuration with examples +### Web Pages + +- **Home Page** (`/`): Dashboard with feature overview and statistics +- **Items Page** (`/items`): Browse and manage items +- **Users Page** (`/users`): View and manage users +- **LLM Chat** (`/llm`): Interactive AI chat interface +- **Documentation** (`/docs`): Full project documentation (MkDocs) + +### API Proxy Endpoints + +The web application proxies the following API endpoints: + +- `GET /api/items` β†’ Backend `/items` +- `GET /api/items/{item_id}` β†’ Backend `/items/{item_id}` +- `GET /api/users` β†’ Backend `/users` +- `GET /api/users/{user_id}` β†’ Backend `/users/{user_id}` +- `POST /api/llm/chat` β†’ Backend `/llm/chat` +- `GET /api/llm/models` β†’ Backend `/llm/models` +- `GET /api/llm/health` β†’ Backend `/llm/health` +- `GET /api/config` β†’ Returns frontend configuration + +### Documentation Site + +The embedded MkDocs documentation includes: + +- **Getting Started**: Quick setup guide +- **Architecture**: System architecture and component details - **Kubernetes Resources**: Complete resource reference -- **CI/CD Pipeline**: Gitea Actions workflow documentation +- **API7 Configuration**: Gateway setup and configuration +- **CI/CD Pipeline**: Automation and deployment workflows - **Troubleshooting**: Common issues and solutions -## Running Locally +## πŸš€ Quick Start ### Prerequisites ```bash +python >= 3.8 +pip +``` + +### Local Development + +#### Install Dependencies + +```bash +cd web pip install -r requirements.txt ``` -### Start Application +#### Run the Application ```bash +# Basic run (connects to localhost:8001 by default) python main.py + +# With custom API backend URL +export API_BASE_URL="http://localhost:8001" +python main.py + +# Or use uvicorn directly +uvicorn main:app --reload --host 0.0.0.0 --port 8000 ``` -**Access**: +#### Access the Application -- Main Page: http://localhost:8000 -- Documentation: http://localhost:8000/docs/ -- Health Check: http://localhost:8000/health +- **Home**: http://localhost:8000 +- **Items**: http://localhost:8000/items +- **Users**: http://localhost:8000/users +- **LLM Chat**: http://localhost:8000/llm +- **Documentation**: http://localhost:8000/docs +- **Health Check**: http://localhost:8000/health -### Build Documentation Manually +### Docker -```bash -mkdocs build -f docs/mkdocs.yml -d site -``` - -## Docker - -### Build Image +#### Build Image ```bash docker build -t web-app . @@ -56,23 +99,379 @@ docker build -t web-app . The Dockerfile: 1. Installs Python dependencies -2. Copies application and documentation source -3. Builds static documentation site with MkDocs -4. Serves both the app and docs +2. Copies application code, templates, static assets, and docs +3. Builds static documentation with MkDocs +4. Serves both the app and documentation -### Run Container +#### Run Container ```bash +# Basic run docker run -p 8000:8000 web-app + +# With custom API backend URL +docker run -p 8000:8000 \ + -e API_BASE_URL="http://api-backend:8001" \ + web-app + +# Run with host network (for local testing) +docker run --network host \ + -e API_BASE_URL="http://localhost:8001" \ + web-app ``` -## Kubernetes Deployment +## πŸ”§ Configuration + +### Environment Variables + +| Variable | Description | Default | Required | +| -------------- | --------------- | ----------------------- | -------- | +| `API_BASE_URL` | Backend API URL | `http://localhost:8001` | No | + +### Example Configuration + +**Development**: + +```bash +export API_BASE_URL="http://localhost:8001" +python main.py +``` + +**Docker**: + +```bash +docker run -p 8000:8000 \ + -e API_BASE_URL="http://api-service:8001" \ + web-app +``` + +**Kubernetes**: + +```yaml +env: + - name: API_BASE_URL + value: "http://nginx-service.api7ee.svc.cluster.local:8080" +``` + +## πŸ“„ Pages and Routes + +### HTML Pages + +#### `GET /` + +Home dashboard with feature cards and statistics. + +**Features**: + +- Feature cards (Items, Users, LLM, API Docs) +- Real-time statistics (item count, user count) +- Feature highlights +- Links to all sections + +#### `GET /items` + +Items management page. + +**Features**: + +- Display all items from API +- Real-time data fetching +- Interactive UI + +#### `GET /users` + +Users management page. + +**Features**: + +- Display all users from API +- User information cards +- Real-time data updates + +#### `GET /llm` + +LLM chat interface. + +**Features**: + +- Interactive chat with AI +- Markdown rendering for responses +- Token usage display +- Rate limit indicator (100 tokens/60s) +- Model selection (videogame-expert) +- Real-time status updates + +### API Proxy Routes + +#### `GET /api/items` + +Proxy to backend API items endpoint. + +**Backend**: `GET {API_BASE_URL}/items` + +#### `GET /api/items/{item_id}` + +Proxy to backend API specific item endpoint. + +**Backend**: `GET {API_BASE_URL}/items/{item_id}` + +#### `GET /api/users` + +Proxy to backend API users endpoint. + +**Backend**: `GET {API_BASE_URL}/users` + +#### `GET /api/users/{user_id}` + +Proxy to backend API specific user endpoint. + +**Backend**: `GET {API_BASE_URL}/users/{user_id}` + +#### `POST /api/llm/chat` + +Proxy to backend LLM chat endpoint. + +**Backend**: `POST {API_BASE_URL}/llm/chat` + +**Request Body**: + +```json +{ + "prompt": "What is Zelda?", + "max_tokens": 150, + "temperature": 0.7, + "model": "videogame-expert" +} +``` + +#### `GET /api/llm/models` + +Proxy to backend LLM models endpoint. + +**Backend**: `GET {API_BASE_URL}/llm/models` + +#### `GET /api/llm/health` + +Proxy to backend LLM health check. + +**Backend**: `GET {API_BASE_URL}/llm/health` + +### Health Check + +#### `GET /health` + +Web application health check. + +**Response**: + +```json +{ + "status": "healthy", + "service": "web", + "version": "1.0.0", + "api_backend": "http://localhost:8001", + "api_status": "healthy" +} +``` + +**API Status Values**: + +- `healthy`: Backend is responding +- `unhealthy`: Backend returned non-200 status +- `unreachable`: Cannot connect to backend + +### Configuration Endpoint + +#### `GET /api/config` + +Get current frontend configuration. + +**Response**: + +```json +{ + "api_base_url": "http://localhost:8001" +} +``` + +## πŸ“š Documentation + +### MkDocs Configuration + +The application includes a comprehensive documentation site built with MkDocs Material theme. + +**Configuration file**: `mkdocs.yml` + +**Theme Features**: + +- Material Design theme +- Light/Dark mode toggle +- Navigation tabs and sections +- Search functionality +- Syntax highlighting +- Code copy buttons + +### Documentation Structure + +``` +docs/ +β”œβ”€β”€ index.md # Documentation home +β”œβ”€β”€ getting-started.md # Quick start guide +β”œβ”€β”€ architecture.md # System architecture +β”œβ”€β”€ kubernetes-resources.md # K8s resources reference +β”œβ”€β”€ api7-configuration.md # API7 Gateway setup +β”œβ”€β”€ cicd-pipeline.md # CI/CD documentation +└── troubleshooting.md # Troubleshooting guide +``` + +### Building Documentation + +#### Serve Locally (Development) + +```bash +cd web +mkdocs serve + +# Access at http://localhost:8001 +``` + +#### Build Static Site + +```bash +mkdocs build -d site + +# Output directory: web/site/ +``` + +The Docker build automatically builds the documentation during image creation. + +### Updating Documentation + +1. Edit markdown files in `docs/` directory +2. Test locally with `mkdocs serve` +3. Commit changes +4. Rebuild Docker image or re-deploy + +## 🎨 Templates and Static Assets + +### Templates (Jinja2) + +Located in `templates/`: + +- **base.html**: Base template with common HTML structure +- **index.html**: Home dashboard page +- **items.html**: Items management page +- **users.html**: Users management page +- **llm.html**: LLM chat interface + +### Static Assets + +Located in `static/`: + +- **css/**: Custom stylesheets +- **js/**: JavaScript files + +### Template Variables + +Templates have access to: + +- `request`: Starlette Request object +- Context variables passed from route handlers + +## πŸ§ͺ Testing + +### Manual Testing + +```bash +# Test home page +curl http://localhost:8000/ + +# Test health check +curl http://localhost:8000/health + +# Test API proxy +curl http://localhost:8000/api/items +curl http://localhost:8000/api/users + +# Test LLM proxy +curl -X POST http://localhost:8000/api/llm/chat \ + -H "Content-Type: application/json" \ + -d '{ + "prompt": "What is Mario?", + "max_tokens": 100 + }' + +# Test configuration +curl http://localhost:8000/api/config +``` + +### Browser Testing + +1. Navigate to http://localhost:8000 +2. Check all navigation links work +3. Verify items and users load +4. Test LLM chat interface +5. Browse documentation at /docs + +## 🐳 Docker + +### Dockerfile Breakdown + +```dockerfile +FROM python:3.11-slim + +WORKDIR /app + +# Install dependencies +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# Copy application files +COPY main.py . +COPY docs/ ./docs/ +COPY static/ ./static/ +COPY templates/ ./templates/ +COPY mkdocs.yml . + +# Build documentation +RUN mkdocs build -d site + +EXPOSE 8000 + +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] +``` + +### Multi-stage Build Benefits + +- Dependencies installed during build +- Documentation pre-built as static files +- Smaller runtime container +- Faster startup time + +### Build and Push + +```bash +# Build +docker build -t git.commandware.com/demos/api7-demo/web:latest . + +# Tag +docker tag git.commandware.com/demos/api7-demo/web:latest \ + git.commandware.com/demos/api7-demo/web:v1.0.0 + +# Push +docker push git.commandware.com/demos/api7-demo/web:latest +docker push git.commandware.com/demos/api7-demo/web:v1.0.0 +``` + +## ☸️ Kubernetes Deployment + +### Basic Deployment ```yaml apiVersion: apps/v1 kind: Deployment metadata: - name: web + name: web-service namespace: api7ee spec: replicas: 2 @@ -90,14 +489,28 @@ spec: ports: - containerPort: 8000 name: http + env: + - name: API_BASE_URL + value: "http://nginx-service.api7ee.svc.cluster.local:8080" livenessProbe: httpGet: path: /health port: 8000 + initialDelaySeconds: 30 + periodSeconds: 10 readinessProbe: httpGet: path: /health port: 8000 + initialDelaySeconds: 10 + periodSeconds: 5 + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 250m + memory: 256Mi --- apiVersion: v1 kind: Service @@ -114,55 +527,259 @@ spec: app: web ``` -## Documentation Structure +### With Helm -``` -docs/ -β”œβ”€β”€ mkdocs.yml # MkDocs configuration -β”œβ”€β”€ index.md # Documentation home -β”œβ”€β”€ getting-started.md # Quick start guide -β”œβ”€β”€ architecture.md # Infrastructure architecture -β”œβ”€β”€ kubernetes-resources.md # K8s resources reference -β”œβ”€β”€ api7-configuration.md # API7 Gateway config guide -β”œβ”€β”€ cicd-pipeline.md # CI/CD documentation -└── troubleshooting.md # Troubleshooting guide +See the [Helm chart README](../helm/api7ee-demo-k8s/README.md) for full deployment options. + +```bash +helm install api7ee-demo ./helm/api7ee-demo-k8s \ + --set web.image.tag=v1.0.0 \ + --set web.replicaCount=3 \ + --namespace api7ee ``` -## Endpoints +## πŸ“¦ Dependencies -| Endpoint | Description | -| --------- | --------------------------- | -| `/` | Main web dashboard | -| `/docs/` | Documentation site (MkDocs) | -| `/health` | Health check endpoint | +### Python Requirements -## CI/CD +``` +fastapi==0.104.1 +uvicorn[standard]==0.24.0 +jinja2==3.1.3 +python-multipart==0.0.6 +httpx==0.26.0 +mkdocs==1.5.3 +mkdocs-material==9.5.3 +pymdown-extensions==10.7 +``` -Images are automatically built and pushed to Gitea registry on every push: +### Install -**Registry**: `git.commandware.com/demos/api7-demo/web:` +```bash +pip install -r requirements.txt +``` -See [CI/CD Pipeline documentation](docs/cicd-pipeline.md) for details. - -## Development - -### Update Documentation - -1. Edit markdown files in `docs/` directory -2. Test locally: - ```bash - mkdocs serve -f docs/mkdocs.yml - ``` -3. View at http://localhost:8001 -4. Rebuild with `mkdocs build` or rebuild Docker image - -### Dependencies +### Dependency Breakdown - **fastapi**: Web framework -- **uvicorn**: ASGI server +- **uvicorn**: ASGI server with WebSocket support +- **jinja2**: Template engine for HTML pages +- **python-multipart**: Form data parsing +- **httpx**: Async HTTP client for API proxying - **mkdocs**: Documentation site generator - **mkdocs-material**: Material theme for MkDocs +- **pymdown-extensions**: Additional markdown extensions + +## πŸš€ Production Deployment + +### Recommended Configuration + +```yaml +web: + replicaCount: 3 + autoscaling: + enabled: true + minReplicas: 3 + maxReplicas: 15 + targetCPUUtilizationPercentage: 80 + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 500m + memory: 512Mi + env: + - name: API_BASE_URL + value: "http://nginx-service.api7ee.svc.cluster.local:8080" +``` + +### API7 Gateway Integration + +When deployed behind API7 Gateway: + +**Routing**: + +- Priority 1: `/*` routes to web service (matches all except `/api`) +- Hosts: `api7-demo.commandware.it` + +**Plugins**: + +- `redirect`: HTTP β†’ HTTPS enforcement +- No rate limiting on web pages (only on API endpoints) + +**Service Discovery**: + +```yaml +upstream: + name: apache-upstream + nodes: + - host: apache-service.api7ee.svc.cluster.local + port: 80 + weight: 100 +``` + +## πŸ”’ Security + +### Best Practices + +1. **Non-root User**: Container runs as non-root (UID 1000) +2. **Read-only Filesystem**: Root filesystem is read-only +3. **CORS**: Configured via API7 Gateway +4. **Input Validation**: FastAPI automatic validation +5. **Proxy Security**: Validates API responses before forwarding + +### Security Headers + +Consider adding these headers via API7 Gateway: + +```yaml +plugins: + response-rewrite: + headers: + X-Frame-Options: DENY + X-Content-Type-Options: nosniff + X-XSS-Protection: "1; mode=block" +``` + +## πŸ“Š Monitoring + +### Health Checks + +The `/health` endpoint provides: + +- Web service status +- API backend connectivity +- API backend health status + +**Kubernetes Probes**: + +```yaml +livenessProbe: + httpGet: + path: /health + port: 8000 + initialDelaySeconds: 30 + periodSeconds: 10 + +readinessProbe: + httpGet: + path: /health + port: 8000 + initialDelaySeconds: 10 + periodSeconds: 5 +``` + +### Logging + +Monitor application logs: + +```bash +# Docker +docker logs -f web-app + +# Kubernetes +kubectl logs -n api7ee -l app=web --tail=100 -f + +# Specific pod +kubectl logs -n api7ee web-service-xxx-xxx -f +``` + +## πŸ› Troubleshooting + +### Common Issues + +**Issue**: Cannot connect to API backend + +```bash +# Check API_BASE_URL +curl http://localhost:8000/api/config + +# Check backend health +curl http://localhost:8000/health + +# Response shows api_status: "unreachable" +# Solution: Verify API_BASE_URL is correct and backend is running +``` + +**Issue**: Documentation not showing + +```bash +# Rebuild documentation +mkdocs build -d site + +# Check if site directory exists +ls -la site/ + +# Rebuild Docker image +docker build -t web-app . +``` + +**Issue**: Static assets not loading + +```bash +# Check static directory exists +ls -la static/ + +# Verify static mount in Docker +docker run -it web-app ls -la /app/static + +# Check browser console for 404 errors +``` + +**Issue**: Templates not rendering + +```bash +# Check templates directory +ls -la templates/ + +# Verify template files exist +ls templates/*.html + +# Check application logs for Jinja2 errors +docker logs web-app +``` + +### Debug Mode + +Run with debug logging: + +```python +# In main.py, add: +import logging +logging.basicConfig(level=logging.DEBUG) + +# Or with uvicorn: +uvicorn main:app --log-level debug +``` + +## πŸ“š Resources + +### Documentation + +- **FastAPI**: https://fastapi.tiangolo.com/ +- **MkDocs**: https://www.mkdocs.org/ +- **MkDocs Material**: https://squidfunk.github.io/mkdocs-material/ +- **Jinja2**: https://jinja.palletsprojects.com/ +- **HTTPX**: https://www.python-httpx.org/ + +### Related + +- [Main README](../README.md) +- [API Application README](../api/README.md) +- [Helm Chart README](../helm/api7ee-demo-k8s/README.md) + +## 🎯 Future Enhancements + +Potential improvements: + +- [ ] User authentication +- [ ] WebSocket support for real-time updates +- [ ] Progressive Web App (PWA) features +- [ ] Advanced caching strategies +- [ ] Internationalization (i18n) +- [ ] Enhanced error pages --- -_FastAPI web application with integrated MkDocs documentation for API7 Enterprise demo._ +**Version**: 1.0.0 | **Port**: 8000 | **Framework**: FastAPI 0.104.1 | **Theme**: Material for MkDocs 9.5.3