first commit
Some checks failed
Build and Push Docker Images / build-web (push) Failing after 1m3s
Build and Push Docker Images / build-api (push) Failing after 1m1s

This commit is contained in:
d.viti
2025-10-03 01:20:15 +02:00
commit a2eef9efde
20 changed files with 4272 additions and 0 deletions

492
README.md Normal file
View File

@@ -0,0 +1,492 @@
# 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 `.gitea/workflows/build.yml` pipeline automatically:
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:**
- Any branch push
- Manual dispatch
**Registry:** `git.commandware.com/demos/api7-demo`
**Images:**
- `git.commandware.com/demos/api7-demo/web:<branch-name>`
- `git.commandware.com/demos/api7-demo/api:<branch-name>`
### 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+)
- API7 Enterprise Gateway installed
- Namespace: `api7ee`
### Deployment Manifest
**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-----
<YOUR_CERTIFICATE>
-----END CERTIFICATE-----
key: |
-----BEGIN PRIVATE KEY-----
<YOUR_KEY>
-----END PRIVATE KEY-----
```
### Sync Configuration
```bash
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:
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=<API7_NAMESPACE>: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 <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:**
```bash
# 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