Add TKE Kubernetes deployment config: Namespace, ConfigMap, Secret, Deployment, Service, Ingress. Uses nginx ingress controller on Tencent TKE (Singapore cluster). Use when asked to "add K8s config", "deploy to TKE", "add deployment", or "setup Kubernetes".
Per-project Namespace isolation on Tencent TKE with nginx ingress. Based on production config from
ufcenter.xyz.
Check before proceeding. Stop and prompt user if any fail:
echo $SHELL
| Command | Check | If missing |
|---|---|---|
kubectl | command -v kubectl | brew install kubectl |
| Cluster connected | kubectl cluster-info | Configure ~/.kube/config |
| Correct context | kubectl config current-context | Show context, confirm with user |
kubectl config current-context
kubectl get namespaces --no-headers -o custom-columns=NAME:.metadata.name
kubectl get svc -n ingress-nginx ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
cat package.json | grep '"name"'
| Parameter | Required | Auto-detect method | Example |
|---|---|---|---|
APP_NAME | Yes | package.json name field | my-app |
TCR_NAMESPACE | Yes | .env files or default qruiq | qruiq |
DOMAIN | No | k8s/ingress.yaml host field; leave __DOMAIN__ if not found | my-app.qruiq.app |
Execute all steps directly. Do not list as TODOs. Pause at step 3 for user confirmation.
mkdir -p k8s/scripts
cp ~/.qruiq/skills/skills/qruiq-tke-deployment/template/k8s/*.yaml k8s/
cp ~/.qruiq/skills/skills/qruiq-tke-deployment/template/k8s/scripts/init-namespace.sh k8s/scripts/
chmod +x k8s/scripts/init-namespace.sh
sed -i '' "s/__APP_NAME__/<APP_NAME>/g" k8s/*.yaml
sed -i '' "s/__TCR_NAMESPACE__/<TCR_NAMESPACE>/g" k8s/*.yaml
sed -i '' "s/__IMAGE_NAME__/<APP_NAME>/g" k8s/*.yaml
sed -i '' "s/__DOMAIN__/<DOMAIN>/g" k8s/*.yaml
Instruct user to prepare .env.dev (must contain DATABASE_URL, NEXTAUTH_SECRET, NEXTAUTH_URL, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET) and TCR_USERNAME/TCR_PASSWORD, then run:
export TCR_USERNAME=<tcr-username>
export TCR_PASSWORD=<tcr-password>
./k8s/scripts/init-namespace.sh <APP_NAME> dev
Wait for user confirmation before continuing.
Execute all verification — do not leave for user to check.
4a. Wait for pods
kubectl rollout status deployment/<APP_NAME>-web -n <APP_NAME>-dev --timeout=5m
On failure, diagnose:
kubectl get pods -n <APP_NAME>-dev
kubectl describe pod -n <APP_NAME>-dev -l app=<APP_NAME>,component=web
kubectl logs -n <APP_NAME>-dev -l app=<APP_NAME>,component=web --tail=50
4b. Health check (in-cluster)
POD=$(kubectl get pod -n <APP_NAME>-dev -l app=<APP_NAME>,component=web -o jsonpath='{.items[0].metadata.name}')
kubectl exec -n <APP_NAME>-dev $POD -- wget -q -O - http://localhost:3000/api/health
4c. External access
If DOMAIN configured:
curl -sf https://<DOMAIN>/api/health
If not, use LB IP + Host header:
LB_IP=$(kubectl get svc -n ingress-nginx ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -sf -H "Host: <APP_NAME>.qruiq.app" http://$LB_IP/api/health
4d. Report results
Deployment: SUCCESS / FAILED
Pod status: <Running / failure reason>
Health check: <passed / failure reason>
External access: <URL / pending items>
User action required:
- <DNS config, domain binding, etc.>
Template files use __UPPERCASE__ placeholders:
| Placeholder | Description |
|---|---|
__APP_NAME__ | App name, also used as namespace prefix |
__TCR_NAMESPACE__ | TCR image namespace (default: qruiq) |
__IMAGE_NAME__ | Docker image name |
__DOMAIN__ | External domain |
__INGRESS_IP__ | TKE Ingress LB IP |
<project-name>-dev # Dev/test environment
<project-name>-prod # Production (optional)
k8s/namespace.yamlkubectl create secret docker-registry tcr-secret ...k8s/configmap.yamlkubectl create secret generic <app>-secrets --from-env-file=.env.devk8s/deployment.yaml (health probes on /api/health:3000)k8s/service.yaml (ClusterIP, port 80 → 3000)k8s/ingress.yaml (nginx ingress class)| Item | Value |
|---|---|
| Cluster ID | cls-rjk5qyka |
| nginx Ingress LB IP | 43.173.190.227 — use this for DNS |
| Other CLB IP | 150.109.21.157 — not nginx ingress, do not use |
| TCR (Singapore) | sgccr.ccs.tencentyun.com |
| TCR Namespace | qruiq |
| Domain for new projects | *.qruiq.app (NS on Cloudflare) |
qruiq.app works; ufcenter.xyz (NS on afternic) does not.kubectl get ingress ADDRESS field may be inaccurate — always check ingress-nginx-controller Service EXTERNAL-IP.ReadWriteOnce. For multi-pod shared storage, use CFS (NFS).kubectl get pods -n <namespace>
kubectl logs -f deployment/<project>-web -n <namespace>
kubectl rollout restart deployment/<project>-web -n <namespace>
kubectl set image deployment/<project>-web web=<image>:<version> -n <namespace>