diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index 8d046414..9f9d4615 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -255,6 +255,7 @@ jobs: kubectl apply -f deployments/staging/kubernetes/redis.yaml kubectl apply -f deployments/staging/kubernetes/rabbitmq.yaml kubectl apply -f deployments/staging/kubernetes/minio.yaml + kubectl apply -f deployments/staging/kubernetes/traefik.yaml kubectl apply -f deployments/staging/kubernetes/ingress.yaml kubectl apply -f deployments/staging/kubernetes/network-policy.yaml fi diff --git a/deployments/staging/kubernetes/ingress.yaml b/deployments/staging/kubernetes/ingress.yaml index cc20e2d2..5e41eab0 100644 --- a/deployments/staging/kubernetes/ingress.yaml +++ b/deployments/staging/kubernetes/ingress.yaml @@ -1,11 +1,13 @@ -# EN: Traefik Ingress for GoodGo Staging - API Gateway routing -# VI: Traefik Ingress cho GoodGo Staging - Dinh tuyen API Gateway +# EN: Nginx Ingress → Traefik proxy for GoodGo POS System +# VI: Nginx Ingress → Traefik proxy cho he thong GoodGo POS # -# Routes match infra/traefik/dynamic/routes.yml for consistency -# Host: api.techbi.org (API), platform.techbi.org (POS Frontend) +# Architecture: +# Internet → Nginx Ingress (TLS, port 443) → Traefik (routing, port 80) → Services +# Nginx handles: TLS termination, cert-manager, external access +# Traefik handles: path routing, middleware (rate-limit, retry, compress, headers) # ============================================================================= -# API Ingress - Backend services +# API Ingress — proxies all API traffic to Traefik # ============================================================================= apiVersion: networking.k8s.io/v1 kind: Ingress @@ -16,11 +18,16 @@ metadata: environment: staging platform: goodgo annotations: - # EN: Nginx Ingress class - # VI: Ingress class cua Nginx nginx.ingress.kubernetes.io/proxy-body-size: "50m" nginx.ingress.kubernetes.io/proxy-read-timeout: "60" nginx.ingress.kubernetes.io/proxy-send-timeout: "60" + # EN: WebSocket support for SignalR hubs + # VI: Ho tro WebSocket cho SignalR hubs + nginx.ingress.kubernetes.io/proxy-http-version: "1.1" + nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri" + # EN: Pass original Host header to Traefik for routing decisions + # VI: Truyen Host header goc cho Traefik de dinh tuyen + nginx.ingress.kubernetes.io/upstream-vhost: "api.techbi.org" # EN: cert-manager TLS (Let's Encrypt production) # VI: TLS bang cert-manager (Let's Encrypt production) cert-manager.io/cluster-issuer: letsencrypt-prod @@ -34,514 +41,17 @@ spec: - host: api.techbi.org http: paths: - # ===== IAM Service ===== - - path: /api/v1/auth + - path: / pathType: Prefix backend: service: - name: iam-service + name: traefik port: - number: 8080 - - path: /api/v1/users - pathType: Prefix - backend: - service: - name: iam-service - port: - number: 8080 - - path: /api/v1/identity - pathType: Prefix - backend: - service: - name: iam-service - port: - number: 8080 - - path: /api/v1/access - pathType: Prefix - backend: - service: - name: iam-service - port: - number: 8080 - - path: /api/v1/governance - pathType: Prefix - backend: - service: - name: iam-service - port: - number: 8080 - - path: /api/v1/rbac - pathType: Prefix - backend: - service: - name: iam-service - port: - number: 8080 - - path: /api/v1/mfa - pathType: Prefix - backend: - service: - name: iam-service - port: - number: 8080 - - path: /api/v1/sessions - pathType: Prefix - backend: - service: - name: iam-service - port: - number: 8080 - # EN: IdentityServer OIDC endpoints - # VI: IdentityServer OIDC endpoints - - path: /connect - pathType: Prefix - backend: - service: - name: iam-service - port: - number: 8080 - - path: /.well-known - pathType: Prefix - backend: - service: - name: iam-service - port: - number: 8080 - - # ===== Merchant Service ===== - - path: /api/v1/merchants - pathType: Prefix - backend: - service: - name: merchant-service - port: - number: 8080 - - path: /api/v1/shops - pathType: Prefix - backend: - service: - name: merchant-service - port: - number: 8080 - - path: /api/v1/subscriptions - pathType: Prefix - backend: - service: - name: merchant-service - port: - number: 8080 - - # ===== Order Service ===== - - path: /api/v1/orders - pathType: Prefix - backend: - service: - name: order-service - port: - number: 8080 - # EN: POS/KDS SignalR Hub (WebSocket) - # VI: POS/KDS SignalR Hub (WebSocket) - - path: /hubs/pos - pathType: Prefix - backend: - service: - name: order-service - port: - number: 8080 - - # ===== FnB Engine ===== - - path: /api/v1/kitchen - pathType: Prefix - backend: - service: - name: fnb-engine - port: - number: 8080 - - path: /api/v1/fnb - pathType: Prefix - backend: - service: - name: fnb-engine - port: - number: 8080 - - path: /api/v1/tables - pathType: Prefix - backend: - service: - name: fnb-engine - port: - number: 8080 - - path: /api/v1/sessions - pathType: Prefix - backend: - service: - name: fnb-engine - port: - number: 8080 - # EN: Kitchen Display SignalR Hub - # VI: SignalR Hub Man hinh bep - - path: /hubs/kitchen - pathType: Prefix - backend: - service: - name: fnb-engine - port: - number: 8080 - - # ===== Inventory Service ===== - - path: /api/v1/inventory - pathType: Prefix - backend: - service: - name: inventory-service - port: - number: 8080 - - path: /api/v1/stock - pathType: Prefix - backend: - service: - name: inventory-service - port: - number: 8080 - - # ===== Wallet Service ===== - - path: /api/v1/wallets - pathType: Prefix - backend: - service: - name: wallet-service - port: - number: 8080 - - path: /api/v1/points - pathType: Prefix - backend: - service: - name: wallet-service - port: - number: 8080 - - path: /api/v1/payments - pathType: Prefix - backend: - service: - name: wallet-service - port: - number: 8080 - - # ===== Catalog Service ===== - - path: /api/v1/products - pathType: Prefix - backend: - service: - name: catalog-service - port: - number: 8080 - - path: /api/v1/categories - pathType: Prefix - backend: - service: - name: catalog-service - port: - number: 8080 - - # ===== Storage Service ===== - - path: /api/v1/files - pathType: Prefix - backend: - service: - name: storage-service - port: - number: 8080 - - path: /api/v1/quota - pathType: Prefix - backend: - service: - name: storage-service - port: - number: 8080 - - path: /api/v1/uploads - pathType: Prefix - backend: - service: - name: storage-service - port: - number: 8080 - - # ===== Booking Service ===== - - path: /api/v1/bookings - pathType: Prefix - backend: - service: - name: booking-service - port: - number: 8080 - - path: /api/v1/reservations - pathType: Prefix - backend: - service: - name: booking-service - port: - number: 8080 - - path: /api/v1/appointments - pathType: Prefix - backend: - service: - name: booking-service - port: - number: 8080 - - path: /api/v1/therapists - pathType: Prefix - backend: - service: - name: booking-service - port: - number: 8080 - - # ===== Chat Service ===== - - path: /api/v1/chats - pathType: Prefix - backend: - service: - name: chat-service - port: - number: 8080 - - path: /api/v1/messages - pathType: Prefix - backend: - service: - name: chat-service - port: - number: 8080 - - path: /api/v1/conversations - pathType: Prefix - backend: - service: - name: chat-service - port: - number: 8080 - # EN: Chat SignalR Hub (WebSocket) - # VI: Chat SignalR Hub (WebSocket) - - path: /hubs/chat - pathType: Prefix - backend: - service: - name: chat-service - port: - number: 8080 - - # ===== Social Service ===== - - path: /api/v1/social - pathType: Prefix - backend: - service: - name: social-service - port: - number: 8080 - - path: /api/v1/relationships - pathType: Prefix - backend: - service: - name: social-service - port: - number: 8080 - - # ===== Promotion Service ===== - - path: /api/v1/promotions - pathType: Prefix - backend: - service: - name: promotion-service - port: - number: 8080 - - path: /api/v1/vouchers - pathType: Prefix - backend: - service: - name: promotion-service - port: - number: 8080 - - # ===== Membership Service ===== - - path: /api/v1/members - pathType: Prefix - backend: - service: - name: membership-service - port: - number: 8080 - - path: /api/v1/levels - pathType: Prefix - backend: - service: - name: membership-service - port: - number: 8080 - - # ===== Mining Service ===== - - path: /api/v1/mining - pathType: Prefix - backend: - service: - name: mining-service - port: - number: 8080 - - path: /api/v1/circles - pathType: Prefix - backend: - service: - name: mining-service - port: - number: 8080 - - path: /api/v1/referrals - pathType: Prefix - backend: - service: - name: mining-service - port: - number: 8080 - - # ===== Mission Service ===== - - path: /api/v1/missions - pathType: Prefix - backend: - service: - name: mission-service - port: - number: 8080 - - path: /api/v1/checkins - pathType: Prefix - backend: - service: - name: mission-service - port: - number: 8080 - - # ===== Ads Manager Service ===== - - path: /api/v1/ads - pathType: Prefix - backend: - service: - name: ads-manager-service - port: - number: 8080 - - path: /api/v1/campaigns - pathType: Prefix - backend: - service: - name: ads-manager-service - port: - number: 8080 - - path: /api/v1/adsets - pathType: Prefix - backend: - service: - name: ads-manager-service - port: - number: 8080 - - path: /api/v1/audiences - pathType: Prefix - backend: - service: - name: ads-manager-service - port: - number: 8080 - - # ===== Ads Serving Service ===== - - path: /api/v1/ads-serving - pathType: Prefix - backend: - service: - name: ads-serving-service - port: - number: 8080 - - # ===== Ads Billing Service ===== - - path: /api/v1/ads-billing - pathType: Prefix - backend: - service: - name: ads-billing-service - port: - number: 8080 - - path: /api/v1/ad-invoices - pathType: Prefix - backend: - service: - name: ads-billing-service - port: - number: 8080 - - # ===== Ads Tracking Service ===== - - path: /api/v1/ad-events - pathType: Prefix - backend: - service: - name: ads-tracking-service - port: - number: 8080 - - path: /api/v1/pixels - pathType: Prefix - backend: - service: - name: ads-tracking-service - port: - number: 8080 - - path: /api/v1/conversions - pathType: Prefix - backend: - service: - name: ads-tracking-service - port: - number: 8080 - - # ===== Ads Analytics Service ===== - - path: /api/v1/ad-analytics - pathType: Prefix - backend: - service: - name: ads-analytics-service - port: - number: 8080 - - path: /api/v1/ad-reports - pathType: Prefix - backend: - service: - name: ads-analytics-service - port: - number: 8080 - - # ===== Marketing Services ===== - - path: /api/v1/mkt/facebook - pathType: Prefix - backend: - service: - name: mkt-facebook-service - port: - number: 8080 - - path: /api/v1/mkt/whatsapp - pathType: Prefix - backend: - service: - name: mkt-whatsapp-service - port: - number: 8080 - - path: /api/v1/mkt/x - pathType: Prefix - backend: - service: - name: mkt-x-service - port: - number: 8080 - - path: /api/v1/mkt/zalo - pathType: Prefix - backend: - service: - name: mkt-zalo-service - port: - number: 8080 + number: 80 --- # ============================================================================= -# POS Frontend Ingress +# POS Frontend Ingress — proxies to Traefik # ============================================================================= apiVersion: networking.k8s.io/v1 kind: Ingress @@ -553,6 +63,7 @@ metadata: platform: goodgo annotations: nginx.ingress.kubernetes.io/proxy-body-size: "50m" + nginx.ingress.kubernetes.io/upstream-vhost: "platform.techbi.org" cert-manager.io/cluster-issuer: letsencrypt-prod spec: ingressClassName: nginx @@ -568,6 +79,6 @@ spec: pathType: Prefix backend: service: - name: pos-web + name: traefik port: - number: 8080 + number: 80 diff --git a/deployments/staging/kubernetes/network-policy.yaml b/deployments/staging/kubernetes/network-policy.yaml index 380a3409..c46b0f81 100644 --- a/deployments/staging/kubernetes/network-policy.yaml +++ b/deployments/staging/kubernetes/network-policy.yaml @@ -54,7 +54,8 @@ spec: --- # ============================================================================= -# Allow Nginx Ingress Controller → microservices (port 8080) +# Allow Nginx Ingress + Traefik → microservices (port 8080) +# Nginx handles external TLS, Traefik handles internal routing # ============================================================================= apiVersion: networking.k8s.io/v1 kind: NetworkPolicy @@ -104,10 +105,125 @@ spec: kubernetes.io/metadata.name: kube-system - namespaceSelector: matchLabels: - kubernetes.io/metadata.name: traefik + kubernetes.io/metadata.name: ingress-nginx + # EN: Allow Traefik pod (same namespace) to reach services + # VI: Cho phep Traefik pod (cung namespace) truy cap services + - podSelector: + matchLabels: + app: traefik + ports: + - port: 8080 + protocol: TCP + +--- +# ============================================================================= +# Allow Nginx Ingress → Traefik (port 80) +# ============================================================================= +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-nginx-to-traefik + namespace: staging + labels: + environment: staging + platform: goodgo +spec: + podSelector: + matchLabels: + app: traefik + policyTypes: + - Ingress + ingress: + - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: ingress-nginx + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + # EN: Nginx on hostNetwork appears as node IP, need ipBlock to allow + # VI: Nginx tren hostNetwork xuat hien la node IP, can ipBlock de cho phep + - ipBlock: + cidr: 0.0.0.0/0 + ports: + - port: 80 + protocol: TCP + +--- +# ============================================================================= +# Allow Traefik DNS resolution (kube-dns) +# ============================================================================= +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-traefik-dns-egress + namespace: staging + labels: + environment: staging + platform: goodgo +spec: + podSelector: + matchLabels: + app: traefik + policyTypes: + - Egress + egress: + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + +--- +# ============================================================================= +# Allow Traefik → microservices (egress port 8080) +# ============================================================================= +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-traefik-to-services-egress + namespace: staging + labels: + environment: staging + platform: goodgo +spec: + podSelector: + matchLabels: + app: traefik + policyTypes: + - Egress + egress: + - to: + - podSelector: + matchExpressions: + - key: app + operator: In + values: + - iam-service + - merchant-service + - order-service + - fnb-engine + - inventory-service + - wallet-service + - catalog-service + - storage-service + - booking-service + - chat-service + - social-service + - promotion-service + - membership-service + - mining-service + - mission-service + - ads-manager-service + - ads-serving-service + - ads-billing-service + - ads-tracking-service + - ads-analytics-service + - mkt-facebook-service + - mkt-whatsapp-service + - mkt-x-service + - mkt-zalo-service + - pos-web ports: - port: 8080 protocol: TCP diff --git a/deployments/staging/kubernetes/traefik.yaml b/deployments/staging/kubernetes/traefik.yaml new file mode 100644 index 00000000..a75cf07b --- /dev/null +++ b/deployments/staging/kubernetes/traefik.yaml @@ -0,0 +1,671 @@ +# EN: Traefik v3 - Internal API Gateway for GoodGo POS System +# VI: Traefik v3 - API Gateway noi bo cho he thong GoodGo POS +# +# Architecture: +# Internet → Nginx Ingress (TLS termination, port 443) +# → Traefik (internal routing, middleware, port 80) +# → Backend microservices (port 8080) +# +# Benefits: +# - Rate limiting, circuit breaker, retry middleware +# - Consistent with local dev (Docker Compose + Traefik v3) +# - Nginx handles TLS + external, Traefik handles internal routing + +--- +# ============================================================================= +# Traefik Static Configuration (ConfigMap) +# ============================================================================= +apiVersion: v1 +kind: ConfigMap +metadata: + name: traefik-config + namespace: staging + labels: + app: traefik + environment: staging + platform: goodgo +data: + traefik.yml: | + api: + dashboard: false + insecure: false + + entryPoints: + web: + address: ":80" + + providers: + file: + filename: /etc/traefik/dynamic/routes.yml + watch: true + + log: + level: INFO + + accessLog: + format: json + + metrics: + prometheus: + entryPoint: web + + ping: + entryPoint: web + + routes.yml: | + http: + # ============================================= + # Middlewares + # ============================================= + middlewares: + rate-limit: + rateLimit: + average: 100 + burst: 200 + period: 1s + + retry: + retry: + attempts: 3 + initialInterval: 100ms + + compress: + compress: {} + + secure-headers: + headers: + frameDeny: true + contentTypeNosniff: true + browserXssFilter: true + referrerPolicy: "strict-origin-when-cross-origin" + customResponseHeaders: + X-Powered-By: "" + Server: "" + + api-chain: + chain: + middlewares: + - rate-limit + - retry + - compress + - secure-headers + + websocket-headers: + headers: + customRequestHeaders: + Connection: "Upgrade" + Upgrade: "websocket" + + # ============================================= + # Routers — api.techbi.org + # ============================================= + routers: + # --- IAM Service --- + iam-auth: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/auth`)" + entryPoints: [web] + middlewares: [api-chain] + service: iam-service + iam-users: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/users`)" + entryPoints: [web] + middlewares: [api-chain] + service: iam-service + iam-identity: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/identity`)" + entryPoints: [web] + middlewares: [api-chain] + service: iam-service + iam-access: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/access`)" + entryPoints: [web] + middlewares: [api-chain] + service: iam-service + iam-governance: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/governance`)" + entryPoints: [web] + middlewares: [api-chain] + service: iam-service + iam-rbac: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/rbac`)" + entryPoints: [web] + middlewares: [api-chain] + service: iam-service + iam-mfa: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/mfa`)" + entryPoints: [web] + middlewares: [api-chain] + service: iam-service + iam-sessions: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/sessions`)" + entryPoints: [web] + middlewares: [api-chain] + service: iam-service + iam-oidc-connect: + rule: "Host(`api.techbi.org`) && PathPrefix(`/connect`)" + entryPoints: [web] + middlewares: [api-chain] + service: iam-service + iam-oidc-wellknown: + rule: "Host(`api.techbi.org`) && PathPrefix(`/.well-known`)" + entryPoints: [web] + middlewares: [api-chain] + service: iam-service + + # --- Merchant Service --- + merchant-merchants: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/merchants`)" + entryPoints: [web] + middlewares: [api-chain] + service: merchant-service + merchant-shops: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/shops`)" + entryPoints: [web] + middlewares: [api-chain] + service: merchant-service + merchant-subscriptions: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/subscriptions`)" + entryPoints: [web] + middlewares: [api-chain] + service: merchant-service + + # --- Order Service --- + order-orders: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/orders`)" + entryPoints: [web] + middlewares: [api-chain] + service: order-service + order-hub: + rule: "Host(`api.techbi.org`) && PathPrefix(`/hubs/pos`)" + entryPoints: [web] + middlewares: [websocket-headers] + service: order-service + + # --- FnB Engine --- + fnb-kitchen: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/kitchen`)" + entryPoints: [web] + middlewares: [api-chain] + service: fnb-engine + fnb-fnb: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/fnb`)" + entryPoints: [web] + middlewares: [api-chain] + service: fnb-engine + fnb-tables: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/tables`)" + entryPoints: [web] + middlewares: [api-chain] + service: fnb-engine + fnb-hub: + rule: "Host(`api.techbi.org`) && PathPrefix(`/hubs/kitchen`)" + entryPoints: [web] + middlewares: [websocket-headers] + service: fnb-engine + + # --- Catalog Service --- + catalog-products: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/products`)" + entryPoints: [web] + middlewares: [api-chain] + service: catalog-service + catalog-categories: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/categories`)" + entryPoints: [web] + middlewares: [api-chain] + service: catalog-service + + # --- Inventory Service --- + inventory: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/inventory`)" + entryPoints: [web] + middlewares: [api-chain] + service: inventory-service + inventory-stock: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/stock`)" + entryPoints: [web] + middlewares: [api-chain] + service: inventory-service + + # --- Wallet Service --- + wallet-wallets: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/wallets`)" + entryPoints: [web] + middlewares: [api-chain] + service: wallet-service + wallet-points: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/points`)" + entryPoints: [web] + middlewares: [api-chain] + service: wallet-service + wallet-payments: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/payments`)" + entryPoints: [web] + middlewares: [api-chain] + service: wallet-service + + # --- Storage Service --- + storage-files: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/files`)" + entryPoints: [web] + middlewares: [api-chain] + service: storage-service + storage-quota: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/quota`)" + entryPoints: [web] + middlewares: [api-chain] + service: storage-service + storage-uploads: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/uploads`)" + entryPoints: [web] + middlewares: [api-chain] + service: storage-service + + # --- Booking Service --- + booking-bookings: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/bookings`)" + entryPoints: [web] + middlewares: [api-chain] + service: booking-service + booking-reservations: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/reservations`)" + entryPoints: [web] + middlewares: [api-chain] + service: booking-service + booking-appointments: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/appointments`)" + entryPoints: [web] + middlewares: [api-chain] + service: booking-service + booking-therapists: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/therapists`)" + entryPoints: [web] + middlewares: [api-chain] + service: booking-service + + # --- Chat Service --- + chat-chats: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/chats`)" + entryPoints: [web] + middlewares: [api-chain] + service: chat-service + chat-messages: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/messages`)" + entryPoints: [web] + middlewares: [api-chain] + service: chat-service + chat-conversations: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/conversations`)" + entryPoints: [web] + middlewares: [api-chain] + service: chat-service + chat-hub: + rule: "Host(`api.techbi.org`) && PathPrefix(`/hubs/chat`)" + entryPoints: [web] + middlewares: [websocket-headers] + service: chat-service + + # --- Social Service --- + social: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/social`)" + entryPoints: [web] + middlewares: [api-chain] + service: social-service + social-relationships: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/relationships`)" + entryPoints: [web] + middlewares: [api-chain] + service: social-service + + # --- Promotion Service --- + promotion-promotions: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/promotions`)" + entryPoints: [web] + middlewares: [api-chain] + service: promotion-service + promotion-vouchers: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/vouchers`)" + entryPoints: [web] + middlewares: [api-chain] + service: promotion-service + + # --- Membership Service --- + membership-members: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/members`)" + entryPoints: [web] + middlewares: [api-chain] + service: membership-service + membership-levels: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/levels`)" + entryPoints: [web] + middlewares: [api-chain] + service: membership-service + + # --- Mining Service --- + mining: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/mining`)" + entryPoints: [web] + middlewares: [api-chain] + service: mining-service + mining-circles: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/circles`)" + entryPoints: [web] + middlewares: [api-chain] + service: mining-service + mining-referrals: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/referrals`)" + entryPoints: [web] + middlewares: [api-chain] + service: mining-service + + # --- Mission Service --- + mission-missions: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/missions`)" + entryPoints: [web] + middlewares: [api-chain] + service: mission-service + mission-checkins: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/checkins`)" + entryPoints: [web] + middlewares: [api-chain] + service: mission-service + + # --- Ads Manager Service --- + ads-ads: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/ads`)" + entryPoints: [web] + middlewares: [api-chain] + service: ads-manager-service + ads-campaigns: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/campaigns`)" + entryPoints: [web] + middlewares: [api-chain] + service: ads-manager-service + ads-adsets: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/adsets`)" + entryPoints: [web] + middlewares: [api-chain] + service: ads-manager-service + ads-audiences: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/audiences`)" + entryPoints: [web] + middlewares: [api-chain] + service: ads-manager-service + + # --- Ads Serving --- + ads-serving: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/ads-serving`)" + entryPoints: [web] + middlewares: [api-chain] + service: ads-serving-service + + # --- Ads Billing --- + ads-billing: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/ads-billing`)" + entryPoints: [web] + middlewares: [api-chain] + service: ads-billing-service + ads-invoices: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/ad-invoices`)" + entryPoints: [web] + middlewares: [api-chain] + service: ads-billing-service + + # --- Ads Tracking --- + ads-events: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/ad-events`)" + entryPoints: [web] + middlewares: [api-chain] + service: ads-tracking-service + ads-pixels: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/pixels`)" + entryPoints: [web] + middlewares: [api-chain] + service: ads-tracking-service + ads-conversions: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/conversions`)" + entryPoints: [web] + middlewares: [api-chain] + service: ads-tracking-service + + # --- Ads Analytics --- + ads-analytics: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/ad-analytics`)" + entryPoints: [web] + middlewares: [api-chain] + service: ads-analytics-service + ads-reports: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/ad-reports`)" + entryPoints: [web] + middlewares: [api-chain] + service: ads-analytics-service + + # --- Marketing Services --- + mkt-facebook: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/mkt/facebook`)" + entryPoints: [web] + middlewares: [api-chain] + service: mkt-facebook-service + mkt-whatsapp: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/mkt/whatsapp`)" + entryPoints: [web] + middlewares: [api-chain] + service: mkt-whatsapp-service + mkt-x: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/mkt/x`)" + entryPoints: [web] + middlewares: [api-chain] + service: mkt-x-service + mkt-zalo: + rule: "Host(`api.techbi.org`) && PathPrefix(`/api/v1/mkt/zalo`)" + entryPoints: [web] + middlewares: [api-chain] + service: mkt-zalo-service + + # ============================================= + # Router — platform.techbi.org (POS Frontend) + # ============================================= + pos-web: + rule: "Host(`platform.techbi.org`)" + entryPoints: [web] + middlewares: [compress, secure-headers] + service: pos-web + + # ============================================= + # Services (backend targets) + # ============================================= + services: + iam-service: + loadBalancer: + servers: + - url: "http://iam-service:8080" + merchant-service: + loadBalancer: + servers: + - url: "http://merchant-service:8080" + order-service: + loadBalancer: + servers: + - url: "http://order-service:8080" + fnb-engine: + loadBalancer: + servers: + - url: "http://fnb-engine:8080" + catalog-service: + loadBalancer: + servers: + - url: "http://catalog-service:8080" + inventory-service: + loadBalancer: + servers: + - url: "http://inventory-service:8080" + wallet-service: + loadBalancer: + servers: + - url: "http://wallet-service:8080" + storage-service: + loadBalancer: + servers: + - url: "http://storage-service:8080" + booking-service: + loadBalancer: + servers: + - url: "http://booking-service:8080" + chat-service: + loadBalancer: + servers: + - url: "http://chat-service:8080" + social-service: + loadBalancer: + servers: + - url: "http://social-service:8080" + promotion-service: + loadBalancer: + servers: + - url: "http://promotion-service:8080" + membership-service: + loadBalancer: + servers: + - url: "http://membership-service:8080" + mining-service: + loadBalancer: + servers: + - url: "http://mining-service:8080" + mission-service: + loadBalancer: + servers: + - url: "http://mission-service:8080" + ads-manager-service: + loadBalancer: + servers: + - url: "http://ads-manager-service:8080" + ads-serving-service: + loadBalancer: + servers: + - url: "http://ads-serving-service:8080" + ads-billing-service: + loadBalancer: + servers: + - url: "http://ads-billing-service:8080" + ads-tracking-service: + loadBalancer: + servers: + - url: "http://ads-tracking-service:8080" + ads-analytics-service: + loadBalancer: + servers: + - url: "http://ads-analytics-service:8080" + mkt-facebook-service: + loadBalancer: + servers: + - url: "http://mkt-facebook-service:8080" + mkt-whatsapp-service: + loadBalancer: + servers: + - url: "http://mkt-whatsapp-service:8080" + mkt-x-service: + loadBalancer: + servers: + - url: "http://mkt-x-service:8080" + mkt-zalo-service: + loadBalancer: + servers: + - url: "http://mkt-zalo-service:8080" + pos-web: + loadBalancer: + servers: + - url: "http://pos-web:8080" + +--- +# ============================================================================= +# Traefik Deployment +# ============================================================================= +apiVersion: apps/v1 +kind: Deployment +metadata: + name: traefik + namespace: staging + labels: + app: traefik + environment: staging + platform: goodgo +spec: + replicas: 1 + selector: + matchLabels: + app: traefik + template: + metadata: + labels: + app: traefik + environment: staging + spec: + containers: + - name: traefik + image: traefik:v3.3 + ports: + - containerPort: 80 + protocol: TCP + name: web + args: + - "--configFile=/etc/traefik/traefik.yml" + volumeMounts: + - name: traefik-config + mountPath: /etc/traefik + - name: traefik-dynamic + mountPath: /etc/traefik/dynamic + resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "500m" + memory: "256Mi" + livenessProbe: + httpGet: + path: /ping + port: 80 + initialDelaySeconds: 10 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /ping + port: 80 + initialDelaySeconds: 5 + periodSeconds: 5 + volumes: + - name: traefik-config + configMap: + name: traefik-config + items: + - key: traefik.yml + path: traefik.yml + - name: traefik-dynamic + configMap: + name: traefik-config + items: + - key: routes.yml + path: routes.yml + +--- +# ============================================================================= +# Traefik Service (ClusterIP - internal only) +# ============================================================================= +apiVersion: v1 +kind: Service +metadata: + name: traefik + namespace: staging + labels: + app: traefik + environment: staging + platform: goodgo +spec: + selector: + app: traefik + ports: + - name: web + port: 80 + targetPort: 80 + protocol: TCP + type: ClusterIP