# API7 Demo - FastAPI Applications Demo project showcasing two FastAPI applications deployed on Kubernetes through API7 Enterprise Gateway with automated CI/CD using Gitea. ## πŸ“ 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 β”œβ”€β”€ .gitea/ β”‚ └── workflows/ β”‚ └── build.yml # CI/CD pipeline └── README.md ``` ## 🌐 Applications ### 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 ### API Application (`api/`) REST API with full documentation: - CRUD operations for Items and Users - Automatic Swagger/OpenAPI docs - Data validation with Pydantic **Key Endpoints:** - `GET /docs` - Swagger UI - `GET /items` - List items - `POST /items` - Create item - `GET /users` - List users - `GET /health` - Health check **Port:** 8001 (internally 8000) ## πŸš€ Quick Start ### Local Development **Web Application:** ```bash cd web pip install -r requirements.txt python main.py # Access at http://localhost:8000 ``` **API Application:** ```bash cd api pip install -r requirements.txt python main.py # Swagger at http://localhost:8000/docs ``` ### Docker **Build and run Web:** ```bash 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 ``` ## 🐳 CI/CD with Gitea ### Automated Pipeline The CI/CD workflows automatically: **`.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 **`.gitea/workflows/helm-release.yml`**: 1. Packages Helm charts on every main branch push 2. Creates development versions for main branch builds 3. Creates release versions for tags (v*.*.*) 4. Publishes charts to Gitea Helm registry 5. Creates GitHub releases for tagged versions **Triggers:** - Any branch push (Docker images) - Push to main branch (Helm chart) - Version tags (Helm releases) - Manual dispatch **Registry:** `git.commandware.com/demos/api7-demo` **Docker 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` ### Setup 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` 2. **Push to trigger build:** ```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. #### Add Helm Repository ```bash # Add the Gitea Helm repository helm repo add api7ee https://git.commandware.com/api/packages/$OWNER/helm helm repo update ``` #### Install the Chart ```bash # Install with default values helm install my-api7ee 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 # 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 \ --namespace api7ee ``` #### Configuration Options Key Helm values: | 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` | #### Upgrade/Uninstall ```bash # Upgrade the release helm upgrade my-api7ee api7ee/api7ee-demo-k8s --namespace api7ee # Uninstall helm uninstall my-api7ee --namespace 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 ```bash kubectl apply -f k8s-deployments.yaml kubectl rollout status deployment/web -n api7ee kubectl rollout status deployment/api -n api7ee ``` ## πŸ”Œ API7 Gateway Configuration ### Route Configuration (ADC) **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----- ``` ### Sync Configuration ```bash adc sync -f api7-routes.yaml \ --backend api7ee \ --server https://api7-dashboard.yourdomain.com \ --token \ --gateway-group default \ --tls-skip-verify ``` ### Publish Routes 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:** ```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 ``` **Create Cloudflare secret:** ```bash kubectl create secret generic cloudflare-api-token-secret \ -n cert-manager \ --from-literal=api-token=YOUR_TOKEN ``` ### Kubernetes Service Discovery **Configure in API7 Dashboard:** 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) ``` **Verify RBAC permissions:** ```bash kubectl create clusterrolebinding api7-gateway-discovery \ --clusterrole=view \ --serviceaccount=:default ``` ### Ingress Configuration **Example ingress for API7 Gateway:** ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: api7-gateway-ingress namespace: api7ee spec: ingressClassName: nginx 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 ``` **Note:** Ingress backend points to API7 Gateway service, not application services. ## πŸ› οΈ Troubleshooting ### Routes Return 404 **Problem:** Routes synced but returning 404 **Solution:** Routes not published. Publish via API7 Dashboard. ### Service Discovery Not Working **Problem:** `service registry not found` error **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 ``` ### Container Images Not Found **Problem:** ImagePullBackOff in Kubernetes **Solution:** ```bash # Create registry secret kubectl create secret docker-registry gitea-registry \ --docker-server=git.commandware.com \ --docker-username= \ --docker-password= \ -n api7ee # Add to deployment spec: template: spec: imagePullSecrets: - name: gitea-registry ``` ## πŸ“š 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 ## πŸ” Best Practices ### 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 ### Performance - βœ… Enable service discovery for automatic scaling - βœ… Configure appropriate resource limits - βœ… Use Docker layer caching in CI/CD - βœ… Implement health checks and readiness probes ### Monitoring - βœ… Monitor gateway metrics in API7 Dashboard - βœ… Track API usage and performance - βœ… Set up alerts for certificate expiration - βœ… Review application logs regularly ## πŸ“ License Demo project for API7 Enterprise Gateway evaluation. --- **Repository:** https://git.commandware.com/demos/api7-demo.git