- Added Helm chart build job to main CI/CD workflow - Created dedicated helm-release workflow for version tags - Integrated Helm packaging with Gitea package registry - Added automatic chart versioning and publishing - Updated README with Helm deployment instructions - Configured chart linting and validation steps - Added release automation for tagged versions
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 webpageGET /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 UIGET /items- List itemsPOST /items- Create itemGET /users- List usersGET /health- Health check
Port: 8001 (internally 8000)
🚀 Quick Start
Local Development
Web Application:
cd web
pip install -r requirements.txt
python main.py
# Access at http://localhost:8000
API Application:
cd api
pip install -r requirements.txt
python main.py
# Swagger at http://localhost:8000/docs
Docker
Build and run Web:
docker build -t web-app ./web
docker run -p 8000:8000 web-app
Build and run API:
docker build -t api-app ./api
docker run -p 8001:8000 api-app
🐳 CI/CD with Gitea
Automated Pipeline
The .gitea/workflows/build.yml pipeline automatically:
- Builds Docker images for both applications
- Pushes to Gitea container registry
- Tags images with branch name
- Packages and publishes Helm chart
- Implements layer caching for faster builds
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:<branch-name>git.commandware.com/demos/api7-demo/api:<branch-name>
Helm Repository:
https://git.commandware.com/api/packages/$OWNER/helm
Setup
-
Create
GITEA_TOKENsecret:- Repository Settings → Secrets → Add Secret
- Name:
GITEA_TOKEN - Generate token at: User Settings → Applications → Generate Token
- Required scope:
write:package
-
Push to trigger build:
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
# Add the Gitea Helm repository
helm repo add api7ee https://git.commandware.com/api/packages/$OWNER/helm
helm repo update
Install the Chart
# Install with default values
helm install my-api7ee api7ee/api7ee --namespace api7ee --create-namespace
# Install with custom values
helm install my-api7ee api7ee/api7ee -f custom-values.yaml --namespace api7ee
# Install with specific image tags
helm install my-api7ee api7ee/api7ee \
--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
# Upgrade the release
helm upgrade my-api7ee api7ee/api7ee --namespace api7ee
# Uninstall
helm uninstall my-api7ee --namespace api7ee
Manual Deployment (Alternative)
k8s-deployments.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
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:
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-----
<YOUR_CERTIFICATE>
-----END CERTIFICATE-----
key: |
-----BEGIN PRIVATE KEY-----
<YOUR_KEY>
-----END PRIVATE KEY-----
Sync Configuration
adc sync -f api7-routes.yaml \
--backend api7ee \
--server https://api7-dashboard.yourdomain.com \
--token <YOUR_API7_TOKEN> \
--gateway-group default \
--tls-skip-verify
Publish Routes
Routes must be published via API7 Dashboard to become active:
- Navigate to Services → Select service
- Go to Routes tab
- Click "Publish" for each route
- Select gateway group: "default"
- Confirm
🧪 Testing
Test Endpoints
# 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
# 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/apiprefix)demo.yourdomain.com/*→ Web Service (default priority)
🔧 API7 Enterprise Setup Guide
Certificate Management
Using cert-manager with Cloudflare:
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:
kubectl create secret generic cloudflare-api-token-secret \
-n cert-manager \
--from-literal=api-token=YOUR_TOKEN
Kubernetes Service Discovery
Configure in API7 Dashboard:
- Settings → Service Registry → Add Service Registry
- Select: Kubernetes
- 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:
kubectl create clusterrolebinding api7-gateway-discovery \
--clusterrole=view \
--serviceaccount=<API7_NAMESPACE>:default
Ingress Configuration
Example ingress for API7 Gateway:
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
namefield
Certificate Issues
Problem: Certificate not trusted
Solution:
# Check certificate status
kubectl get certificate -n api7ee
kubectl describe certificate -n api7ee <cert-name>
# 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:
# Create registry secret
kubectl create secret docker-registry gitea-registry \
--docker-server=git.commandware.com \
--docker-username=<USERNAME> \
--docker-password=<TOKEN> \
-n api7ee
# Add to 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