Compare commits

..

4 commits

Author SHA1 Message Date
sync-test
301fc9acd5 chore: add networkpolicy.yaml to ollama kustomization
All checks were successful
sync-to-forgejo / sync (push) Successful in 19s
2026-07-06 01:50:49 +05:30
sync-test
b709d31b67 feat: Add NetworkPolicy for Ollama security on high-performance branch (Task 3) 2026-07-06 01:50:32 +05:30
sync-test
8f777775c9 test(ci): verify github-to-forgejo sync for gitops
All checks were successful
sync-to-forgejo / sync (push) Successful in 20s
2026-07-04 19:29:00 +05:30
Ashwin Kumar Sivakumar
3aa95c9d92 ci: sync GitHub pushes to Forgejo
Some checks failed
sync-to-forgejo / sync (push) Failing after 0s
2026-07-03 18:59:24 +05:30
142 changed files with 682 additions and 6880 deletions

View file

@ -1 +0,0 @@
1783461178

View file

@ -1,37 +0,0 @@
name: sync-to-github
on:
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
concurrency:
group: sync-to-github-${{ github.ref }}
cancel-in-progress: true
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Configure Git
run: |
git config user.name "forgejo-actions[bot]"
git config user.email "forgejo-actions@ci.nxtgauge.com"
- name: Push to GitHub
env:
GH_MIRROR_TOKEN: ${{ secrets.GH_MIRROR_TOKEN }}
run: |
set -euo pipefail
git remote add github-mirror "https://Traceworks2023:${GH_MIRROR_TOKEN}@github.com/Traceworks2023/nxtgauge-gitops.git" 2>/dev/null || \
git remote set-url github-mirror "https://Traceworks2023:${GH_MIRROR_TOKEN}@github.com/Traceworks2023/nxtgauge-gitops.git"
git push github-mirror "HEAD:main"

View file

@ -33,33 +33,6 @@ jobs:
FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }}
run: |
set -euo pipefail
BRANCH="${GITHUB_REF#refs/heads/}"
REMOTE_URL="https://admin:${FORGEJO_TOKEN}@ci.nxtgauge.com/ashwin/${{ github.event.repository.name }}.git"
git remote add forgejo "$REMOTE_URL" 2>/dev/null || git remote set-url forgejo "$REMOTE_URL"
git fetch forgejo "$BRANCH" || true
# This repo isn't a plain mirror: FluxCD's ImageUpdateAutomation
# commits directly to Forgejo (the GitRepository Flux actually
# watches), so Forgejo routinely has commits GitHub never sees.
# A rebase here assumes Forgejo is always a fast-forward of
# GitHub, which breaks the moment Flux has pushed anything - and
# once one run fails, every run after it fails the same way,
# silently stalling all deploys until someone notices and
# reconciles history by hand.
#
# Merge instead. GitHub is the source of truth for human/CI
# content, so conflicting hunks resolve in its favor (-X ours),
# but Flux's commits are kept as merge ancestors rather than
# discarded. The merge commit is only pushed to Forgejo - GitHub's
# branch is left untouched - so this repeats cleanly next run
# instead of accumulating rewritten history on GitHub.
if git show-ref --verify --quiet "refs/remotes/forgejo/$BRANCH"; then
if ! git merge -X ours --no-edit "refs/remotes/forgejo/$BRANCH"; then
echo "::error::Merge with Forgejo's $BRANCH has conflicts -X ours could not resolve; manual reconciliation needed." >&2
exit 1
fi
fi
git push forgejo "HEAD:$BRANCH"
git remote add forgejo "https://admin:${FORGEJO_TOKEN}@ci.nxtgauge.com/ashwin/${{ github.event.repository.name }}.git" 2>/dev/null || \
git remote set-url forgejo "https://admin:${FORGEJO_TOKEN}@ci.nxtgauge.com/ashwin/${{ github.event.repository.name }}.git"
git push forgejo "HEAD:${GITHUB_REF#refs/heads/}" --force

View file

@ -0,0 +1,83 @@
name: Trigger App Builds From GitOps
on:
push:
branches:
- main
- testingcodex
paths:
- apps/nxtgauge-backend/**
- apps/nxtgauge-admin-frontend/**
- apps/nxtgauge-frontendwebsite/**
permissions:
contents: read
jobs:
detect-changes:
if: ${{ github.actor != 'github-actions[bot]' && !startsWith(github.event.head_commit.message, 'chore(gitops): update ') }}
runs-on: ubuntu-latest
outputs:
backend: ${{ steps.filter.outputs.backend }}
admin: ${{ steps.filter.outputs.admin }}
public: ${{ steps.filter.outputs.public }}
steps:
- name: Checkout GitOps repo
uses: actions/checkout@v4
- name: Detect changed app paths
id: filter
uses: dorny/paths-filter@v3
with:
filters: |
backend:
- 'apps/nxtgauge-backend/**'
admin:
- 'apps/nxtgauge-admin-frontend/**'
public:
- 'apps/nxtgauge-frontendwebsite/**'
trigger-backend:
needs: detect-changes
if: ${{ needs.detect-changes.outputs.backend == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Trigger backend workflow
env:
TOKEN: ${{ secrets.GITOPS_PAT }}
run: |
curl -sS -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${TOKEN}" \
https://api.github.com/repos/Traceworks2023/nxtgauge-nov-2025-backend/actions/workflows/build-and-push-ghcr.yml/dispatches \
-d '{"ref":"testingcodex"}'
trigger-admin-frontend:
needs: detect-changes
if: ${{ needs.detect-changes.outputs.admin == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Trigger admin frontend workflow
env:
TOKEN: ${{ secrets.GITOPS_PAT }}
run: |
curl -sS -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${TOKEN}" \
https://api.github.com/repos/Traceworks2023/nxtgauge-nov-2025-frontend/actions/workflows/build-push-and-update-gitops.yml/dispatches \
-d '{"ref":"testingcodex"}'
trigger-public-frontend:
needs: detect-changes
if: ${{ needs.detect-changes.outputs.public == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Trigger public frontend workflow
env:
TOKEN: ${{ secrets.GITOPS_PAT }}
run: |
curl -sS -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${TOKEN}" \
https://api.github.com/repos/Traceworks2023/nxtgauge-frontendwebsite/actions/workflows/build-push-and-update-gitops.yml/dispatches \
-d '{"ref":"testingcodex"}'

View file

@ -1,4 +0,0 @@
creation_rules:
- path_regex: apps/.*\.ya?ml$
encrypted_regex: ^(data|stringData)$
age: age1sqxc53yvap8763eup99g6eza6fa5u65qetdymlh5ch4ugvvv5q0sf3pm4l

View file

@ -1,101 +0,0 @@
# OTP Issue Fix for NXTGAUGE Signup Flow
## Problem Statement
Users get "unable to create account" error when trying to sign up in the frontend-solid application. The OTP (One-Time Password) verification functionality during signup is broken.
## Root Cause Analysis
The OTP fixes were implemented but got overwritten by subsequent commits and finally all services were switched to `high-performance-latest` tag which doesn't include the OTP functionality.
## Historical Context
### April 16, 17:30 - Initial OTP Fixes (Working)
- Frontend commit: `152f918` - Fixed resend-otp API endpoint path
- Backend users commit: `31d4570` - Updated email footer
- These fixes made OTP work correctly
### April 16, 18:06 - v1 API + Legacy OTP Support (Enhanced)
- Gateway commit: `d084491` - Added /api/v1/users routing + legacy resend-otp endpoint for backward compatibility
- Backend users commit: `d084491` - Updated to support v1 API
- Enhanced OTP support with backward compatibility
### April 16, 21:33 - Infrastructure Override (Broke OTP)
- Frontend: `152f918``d26f0bf` (lost OTP fix)
- Backend users: `d084491``9444056` (lost v1 API/OTP support)
- These crane mirror builds overwrote the OTP fixes
### April 17, 05:25 - Current State (Still Broken)
- All services switched to `high-performance-latest` tag
- Frontend: `high-performance-latest` (missing OTP fix from `152f918`)
- Gateway: `high-performance-latest` (missing legacy OTP support from `d084491`)
- Backend users: `high-performance-latest` (missing v1 API/OTP from `d084491`)
## Current GitOps Configuration
### Backend Kustomization (apps/nxtgauge-backend-rust/overlays/prod/kustomization.yaml)
```yaml
images:
- name: registry.nxtgauge.com/nxtgauge-rust-gateway
newTag: high-performance-latest
- name: registry.nxtgauge.com/nxtgauge-rust-users
newTag: high-performance-latest
- name: registry.nxtgauge-frontend-solid
newTag: high-performance-latest
```
### Frontend Kustomization (apps/nxtgauge-frontend-solid/overlays/prod/kustomization.yaml)
```yaml
images:
- name: registry.nxtgauge.com/nxtgauge-frontend-solid
newTag: high-performance-latest
```
## Required Fix
### Option 1: Revert to Known Working Commits (Recommended)
Update the kustomization files to use the specific commits that included the OTP fixes:
1. Frontend: Change back to `152f918` (contains the OTP endpoint fix)
2. Gateway: Change back to `d084491` (contains legacy OTP support)
3. Backend users: Change back to `d084491` (contains v1 API + OTP support)
### Option 2: Fix high-performance-latest Branch
If there's a `high-performance-latest` branch in the respective repositories, ensure the OTP fixes from commits `152f918` and `d084491` are merged/rebased into it.
## Files to Modify
1. `apps/nxtgauge-frontend-solid/overlays/prod/kustomization.yaml`
2. `apps/nxtgauge-backend-rust/overlays/prod/kustomization.yaml`
## Expected Behavior After Fix
1. User enters email during signup
2. Frontend calls OTP generation endpoint
3. Backend generates and sends OTP via email
4. User enters received OTP
5. Frontend calls OTP verification endpoint
6. Backend verifies OTP and creates account
7. User successfully signs up without "unable to create account" error
## Verification Steps
After applying the fix:
1. Trigger Flux sync for both applications
2. Wait for pods to restart with new images
3. Test signup flow: enter email → receive OTP → verify OTP → account created
4. Check logs if signup still fails
5. Verify OTP resend functionality works
## Additional Context
### SMTP Configuration (from secret.yaml)
- SMTP_HOST: "smtp.zeptomail.in"
- SMTP_PORT: "587"
- SMTP_FROM_EMAIL: "support@nxtgauge.com"
- SMTP_SECURE: "false"
### Gateway Configuration
- Gateway URL: "http://nxtgauge-rust-gateway:9100"
- API URL: "http://nxtgauge-rust-gateway:9100/api"
- Users Service URL: "http://nxtgauge-rust-users:9101"
Please analyze the codebase, identify the exact OTP endpoints that need to work, and provide the necessary fixes to restore the signup functionality.

View file

@ -1,193 +0,0 @@
# Route Issue Analysis for NXTGAUGE Frontend-Solid Signup
## Current Status: ❌ NOT FIXED
The route issues from the frontend-solid signup pages are **still not resolved**. Users experience "unable to create account" errors during signup due to API endpoint path mismatches.
## Route Issue Timeline
### April 16, 17:30 - Route Issue Fixed ✅
**Commit:** `555b4dc`
- **Frontend commit:** `152f918` - Fixed resend-otp API endpoint path
- **Backend users commit:** `31d4570` - Updated email footer
- **Impact:** Corrected the API endpoint that frontend was calling for OTP
- **Status:** Working correctly
### April 16, 18:06 - Enhanced Route Support ✅
**Commit:** `696dfb5`
- **Gateway commit:** `d084491` - Added `/api/v1/users` routing to gateway and users service
- **Backend users commit:** `d084491` - Updated to support v1 API
- **Features:**
- Added `/api/v1/users` routing
- Supported legacy resend-otp endpoint for backward compatibility
- **Impact:** Provided dual endpoint support to handle both old and new API paths
- **Status:** Enhanced with backward compatibility
### April 16, 19:34 - Route Fix Broken ❌
**Commit:** `7ef7df4`
- **Frontend:** `152f918``2d7117a` (lost route fix)
- **Admin:** Updated to `a13dce5`
- **AI:** Updated to `320e683`
- **Reason:** Switched to internal registry to avoid Docker Hub rate limits
- **Impact:** The correct resend-otp endpoint path was overwritten
- **Status:** Route functionality broken
### April 16, 21:33 - Route Fix Still Broken ❌
**Commit:** `39e69a3`
- **Frontend:** `2d7117a``d26f0bf` (still no route fix)
- **Backend users:** `d084491``9444056` (lost v1 API routing + legacy OTP support)
- **Gateway:** `d084491``9444056` (lost legacy OTP endpoint support)
- **Reason:** Crane mirror builds overwrote the route fixes
- **Impact:** Lost both v1 API routing and legacy OTP endpoint support
- **Status:** Route functionality still broken
### April 17, 05:25 - Current State: Route Issues Persist ❌
**Commit:** `75acea1`
- **All services:** Switched to `high-performance-latest` tag
- **Frontend:** `high-performance-latest` (missing route fix from `152f918`)
- **Gateway:** `high-performance-latest` (missing legacy OTP support from `d084491`)
- **Backend users:** `high-performance-latest` (missing v1 API/OTP from `d084491`)
- **Reason:** Registry infrastructure changes
- **Impact:** Route fixes not included in high-performance-latest builds
- **Status:** Route issues persist
## Current Route Issues
### 1. Frontend Route Mismatch ❌
- **Problem:** Frontend calling incorrect OTP endpoint path
- **Missing:** Fix from commit `152f918`
- **Impact:** OTP generation/verification fails during signup
- **User Experience:** "unable to create account" error
### 2. Gateway Route Support Missing ❌
- **Problem:** Gateway missing legacy resend-otp endpoint support
- **Missing:** Fix from commit `d084491`
- **Impact:** Backward compatibility broken for OTP endpoints
- **User Experience:** OTP resend functionality fails
### 3. Backend API Routing Missing ❌
- **Problem:** Backend missing `/api/v1/users` routing
- **Missing:** Fix from commit `d084491`
- **Impact:** v1 API endpoints not accessible
- **User Experience:** Signup and user management functions fail
## Current GitOps Configuration
### Backend Kustomization
**File:** `apps/nxtgauge-backend-rust/overlays/prod/kustomization.yaml`
```yaml
images:
- name: registry.nxtgauge.com/nxtgauge-rust-gateway
newTag: high-performance-latest # ❌ Missing d084491
- name: registry.nxtgauge.com/nxtgauge-rust-users
newTag: high-performance-latest # ❌ Missing d084491
```
### Frontend Kustomization
**File:** `apps/nxtgauge-frontend-solid/overlays/prod/kustomization.yaml`
```yaml
images:
- name: registry.nxtgauge.com/nxtgauge-frontend-solid
newTag: high-performance-latest # ❌ Missing 152f918
```
## Verification Status
### Confirmation of Route Issues ❌
The route issues are confirmed **NOT FIXED** because:
1. **Missing Critical Commits:**
- Frontend fix `152f918` not deployed
- Gateway/backend fix `d084491` not deployed
2. **Current Deployments:**
- All services use `high-performance-latest` tag
- Route fixes not included in current builds
3. **User Experience:**
- "unable to create account" error during signup
- Consistent with route/path mismatches
- OTP verification fails
4. **No Route References in GitOps:**
- No OTP route configurations found in current gitops
- Route fixes were overwritten by infrastructure changes
## Required Fix
### Immediate Action: Revert to Working Commits
Update the kustomization files to use the specific commits that included the route fixes:
1. **Frontend:** Change to `152f918`
- Contains correct OTP endpoint path
- File: `apps/nxtgauge-frontend-solid/overlays/prod/kustomization.yaml`
2. **Gateway:** Change to `d084491`
- Contains legacy OTP endpoint support
- File: `apps/nxtgauge-backend-rust/overlays/prod/kustomization.yaml`
3. **Backend users:** Change to `d084491`
- Contains v1 API routing
- File: `apps/nxtgauge-backend-rust/overlays/prod/kustomization.yaml`
### Alternative: Fix high-performance-latest Branch
Ensure the route fixes from commits `152f918` and `d084491` are merged into the `high-performance-latest` branch in respective repositories.
## Expected Behavior After Fix
1. User enters email during signup
2. Frontend calls correct OTP endpoint: `/api/v1/users/resend-otp`
3. Gateway routes request to users service with proper path mapping
4. Backend generates and sends OTP via email
5. User enters received OTP
6. Frontend calls OTP verification endpoint
7. Backend verifies OTP and creates account
8. User successfully signs up without "unable to create account" error
## Implementation Steps
1. **Update GitOps Configuration:**
- Modify `apps/nxtgauge-frontend-solid/overlays/prod/kustomization.yaml`
- Modify `apps/nxtgauge-backend-rust/overlays/prod/kustomization.yaml`
2. **Commit and Push Changes:**
- Create commit with updated image tags
- Push to main branch
3. **Trigger Flux Sync:**
- Sync `nxtgauge-frontend-solid` application
- Sync `nxtgauge-backend-rust` application
4. **Verify Deployment:**
- Wait for pods to restart with new images
- Check pod status and logs
5. **Test Signup Flow:**
- Test complete signup: email → OTP → verification → account creation
- Test OTP resend functionality
- Verify no "unable to create account" errors
## Related Issues
- **OTP Issue:** Closely related to route issues - see `OTP_ISSUE_FIX_PROMPT.md`
- **Email Configuration:** SMTP settings are correct in `apps/nxtgauge-backend-rust/base/secret.yaml`
- **Gateway Configuration:** Gateway service properly configured in `apps/nxtgauge-backend-rust/base/gateway-service.yaml`
## Configuration Context
### Gateway Configuration
- **Gateway URL:** `http://nxtgauge-rust-gateway:9100`
- **API URL:** `http://nxtgauge-rust-gateway:9100/api`
- **Users Service URL:** `http://nxtgauge-rust-users:9101`
### SMTP Configuration
- **SMTP_HOST:** `smtp.zeptomail.in`
- **SMTP_PORT:** `587`
- **SMTP_FROM_EMAIL:** `support@nxtgauge.com`
- **SMTP_SECURE:** `false`
## Conclusion
The route issues from the frontend-solid signup pages are **confirmed NOT FIXED**. The specific commits that contained the route corrections (`152f918` and `d084491`) are not currently deployed, and all services are using `high-performance-latest` which doesn't include these critical route fixes.
**Action Required:** Revert to the working commits to restore proper route functionality and fix the signup flow.

View file

@ -1,71 +0,0 @@
# Scaled to 0 (Phase 0 of the AI architecture doc — "Stabilize the Existing
# Environment"): ai-guard has no Dockerfile in its source repo, so no image
# has ever been successfully built by its CI. The pod has been in
# ImagePullBackOff for 14+ days (90,000+ failed pulls) pulling an image that
# doesn't exist. It also has no Service (unreachable even if healthy) and
# depends on llm-guard/presidio, neither of which are deployed. Nothing
# currently routes through it — both AI consumers (nxtgauge-ai-assistant,
# nxtgauge-backend-rust) call LiteLLM directly. Scaling to 0 stops the
# wasted kubelet pull-retry churn until Phase 3 (Rebuild ai-guard) is done
# properly, per the architecture doc.
apiVersion: apps/v1
kind: Deployment
metadata:
name: ai-guard
namespace: nxtgauge-ai
labels:
app: ai-guard
spec:
replicas: 0
selector:
matchLabels:
app: ai-guard
template:
metadata:
labels:
app: ai-guard
spec:
containers:
- name: ai-guard
image: registry.nxtgauge.com/ai-guard:latest
imagePullPolicy: Always
ports:
- containerPort: 8080
name: http
env:
- name: RUST_LOG
value: "info"
- name: PORT
value: "8080"
- name: OLLAMA_BASE_URL
value: "http://ollama.nxtgauge-ai.svc.cluster.local:11434"
- name: OLLAMA_CHAT_MODEL
value: "gemma3:270m"
- name: LLM_GUARD_URL
value: "http://llm-guard.nxtgauge-ai.svc.cluster.local:8000"
- name: PRESIDIO_URL
value: "http://presidio.nxtgauge-ai.svc.cluster.local:3000"
- name: AI_SERVICE_KEY
valueFrom:
secretKeyRef:
name: ai-guard-secrets
key: ai-service-key
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 1000m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 20
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10

View file

@ -1,7 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- secret.yaml
- deployment.yaml
- service.yaml

View file

@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: nxtgauge-ai

View file

@ -1,23 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: ai-guard-secrets
namespace: nxtgauge-ai
type: Opaque
stringData:
ai-service-key: ""
sops:
age:
- recipient: age1sqxc53yvap8763eup99g6eza6fa5u65qetdymlh5ch4ugvvv5q0sf3pm4l
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjblkzcGRBRWhROVlieEtL
MG51WmF6RThLTHN4K3YwVUxkYTBZek5HdzJNClY0cXFmM3NaY1M4V1ZPQWx1UlZo
bVFibWNlVjRBclRCMUl4MlowYm1ocjQKLS0tIDNoNEgwckZRdEROZmFybUd3NnhU
YTFWcWdUZk90ZWkzVkpWWXhWVzJQbzQK8Qe0Mrz80DruvKEW7sFvTMrhyUIsTK3p
BQtp4WPQZpedJG6RN3Q0hs3d6D2un/wvlq1OFyHOWsheh3sbuYn+Qg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-07-02T12:17:30Z"
mac: ENC[AES256_GCM,data:kCzNtzPNF2jVJoQQO4J28MkcNw0uzTrJaQbCCXxwnkWdO+HFMYCskYwrxxouwuP2Gupt1vHOE8nk+a/oWzKCv5rhuVa6VyyMH9ufK5XPhJbuYMsf2IsuLgHWE95lhJEerezusm6L68rS45i+YCd0/biS7vc0AIxt8NcI2soCcPE=,iv:pacRPzx4+K+dsNxASA1I2oeLZNK3gy0bydDbt58jsjw=,tag:RVnbv1myFiTSifjurd/kyg==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View file

@ -1,16 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: ai-guard
namespace: nxtgauge-ai
labels:
app: ai-guard
spec:
type: ClusterIP
selector:
app: ai-guard
ports:
- name: http
port: 8080
targetPort: 8080
protocol: TCP

View file

@ -1,7 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
images:
- name: registry.nxtgauge.com/ai-guard
newTag: latest

View file

@ -1,168 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: forgejo
---
apiVersion: v1
kind: ConfigMap
metadata:
name: forgejo-config
namespace: forgejo
data:
app.ini: |
RUN_MODE = prod
RUN_USER = forge
[server]
DOMAIN = ci.nxtgauge.com
HTTP_PORT = 3000
ROOT_URL = https://ci.nxtgauge.com/
DISABLE_SSH = false
SSH_PORT = 22
LFS_OBJECTS_PATH = /data/gitea/lfs
[database]
DB_TYPE = postgres
HOST = pg-postgresql.data.svc.cluster.local:5432
NAME = forgejo
USER = nxtgauge
PASSWD = chandan2026@1
SSL_MODE = disable
[security]
INSTALL_LOCK = true
SECRET_KEY = eF4nC8wQ3rT2yU9iO5pA1sD6fG7hJ8kL0zXcVbNmMqWeRtY
[service]
DISABLE_REGISTRATION = false
[log]
MODE = console
LEVEL = info
[packages]
ENABLED = true
[packages.container]
ENABLED = true
REGISTRY_TYPE = docker-registry
REGISTRY_URL = https://registry.nxtgauge.com
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: forgejo-data
namespace: forgejo
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: forgejo
namespace: forgejo
labels:
app: forgejo
spec:
replicas: 1
selector:
matchLabels:
app: forgejo
strategy:
type: Recreate
template:
metadata:
labels:
app: forgejo
spec:
containers:
- name: forgejo
image: registry.nxtgauge.com/forgejo:10
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3000
name: http
env:
- name: FORGEJO__SERVER__ROOT_URL
value: "https://ci.nxtgauge.com/"
- name: FORGEJO__DATABASE__HOST
value: "pg-postgresql.data.svc.cluster.local"
- name: FORGEJO__DATABASE__PORT
value: "5432"
- name: FORGEJO__DATABASE__NAME
value: "forgejo"
- name: FORGEJO__DATABASE__USER
value: "nxtgauge"
- name: FORGEJO__DATABASE__PASSWD
value: "chandan2026@1"
- name: FORGEJO__PACKAGES__ENABLED
value: "true"
- name: FORGEJO__PACKAGES__CONTAINER__ENABLED
value: "true"
- name: FORGEJO__PACKAGES__CONTAINER__REGISTRY_TYPE
value: "docker-registry"
- name: FORGEJO__PACKAGES__CONTAINER__REGISTRY_URL
value: "https://registry.nxtgauge.com"
volumeMounts:
- mountPath: /data
name: data
resources:
limits:
cpu: "1"
memory: 512Mi
requests:
cpu: 100m
memory: 256Mi
readinessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
livenessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 60
periodSeconds: 30
volumes:
- name: data
persistentVolumeClaim:
claimName: forgejo-data
---
apiVersion: v1
kind: Service
metadata:
name: forgejo-http
namespace: forgejo
spec:
selector:
app: forgejo
ports:
- port: 3000
targetPort: 3000
name: http
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: forgejo
namespace: forgejo
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
spec:
ingressClassName: traefik
tls:
- hosts:
- ci.nxtgauge.com
secretName: forgejo-tls
rules:
- host: ci.nxtgauge.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: forgejo-http
port:
number: 3000

View file

@ -1,155 +0,0 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: forgejo-runner
namespace: forgejo
labels:
app: forgejo-runner
spec:
selector:
matchLabels:
app: forgejo-runner
template:
metadata:
labels:
app: forgejo-runner
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: DoesNotExist
- key: node-role.kubernetes.io/master
operator: DoesNotExist
initContainers:
- name: init-runner-permissions
image: ci.nxtgauge.com/admin/busybox:1.36
command: ["/bin/sh", "-ec"]
args:
- |
mkdir -p /data /cache
chown -R 1000:0 /data /cache
chmod -R g=u /data /cache
securityContext:
runAsUser: 0
volumeMounts:
- name: runner-config
mountPath: /data
- name: runner-cache
mountPath: /cache
containers:
- name: dind
image: ci.nxtgauge.com/admin/docker:27-dind
args:
- --host=tcp://0.0.0.0:2375
- --tls=false
securityContext:
privileged: true
env:
- name: DOCKER_TLS_CERTDIR
value: ""
volumeMounts:
- name: dind-storage
mountPath: /var/lib/docker
- name: docker-config
mountPath: /etc/docker/daemon.json
subPath: daemon.json
- name: registry-cert
mountPath: /etc/docker/certs.d/ci.nxtgauge.com/ca.crt
subPath: registry.crt
readOnly: true
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 2
memory: 4Gi
- name: runner
image: ci.nxtgauge.com/admin/forgejo-runner:6
env:
- name: DOCKER_HOST
value: tcp://127.0.0.1:2375
- name: FORGEJO_INSTANCE_URL
value: http://forgejo-http.forgejo.svc.cluster.local:3000
- name: FORGEJO_RUNNER_REGISTRATION_TOKEN
valueFrom:
secretKeyRef:
name: forgejo-runner-secret
key: FORGEJO_RUNNER_REGISTRATION_TOKEN
- name: K8S_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: FORGEJO_RUNNER_LABELS
value: "self-hosted:docker://ci.nxtgauge.com/admin/forgejo-runner-job:bookworm,linux:docker://ci.nxtgauge.com/admin/forgejo-runner-job:bookworm,ubuntu-latest:docker://ci.nxtgauge.com/admin/forgejo-runner-job:bookworm,ubuntu-22.04:docker://ci.nxtgauge.com/admin/forgejo-runner-job:bookworm,ubuntu-24.04:docker://ci.nxtgauge.com/admin/forgejo-runner-job:bookworm,debian-12:docker://ci.nxtgauge.com/admin/forgejo-runner-job:bookworm,docker-ready:docker://ci.nxtgauge.com/admin/forgejo-runner-job:bookworm"
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 4
memory: 8Gi
volumeMounts:
- name: runner-config
mountPath: /data
- name: runner-cache
mountPath: /cache
command: ["/bin/sh"]
args:
- -ec
- |
cd /data
RUNNER_NAME="${K8S_NODE_NAME}"
echo "Waiting for Docker sidecar on ${K8S_NODE_NAME}..."
sleep 8
rm -f .runner
echo "Registering runner ${RUNNER_NAME}..."
forgejo-runner register \
--no-interactive \
--instance "$FORGEJO_INSTANCE_URL" \
--token "$FORGEJO_RUNNER_REGISTRATION_TOKEN" \
--name "$RUNNER_NAME" \
--labels "$FORGEJO_RUNNER_LABELS"
echo "Starting daemon..."
# Create config.yaml for daemon
if [ ! -f /data/config.yaml ]; then
cat > /data/config.yaml << CONFIGEOF
log:
level: info
runner:
file: .runner
daemon:
container:
network: host
privileged: true
CONFIGEOF
fi
exec forgejo-runner daemon
volumes:
- name: docker-config
configMap:
name: docker-daemon-config
- name: registry-cert
configMap:
name: registry-cert
items:
- key: registry.crt
path: registry.crt
- name: runner-config
hostPath:
path: /var/lib/forgejo-runner
type: DirectoryOrCreate
- name: runner-cache
hostPath:
path: /var/cache/forgejo-runner
type: DirectoryOrCreate
- name: dind-storage
emptyDir: {}
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 0

View file

@ -1,10 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: docker-daemon-config
namespace: forgejo
data:
daemon.json: |
{
"insecure-registries": ["registry.nxtgauge.com"]
}

View file

@ -1,15 +0,0 @@
FROM ci.nxtgauge.com/admin/docker:27-dind
RUN apk add --no-cache \
bash \
curl \
git \
jq \
nodejs \
npm \
openssh-client \
python3 \
py3-pip \
tar
ENTRYPOINT []

View file

@ -1,28 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: registry-cert
namespace: forgejo
data:
registry.crt: |
-----BEGIN CERTIFICATE-----
MIIDXjCCAkagAwIBAgIRAKmaH9FY6+MJkPAoIP/iQkkwDQYJKoZIhvcNAQELBQAw
HzEdMBsGA1UEAxMUVFJBRUZJSyBERUZBVUxUIENFUlQwHhcNMjYwNjE3MTYxMTI2
WhcNMjcwNjE3MTYxMTI2WjAfMR0wGwYDVQQDExRUUkFFRklLIERFRkFVTFQgQ0VS
VDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALOQ4CM5+Vxm/0S3ijLl
nCdrhLO5/YHW4cby7llpn2Sac2fJP4jVnLLrFWITAfvqa5o2oDeHJH9nhpGZI/fg
NQvQu9RZIeq4d8xKoJ4d8qSJ2IVt2JJ+J0cjfg6Wm69DnFGpZGy4Vz4DgEWQ1u20
gnRfFBPBZmo45/pz9UafNtjoOx++C8VeHJRt8RCd0Zx26wePXQbN07+T1tj3MOc+
t92IBn0tQ9g20hiGMgrhi50dPv7HEupbKKy7ZCkBVN/XNHFrvorsCudirFlJZTGw
k2chsTOm2jiIf7xob+Ma1kHncH/NWm9QVieeBUTgrH/Fa2xAHhJ+DuFR0iXW8APj
FnMCAwEAAaOBlDCBkTAOBgNVHQ8BAf8EBAMCA7gwEwYDVR0lBAwwCgYIKwYBBQUH
AwEwDAYDVR0TAQH/BAIwADBcBgNVHREEVTBTglFmZmE0MmE0ZGJhZGJiMTY3ZjUz
YTBiNjA3ZWIyOTQ5OS5iN2QyYWM4ZDlhODRmZDU1MjU5OTc1Y2I0NDM3MWZhZS50
cmFlZmlrLmRlZmF1bHQwDQYJKoZIhvcNAQELBQADggEBAF1RgfSra5RE1zyRLAai
d8tBbzBMAYQVrLKjlYATsnv+d6RQ9ZocdwgLG2OI+roFx1BuLLl/C5aL09UFqCvr
Ab2exdlLMi4IGoVvgUkEtWYwwnbbsL0hR0keR7UE5snc2tT3SlAYLHenzY3kPFhf
Tx0IiS1hdLAQk0TpfRKDYJ7+IV5Mj+aeiG9uK+0je5VcvRSFnrGnackYT7f5yX96
fQ9vwhi7HvWwUlj/8wU/Se//92N7KkddlasyBF77Gdhnoa9qzYyUD1DJHCyfmkaI
RV9jAOWn4RFwpXB7TqNAKnkGWzYBaF5OQc7K/pHgYb+RtC1uNKd1rK3Lyoh56vAy
Y1g=
-----END CERTIFICATE-----

View file

@ -1,6 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: github-actions
resources:
- namespace.yaml
- runners.yaml

View file

@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: github-actions

View file

@ -1,371 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: github-runner-frontend
namespace: github-actions
labels:
app: github-runner-frontend
spec:
replicas: 1
selector:
matchLabels:
app: github-runner-frontend
template:
metadata:
labels:
app: github-runner-frontend
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: DoesNotExist
- key: node-role.kubernetes.io/master
operator: DoesNotExist
containers:
- name: dind
image: docker:27-dind
args:
- --host=tcp://0.0.0.0:2375
- --tls=false
securityContext:
privileged: true
env:
- name: DOCKER_TLS_CERTDIR
value: ""
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 2
memory: 4Gi
volumeMounts:
- name: dind-storage
mountPath: /var/lib/docker
- name: runner
image: docker.io/myoung34/github-runner:ubuntu-noble
env:
- name: ACCESS_TOKEN
valueFrom:
secretKeyRef:
name: github-runner-secrets
key: ACCESS_TOKEN
- name: RUNNER_SCOPE
value: repo
- name: REPO_URL
value: https://github.com/Traceworks2023/nxtgauge-frontend-solid
- name: RUNNER_NAME_PREFIX
value: frontend
- name: RANDOM_RUNNER_SUFFIX
value: "true"
- name: LABELS
value: ubuntu-latest,docker-ready
- name: RUNNER_WORKDIR
value: /tmp/runner/_work
- name: RUN_AS_ROOT
value: "true"
- name: DOCKER_HOST
value: tcp://127.0.0.1:2375
- name: DISABLE_AUTO_UPDATE
value: "true"
- name: UNSET_CONFIG_VARS
value: "true"
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 2
memory: 4Gi
volumeMounts:
- name: runner-work
mountPath: /tmp/runner
volumes:
- name: dind-storage
emptyDir: {}
- name: runner-work
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: github-runner-admin
namespace: github-actions
labels:
app: github-runner-admin
spec:
replicas: 1
selector:
matchLabels:
app: github-runner-admin
template:
metadata:
labels:
app: github-runner-admin
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: DoesNotExist
- key: node-role.kubernetes.io/master
operator: DoesNotExist
containers:
- name: dind
image: docker:27-dind
args:
- --host=tcp://0.0.0.0:2375
- --tls=false
securityContext:
privileged: true
env:
- name: DOCKER_TLS_CERTDIR
value: ""
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 2
memory: 4Gi
volumeMounts:
- name: dind-storage
mountPath: /var/lib/docker
- name: runner
image: docker.io/myoung34/github-runner:ubuntu-noble
env:
- name: ACCESS_TOKEN
valueFrom:
secretKeyRef:
name: github-runner-secrets
key: ACCESS_TOKEN
- name: RUNNER_SCOPE
value: repo
- name: REPO_URL
value: https://github.com/Traceworks2023/nxtgauge-admin-solid
- name: RUNNER_NAME_PREFIX
value: admin
- name: RANDOM_RUNNER_SUFFIX
value: "true"
- name: LABELS
value: ubuntu-latest,docker-ready
- name: RUNNER_WORKDIR
value: /tmp/runner/_work
- name: RUN_AS_ROOT
value: "true"
- name: DOCKER_HOST
value: tcp://127.0.0.1:2375
- name: DISABLE_AUTO_UPDATE
value: "true"
- name: UNSET_CONFIG_VARS
value: "true"
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 2
memory: 4Gi
volumeMounts:
- name: runner-work
mountPath: /tmp/runner
volumes:
- name: dind-storage
emptyDir: {}
- name: runner-work
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: github-runner-ai-assistant
namespace: github-actions
labels:
app: github-runner-ai-assistant
spec:
replicas: 1
selector:
matchLabels:
app: github-runner-ai-assistant
template:
metadata:
labels:
app: github-runner-ai-assistant
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: DoesNotExist
- key: node-role.kubernetes.io/master
operator: DoesNotExist
containers:
- name: dind
image: docker:27-dind
args:
- --host=tcp://0.0.0.0:2375
- --tls=false
securityContext:
privileged: true
env:
- name: DOCKER_TLS_CERTDIR
value: ""
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 2
memory: 4Gi
volumeMounts:
- name: dind-storage
mountPath: /var/lib/docker
- name: runner
image: docker.io/myoung34/github-runner:ubuntu-noble
env:
- name: ACCESS_TOKEN
valueFrom:
secretKeyRef:
name: github-runner-secrets
key: ACCESS_TOKEN
- name: RUNNER_SCOPE
value: repo
- name: REPO_URL
value: https://github.com/Traceworks2023/nxtgauge-ai-assistant
- name: RUNNER_NAME_PREFIX
value: ai-assistant
- name: RANDOM_RUNNER_SUFFIX
value: "true"
- name: LABELS
value: ubuntu-latest,docker-ready
- name: RUNNER_WORKDIR
value: /tmp/runner/_work
- name: RUN_AS_ROOT
value: "true"
- name: DOCKER_HOST
value: tcp://127.0.0.1:2375
- name: DISABLE_AUTO_UPDATE
value: "true"
- name: UNSET_CONFIG_VARS
value: "true"
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 2
memory: 4Gi
volumeMounts:
- name: runner-work
mountPath: /tmp/runner
volumes:
- name: dind-storage
emptyDir: {}
- name: runner-work
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: github-runner-backend
namespace: github-actions
labels:
app: github-runner-backend
spec:
replicas: 3
selector:
matchLabels:
app: github-runner-backend
template:
metadata:
labels:
app: github-runner-backend
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: DoesNotExist
- key: node-role.kubernetes.io/master
operator: DoesNotExist
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: github-runner-backend
topologyKey: kubernetes.io/hostname
containers:
- name: dind
image: docker:27-dind
args:
- --host=tcp://0.0.0.0:2375
- --tls=false
securityContext:
privileged: true
env:
- name: DOCKER_TLS_CERTDIR
value: ""
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2
memory: 4Gi
volumeMounts:
- name: dind-storage
mountPath: /var/lib/docker
- name: runner
image: docker.io/myoung34/github-runner:ubuntu-noble
env:
- name: ACCESS_TOKEN
valueFrom:
secretKeyRef:
name: github-runner-secrets
key: ACCESS_TOKEN
- name: RUNNER_SCOPE
value: repo
- name: REPO_URL
value: https://github.com/Traceworks2023/nxtgauge-backend-rust
- name: RUNNER_NAME_PREFIX
value: backend
- name: RANDOM_RUNNER_SUFFIX
value: "true"
- name: LABELS
value: ubuntu-latest,docker-ready
- name: RUNNER_WORKDIR
value: /tmp/runner/_work
- name: RUN_AS_ROOT
value: "true"
- name: DOCKER_HOST
value: tcp://127.0.0.1:2375
- name: DISABLE_AUTO_UPDATE
value: "true"
- name: UNSET_CONFIG_VARS
value: "true"
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 4
memory: 8Gi
volumeMounts:
- name: runner-work
mountPath: /tmp/runner
volumes:
- name: dind-storage
emptyDir: {}
- name: runner-work
emptyDir: {}

View file

@ -1,100 +0,0 @@
# LiteLLM Connection Details for OpenCode
## Quick Connect
| Setting | Value |
|---------|-------|
| **Base URL** | `http://litellm.nxtgauge-ai.svc.cluster.local:4000/v1` |
| **API Key** | `<REDACTED - see nxtgauge-litellm-secrets Secret, key LITELLM_MASTER_KEY>` |
## Available Models
- `askash-main` - Primary model (Ollama gemma3:270m)
- `askash-fast` - Faster response variant
- `coding-main` - Optimized for code tasks
## OpenCode Configuration
### Option 1: Environment Variables
```bash
export OPENAI_API_KEY="<REDACTED - see nxtgauge-litellm-secrets Secret, key LITELLM_MASTER_KEY>"
export OPENAI_API_BASE="http://litellm.nxtgauge-ai.svc.cluster.local:4000/v1"
export LLM_MODEL="askash-main"
```
### Option 2: Config File
Create `~/.config/opencode/config.json`:
```json
{
"provider": "openai",
"apiKey": "<REDACTED - see nxtgauge-litellm-secrets Secret, key LITELLM_MASTER_KEY>",
"baseUrl": "http://litellm.nxtgauge-ai.svc.cluster.local:4000/v1",
"model": "askash-main"
}
```
### Option 3: .opencode File (Project-specific)
Create `.opencode` in your project root:
```json
{
"llm": {
"provider": "openai",
"apiKey": "<REDACTED - see nxtgauge-litellm-secrets Secret, key LITELLM_MASTER_KEY>",
"baseUrl": "http://litellm.nxtgauge-ai.svc.cluster.local:4000/v1",
"model": "askash-main"
}
}
```
## Test Connection
```bash
# List models
curl http://litellm.nxtgauge-ai.svc.cluster.local:4000/v1/models \
-H "Authorization: Bearer <REDACTED - see nxtgauge-litellm-secrets Secret, key LITELLM_MASTER_KEY>"
# Chat completion
curl http://litellm.nxtgauge-ai.svc.cluster.local:4000/v1/chat/completions \
-H "Authorization: Bearer <REDACTED - see nxtgauge-litellm-secrets Secret, key LITELLM_MASTER_KEY>" \
-H "Content-Type: application/json" \
-d '{
"model": "askash-main",
"messages": [{"role": "user", "content": "Hello"}]
}'
```
## Port-Forward (If Running Locally)
If you need to access from your local machine:
```bash
kubectl port-forward svc/litellm 4000:4000 -n nxtgauge-ai
```
Then use: `http://localhost:4000/v1`
## Troubleshooting
| Issue | Solution |
|-------|----------|
| Connection refused | Run `kubectl port-forward svc/litellm 4000:4000 -n nxtgauge-ai` |
| 401 Unauthorized | Check API key is correct |
| 404 Not Found | Ensure URL ends with `/v1` |
| Timeout | Model may be loading; retry |
## Verify LiteLLM is Running
```bash
kubectl get pods -n nxtgauge-ai -l app=litellm
```
---
**Last Updated**: 2026-06-14
**Namespace**: nxtgauge-ai
**Service**: litellm:4000

View file

@ -1,189 +0,0 @@
# LiteLLM Setup for Nxtgauge
## Overview
LiteLLM is deployed as an API gateway to the internal Ollama service, providing OpenAI-compatible API endpoints.
## Architecture
- **Ollama**: Internal ClusterIP service at `ollama.nxtgauge-ai.svc.cluster.local:11434`
- **LiteLLM**: ClusterIP service at `10.43.7.24:4000` (internal)
- **Ingress**: Exposed at `https://llm.nxtgauge.com/v1` via Traefik
- **Security**: API key required via `LITELLM_MASTER_KEY`
## Master Key
**Production Master Key**: `<REDACTED - see nxtgauge-litellm-secrets Secret, key LITELLM_MASTER_KEY>`
⚠️ **IMPORTANT**: Store this key securely. It grants full access to the LLM API.
## Model Aliases
All aliases route to the same Ollama model (`gemma3:270m`):
| Alias | Model | Timeout | Retries |
|-------|-------|---------|---------|
| `askash-main` | ollama/gemma3:270m | 300s | 2 |
| `askash-fast` | ollama/gemma3:270m | 120s | 1 |
| `coding-main` | ollama/gemma3:270m | 300s | 2 |
## Files Created
### Base Configuration
- `/home/ashwin/nxtgauge-gitops/apps/litellm/base/configmap.yaml` - LiteLLM config
- `/home/ashwin/nxtgauge-gitops/apps/litellm/base/secret.yaml` - Secret template
- `/home/ashwin/nxtgauge-gitops/apps/litellm/base/deployment.yaml` - Deployment spec
- `/home/ashwin/nxtgauge-gitops/apps/litellm/base/service.yaml` - Service spec
- `/home/ashwin/nxtgauge-gitops/apps/litellm/base/ingress.yaml` - Ingress with TLS
- `/home/ashwin/nxtgauge-gitops/apps/litellm/base/ratelimit.yaml` - Rate limiting middleware
- `/home/ashwin/nxtgauge-gitops/apps/litellm/base/kustomization.yaml` - Base kustomization
### Production Overlay
- `/home/ashwin/nxtgauge-gitops/apps/litellm/overlays/prod/kustomization.yaml` - Production overlay with secure key
## Testing Commands
### List Available Models
```bash
curl https://llm.nxtgauge.com/v1/models \
-H "Authorization: Bearer <REDACTED - see nxtgauge-litellm-secrets Secret, key LITELLM_MASTER_KEY>"
```
### Test Chat Completion
```bash
curl https://llm.nxtgauge.com/v1/chat/completions \
-H "Authorization: Bearer <REDACTED - see nxtgauge-litellm-secrets Secret, key LITELLM_MASTER_KEY>" \
-H "Content-Type: application/json" \
-d '{
"model": "askash-main",
"messages": [
{
"role": "user",
"content": "Say hello from Ask Ash"
}
]
}'
```
### Test from Inside Cluster
```bash
kubectl run test-curl --rm -i --restart=Never --image=curlimages/curl:latest -- \
http://litellm.nxtgauge-ai.svc.cluster.local:4000/v1/models \
-H "Authorization: Bearer <REDACTED - see nxtgauge-litellm-secrets Secret, key LITELLM_MASTER_KEY>"
```
## OpenCode Configuration
Create/edit `~/.config/opencode/opencode.json`:
```json
{
"baseURL": "https://llm.nxtgauge.com/v1",
"apiKey": "<REDACTED - see nxtgauge-litellm-secrets Secret, key LITELLM_MASTER_KEY>",
"models": {
"default": "askash-main",
"available": [
"askash-main",
"askash-fast",
"coding-main"
]
}
}
```
## Ask Ash Local Environment
Create `.env.local` in your Ask Ash project:
```bash
# LiteLLM Provider Configuration
LLM_PROVIDER=openai_compatible
OPENAI_BASE_URL=https://llm.nxtgauge.com/v1
OPENAI_API_KEY=<REDACTED - see nxtgauge-litellm-secrets Secret, key LITELLM_MASTER_KEY>
LLM_MODEL=askash-main
AI_DEBUG=true
```
## Promptfoo Configuration
Create `promptfooconfig.yaml`:
```yaml
providers:
- id: openai
config:
apiBaseUrl: https://llm.nxtgauge.com/v1
apiKey: <REDACTED - see nxtgauge-litellm-secrets Secret, key LITELLM_MASTER_KEY>
model: askash-main
```
## DNS Configuration (Cloudflare)
Add DNS record in Cloudflare:
- **Type**: A
- **Name**: llm
- **Content**: Your cluster external IP (check with `kubectl get svc -n kube-system traefik`)
- **TTL**: Auto
- **Proxy Status**: DNS only (for testing), then enable after TLS works
## Security Notes
1. ✅ Ollama is NOT exposed publicly (ClusterIP only)
2. ✅ LiteLLM requires API key authentication
3. ✅ TLS enabled via cert-manager/Let's Encrypt
4. ✅ Rate limiting enabled (100 req/min avg, 50 burst)
5. ⚠️ Master key is stored in Kubernetes Secret (not in Git)
## Management Commands
```bash
# Check LiteLLM status
kubectl get pods -n nxtgauge-ai -l app=litellm
# View logs
kubectl logs -n nxtgauge-ai -l app=litellm --tail=100 -f
# Restart LiteLLM
kubectl rollout restart deployment litellm -n nxtgauge-ai
# Get master key
kubectl get secret litellm-secrets -n nxtgauge-ai -o jsonpath='{.data.LITELLM_MASTER_KEY}' | base64 -d
# Edit configuration
kubectl edit configmap litellm-config -n nxtgauge-ai
# Port-forward for local testing
kubectl port-forward svc/litellm 4000:4000 -n nxtgauge-ai
```
## Troubleshooting
### Pod not starting
```bash
kubectl describe pod -n nxtgauge-ai -l app=litellm
kubectl logs -n nxtgauge-ai -l app=litellm --previous
```
### Ollama unreachable
```bash
kubectl get svc -n nxtgauge-ai ollama
kubectl exec -n nxtgauge-ai -it ollama-76fb847d46-b7pkp -- ollama list
```
### TLS not working
```bash
kubectl get certificate -n nxtgauge-ai
kubectl describe certificate -n nxtgauge-ai litellm-tls
```
## Future Enhancements
1. Add more Ollama models and configure model-specific aliases
2. Implement request/response caching with Redis
3. Add Prometheus metrics for observability
4. Configure team-based API keys for multi-user access
5. Add request logging and usage analytics
6. Implement token-based billing/quota management
---
**Deployed**: 2026-06-14
**Namespace**: nxtgauge-ai
**Service**: litellm (10.43.7.24:4000)
**Ingress**: https://llm.nxtgauge.com

View file

@ -1,94 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: litellm-config
namespace: nxtgauge-ai
data:
config.yaml: |
model_list:
# === FAST MODEL (qwen3:4b) - 2.5GB ===
- model_name: askash-fast
litellm_params:
model: ollama/qwen3:4b
api_base: http://ollama.nxtgauge-ai.svc.cluster.local:11434
timeout: 60
- model_name: recommender
litellm_params:
model: ollama/qwen3:4b
api_base: http://ollama.nxtgauge-ai.svc.cluster.local:11434
timeout: 60
- model_name: messenger
litellm_params:
model: ollama/qwen3:4b
api_base: http://ollama.nxtgauge-ai.svc.cluster.local:11434
timeout: 60
- model_name: safety-check
litellm_params:
model: ollama/qwen3:4b
api_base: http://ollama.nxtgauge-ai.svc.cluster.local:11434
timeout: 60
- model_name: help-assistant
litellm_params:
model: ollama/qwen3:4b
api_base: http://ollama.nxtgauge-ai.svc.cluster.local:11434
timeout: 60
# === POWER MODEL (qwen3:8b) - 5.2GB ===
- model_name: askash-main
litellm_params:
model: ollama/qwen3:8b
api_base: http://ollama.nxtgauge-ai.svc.cluster.local:11434
timeout: 300
- model_name: jd-generator
litellm_params:
model: ollama/qwen3:8b
api_base: http://ollama.nxtgauge-ai.svc.cluster.local:11434
timeout: 300
- model_name: profile-writer
litellm_params:
model: ollama/qwen3:8b
api_base: http://ollama.nxtgauge-ai.svc.cluster.local:11434
timeout: 300
- model_name: service-writer
litellm_params:
model: ollama/qwen3:8b
api_base: http://ollama.nxtgauge-ai.svc.cluster.local:11434
timeout: 300
- model_name: requirement-writer
litellm_params:
model: ollama/qwen3:8b
api_base: http://ollama.nxtgauge-ai.svc.cluster.local:11434
timeout: 300
- model_name: support-drafter
litellm_params:
model: ollama/qwen3:8b
api_base: http://ollama.nxtgauge-ai.svc.cluster.local:11434
timeout: 300
- model_name: decision-support
litellm_params:
model: ollama/qwen3:8b
api_base: http://ollama.nxtgauge-ai.svc.cluster.local:11434
timeout: 300
- model_name: ultra-fast
litellm_params:
model: ollama/gemma3:270m
api_base: http://ollama.nxtgauge-ai.svc.cluster.local:11434
timeout: 30
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
router_settings:
fallback_retries: 2
timeout: 300

View file

@ -1,91 +0,0 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: litellm-postgres-backup
namespace: nxtgauge-ai
spec:
schedule: "45 2 * * *"
# Suspended: the nxtgauge-ai postgres instance has no working "litellm" database today
# (CREATE DATABASE fails on a corrupt system catalog file, base/<oid>/2617 "File exists").
# Un-suspend once that instance is fixed/reinitialized.
suspend: true
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 5
jobTemplate:
spec:
backoffLimit: 2
template:
spec:
restartPolicy: OnFailure
containers:
- name: pg-backup
image: postgres:15-alpine
envFrom:
- secretRef:
name: litellm-postgres-backup-secret
env:
- name: PGHOST
value: postgres
- name: PGPORT
value: "5432"
- name: PGUSER
valueFrom:
secretKeyRef:
name: postgres-credentials
key: POSTGRES_USER
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: postgres-credentials
key: POSTGRES_PASSWORD
- name: PGDATABASE
valueFrom:
secretKeyRef:
name: postgres-credentials
key: POSTGRES_DB
command: ["/bin/sh", "-ec"]
args:
- |
apk add --no-cache aws-cli python3 >/dev/null
TIMESTAMP="$(date -u +%Y%m%dT%H%M%SZ)"
RAW_FILE="/tmp/${PGDATABASE}-${TIMESTAMP}.sql"
DUMP_FILE="${RAW_FILE}.gz"
pg_dump -h "$PGHOST" -p "$PGPORT" -U "$PGUSER" -d "$PGDATABASE" -f "$RAW_FILE"
gzip -9 "$RAW_FILE"
export AWS_ACCESS_KEY_ID="$B2_ACCESS_KEY_ID"
export AWS_SECRET_ACCESS_KEY="$B2_SECRET_ACCESS_KEY"
export AWS_DEFAULT_REGION="$B2_REGION"
aws --endpoint-url "$B2_ENDPOINT" s3 cp "$DUMP_FILE" "s3://${B2_BUCKET_NAME}/${BACKUP_PREFIX}/$(basename "$DUMP_FILE")"
rm -f "$DUMP_FILE"
echo "Uploaded $(basename "$DUMP_FILE") to s3://${B2_BUCKET_NAME}/${BACKUP_PREFIX}/"
python3 - <<'PYEOF'
import subprocess, json, datetime, os
bucket = os.environ["B2_BUCKET_NAME"]
prefix = os.environ["BACKUP_PREFIX"]
endpoint = os.environ["B2_ENDPOINT"]
retention_days = int(os.environ.get("RETENTION_DAYS", "30"))
cutoff = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=retention_days)
out = subprocess.run(
["aws", "--endpoint-url", endpoint, "s3api", "list-objects-v2",
"--bucket", bucket, "--prefix", prefix],
capture_output=True, text=True, check=True,
)
listing = json.loads(out.stdout or "{}")
for obj in listing.get("Contents", []):
last_modified = datetime.datetime.fromisoformat(obj["LastModified"].replace("Z", "+00:00"))
if last_modified < cutoff:
subprocess.run(
["aws", "--endpoint-url", endpoint, "s3api", "delete-object",
"--bucket", bucket, "--key", obj["Key"]],
check=True,
)
print("deleted expired backup:", obj["Key"])
PYEOF

View file

@ -1,29 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: litellm-postgres-backup-secret
namespace: nxtgauge-ai
type: Opaque
stringData:
B2_ACCESS_KEY_ID: ENC[AES256_GCM,data:yN9jyY/mHskyNY9kuFOBxQ0BUINQxnE2fw==,iv:2sfOXDoDKdDA3fTd/9rRQMp4HkE3e7uX58Aq1RWMjuw=,tag:xX98THKq5vkcgCVHO083CQ==,type:str]
B2_SECRET_ACCESS_KEY: ENC[AES256_GCM,data:LZV5e3XQGi3Pgg8o7ffqIUP0MH5hayT3sYqkjg8dkw==,iv:9bGRz5ITzhtXu+j+02g4gpUnbyOhs0UrP/R/xJJlueU=,tag:K1LcWKHX5h9EOSBj5Q2Cng==,type:str]
B2_BUCKET_NAME: ENC[AES256_GCM,data:yP03INPoykOW3OunfHsF,iv:dEJ4okMMmh/EQXBRJeVjD1SjmL5irEQRy+3nUlFYhDY=,tag:fBJgeWexd/aBLVPFIIgRjg==,type:str]
B2_ENDPOINT: ENC[AES256_GCM,data:sMZy7lZGhlKBgeXfxgjTynpjzsLSHtWcwKjyRGhSI4l743kBnM5yCBU=,iv:tZeFK0RxNFCAbpSEW8ICQT2rgdc7ZI98vEaIHszaHr8=,tag:KcAVpgFWCorKJ9sWOucliQ==,type:str]
B2_REGION: ENC[AES256_GCM,data:t9ExTVXacRQXvWTGbRM=,iv:KMw95/jQyqpYg73NVWEomxehMa2F05R2SlVJh4V/xPQ=,tag:1L+0ykYFF7LK+9QD+os4Kg==,type:str]
BACKUP_PREFIX: ENC[AES256_GCM,data:8IsLsR5ls+dW4MvQ7KwveA==,iv:TmESoyByMxEiFZ8pi85T+Gp3P7Do3Zg7BzhUTjBr8Ik=,tag:/FUuSfg7kI6EK+WTvvE5BQ==,type:str]
RETENTION_DAYS: ENC[AES256_GCM,data:mAY=,iv:ZCld9d9vQD3goHcZ9yH0pFmvnGAGLGm1dUz+YPdptl4=,tag:N6TRLOFwPbE/ZF3/a0Y97A==,type:str]
sops:
age:
- recipient: age1sqxc53yvap8763eup99g6eza6fa5u65qetdymlh5ch4ugvvv5q0sf3pm4l
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvdjRoMzdlWlhtck9EM2FE
SXZFdG5GMDJkM2xUQjJJeHRRbWZsdjlhblZVClpPZTU1YlA2TkJ3elRQdWY3a0ds
cHNZUllxSnJDVWxBaTMzMENtNG4rZGcKLS0tIDFtUW5EZk91NFFwa2svelF4Z0dN
clZmdmtkdWJaOHVLOHlBOGIzSUtWcjQKt3I7Zar8UCsS8UfY+SGbc8nxX+PUjp0f
8PJKBFr9VahsZp7XsN6iq1qbWWdSpWlo8mlkyhxF6ZfiP/LI+N/Okg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-08-15T17:03:21Z"
mac: ENC[AES256_GCM,data:tX/IdisbNhepZ4fuaS39EJ2wEPUEpVMsTJvuKqejYLkm4fQ4TlAhyW/IE6qZIqg/PlKVE5316jFM95oW6KK4Ymeth3jglVedV0wfx7rrvkHoiJL+RtzFG4leD7UHnkHDBrhtAJzNLlQhm+uy8BKpxGU4XsAXWxCU2xqNmsuhaeE=,iv:WLdixhlKx5KmNo7xKfZc/P0ks+aS9kq55IcO/zevJTc=,tag:O3nT3OPocIn/ijhGWJaIvA==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View file

@ -1,26 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: litellm-db-credentials
namespace: nxtgauge-ai
type: Opaque
stringData:
DATABASE_URL: ENC[AES256_GCM,data:pCnOS9l7BlmxL5aDcaaulSgNxQa2M8a7uhVbnQ98k3NFNsJILkVJmALxzsufRsJhlSFAzfGR+3dSSPPrAzBzFzPMWjxOEtmKH4/9lMqRpVKYlQY=,iv:ucMlqs1WvAY7+vK93EC7NIdIOCvYgmFujZJP+VblTEU=,tag:mPm97ID7QXqJHIs+7Bp6Gg==,type:str]
DB_USER: ENC[AES256_GCM,data:DEV7RshBbg==,iv:0C2vDbjSsyyWB2ueOJSIbjflvjZaOMHp7uYcf92A+RQ=,tag:5dypXrRYgbc4yIuT9J3uDQ==,type:str]
DB_PASSWORD: ENC[AES256_GCM,data:/9hbGZMnXxqEMQ==,iv:zGPlktP7ahdY4xbhhQLKw90IwlG0rT15eBIdGmfsLYM=,tag:eazhcIWuhQJYB/ZcwD7RbQ==,type:str]
DB_NAME: ENC[AES256_GCM,data:+ZsZs4tCxg==,iv:BoySPuXGlfzVYQ6Nnco6AduRvtYSfCKSrQ7O+RCS5ew=,tag:xeUcIVRg9hEjKqVmIyd/dw==,type:str]
sops:
age:
- recipient: age1sqxc53yvap8763eup99g6eza6fa5u65qetdymlh5ch4ugvvv5q0sf3pm4l
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRQkNZdml4cnM2ZjJTSWRR
V1ptVU5CY0lMdVV4L0tNUXRJVE84ZmczcUhrCnUvdWd1bndqZWUxaUZEQkoyQzBL
NkQ2NDNPVXJVcVcwMHlML2ZxQmsvZ2sKLS0tIG5GNXhCNjhJY1BTczllY2k1aTlo
QTNnZmwwUzlDM0c1VzV6Z0hJclI1TFEKnE1Zl5FdPnO+638Whw77pSqTE0yJFHWY
eA8YPz9z3MfkNEv94aue67zClbW1rx73cc90ASvPUpMm1l4NVb9ivQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-07-02T12:17:30Z"
mac: ENC[AES256_GCM,data:a1WLtxBrW1GHHr1zg58D+pSvAHT/AYqYtXSZBAW8rkyFgU8PslzUCy7Fgs8ImhcQf3ykMGJH7rKDtG3DKqhr+VWHse0P30u3OgxfOoMIeSyWMKtlg9DWsWKpk3Eid/0iNW3XsCF/0PgORIfvEdbUkMSFlWLlXIZ4Qs4fon4YGFM=,iv:z6GbmWObIgnZ9DnHJpSx8SsAD5ukRgmboGdVwb28cMU=,tag:T/mgHx8fvtOaPP9m65ATPg==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View file

@ -1,84 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: litellm
namespace: nxtgauge-ai
labels:
app: litellm
spec:
replicas: 1
selector:
matchLabels:
app: litellm
template:
metadata:
labels:
app: litellm
spec:
containers:
- name: litellm
# This app was never included in Flux's root kustomization (see
# clusters/production/kustomization.yaml), so it was only ever
# deployed by a one-off manual `kubectl apply` and has since
# drifted from this file. Corrected to match what's actually
# running live (the real upstream image) rather than
# registry.nxtgauge.com/litellm:latest, which doesn't appear to
# exist/be maintained — using it would have broken a working
# deployment the moment this file was wired back into GitOps.
image: ghcr.io/berriai/litellm:latest
command:
- "/bin/bash"
args:
- "-c"
- "cat /app/config.yaml && exec litellm --config /app/config.yaml --port 4000 --host 0.0.0.0"
ports:
- containerPort: 4000
name: http
env:
- name: LITELLM_MASTER_KEY
valueFrom:
secretKeyRef:
name: litellm-secrets
key: LITELLM_MASTER_KEY
- name: LITELLM_LOG_LEVEL
value: "DEBUG"
# Present on the live (drifted) deployment but missing from this
# file — LiteLLM's proxy tries to reach Postgres for spend
# tracking/virtual-key storage regardless of whether
# general_settings.database_url is set in config.yaml, and
# fails startup entirely if DATABASE_URL is unset (discovered
# when adopting this file caused a crash loop: the litellm-db-
# credentials secret already existed, this file just never
# referenced it).
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: litellm-db-credentials
key: DATABASE_URL
volumeMounts:
- name: config
mountPath: /app/config.yaml
subPath: config.yaml
readOnly: true
resources:
requests:
cpu: 100m
memory: 256Mi
livenessProbe:
tcpSocket:
port: 4000
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
tcpSocket:
port: 4000
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
volumes:
- name: config
configMap:
name: litellm-config

View file

@ -1,25 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: litellm
namespace: nxtgauge-ai
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: traefik
tls:
- hosts:
- llm.nxtgauge.com
secretName: litellm-tls
rules:
- host: llm.nxtgauge.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: litellm
port:
number: 4000

View file

@ -1,12 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: nxtgauge-ai
resources:
- configmap.yaml
- secret.yaml
- deployment.yaml
- service.yaml
- ingress.yaml
- ratelimit.yaml

View file

@ -1,93 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: nxtgauge-ai
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
namespace: nxtgauge-ai
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: Secret
metadata:
name: postgres-credentials
namespace: nxtgauge-ai
type: Opaque
stringData:
POSTGRES_USER: "litellm"
POSTGRES_PASSWORD: "litellm123"
POSTGRES_DB: "litellm"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
namespace: nxtgauge-ai
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15-alpine
ports:
- containerPort: 5432
env:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: postgres-credentials
key: POSTGRES_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-credentials
key: POSTGRES_PASSWORD
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: postgres-credentials
key: POSTGRES_DB
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: postgres-pvc
---
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: nxtgauge-ai
spec:
selector:
app: postgres
ports:
- port: 5432
targetPort: 5432
type: ClusterIP

View file

@ -1,9 +0,0 @@
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: rate-limit
namespace: nxtgauge-ai
spec:
rateLimit:
average: 100
burst: 50

View file

@ -1,25 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: litellm-secrets
namespace: nxtgauge-ai
type: Opaque
stringData:
#ENC[AES256_GCM,data:TuZS4IVk6g2SXUpQWkoDALAK3ack+ekBGd24mDPJ5L0J4fQpA3zUYjcG,iv:Dox0GMeXJ0QeScAojVw6XRCprf1/YfGBaQYiT4p37eM=,tag:WSKyjkk2WPhVmR2fnxWhFg==,type:comment]
#ENC[AES256_GCM,data:1WnTc8lueif6P56qf53jReLQ2Zwowp+eNPO9zip7LBplvfc+zXrQ1HAF9g==,iv:LIXZlIOxl2VQS8Hc7MNQCh/c+RLFyhv3ppiY9ngYOEY=,tag:ozEMau2Qa6/vxq02lBCtbA==,type:comment]
LITELLM_MASTER_KEY: ENC[AES256_GCM,data:AKcD37IsUX77Fewg8AdklrJ+s88WdeFMMwmxERY=,iv:Sq1YbOQl4Q2A6d2uuB2lKl61qHTwwWf3KrYB8uFE36A=,tag:hjndpCamkXw5SjaSS4QA9Q==,type:str]
sops:
age:
- recipient: age1sqxc53yvap8763eup99g6eza6fa5u65qetdymlh5ch4ugvvv5q0sf3pm4l
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrMElxRmFvWkNsc2pLMldG
SnNsaSsza2FpbUlkMG1RZGZJOWhrNmlwRG1vClhRL3phOGlSQmxEVmZWaTNEUFB1
bFFtemFNbFpMTlQyWVVhWFNLZlZtNTAKLS0tIGlwRjdGTHBtVlZKRkpwTVZaTjY1
Vmthb3FHR2xjUGRZZGxvci9ybHJ0WDgKIer4ERUBD+go3E19pvdb/zn75PrwVa3n
2bbLDG0clSu7KuaGdZh5AcNQTbl16sjiQxmxzqYIKib7neQBjDH3Kw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-07-02T12:17:30Z"
mac: ENC[AES256_GCM,data:bCslBTumwUUk/wz0yfrdxRsucx/j4Ij/uO9RVE2b8bgKualJ0KYiN6kfgUpylTW0G67pslU1/eGkOcmG4/eYVmwIAn2m4MZ/ni7/0YZ/DoRQFqujscr2/sWYZi1LEtroj8jTEW+3Nw2g6Z0SobEoN2s+V8MrVgPR1Z7BCnvvE/g=,iv:ZGqA7pqhpwU2jYi8/dslaHtDYvrclc6UWbhHv922wYk=,tag:M1S63XwixHXij7RrHE+JGA==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View file

@ -1,15 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: litellm
namespace: nxtgauge-ai
labels:
app: litellm
spec:
type: ClusterIP
ports:
- port: 4000
targetPort: 4000
name: http
selector:
app: litellm

View file

@ -1,11 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: nxtgauge-ai
resources:
- ../../base
# Overrides the placeholder LITELLM_MASTER_KEY from base/secret.yaml via strategic merge.
patches:
- path: secret.yaml

View file

@ -1,23 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: litellm-secrets
namespace: nxtgauge-ai
type: Opaque
stringData:
LITELLM_MASTER_KEY: ENC[AES256_GCM,data:cY9TuaFw5lS33WupTrWN4MrLtj9eGCZWwKsWjfU6xvLfksb8fZSxBuy3te9iA2scQFpkAaTtHfc0d3BqhfB/f/kQfUZWqpXNI53x4jhQ5cQ=,iv:JDL+6l1LvjdeCPFZ0uRNMxl8bZ2Hma45OnMADHcQImQ=,tag:u+icxo/y18YcRuwHHQzWSQ==,type:str]
sops:
age:
- recipient: age1sqxc53yvap8763eup99g6eza6fa5u65qetdymlh5ch4ugvvv5q0sf3pm4l
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBySEpkalRaaWczNHpDbTI0
UUlZNWtiZlIxcWs1TDJSUTBuek44YjB5bENrCk5qMThoT2hEa3QvWHVWMGpLWW8w
aGVSTVhrVmNCdzhmZGUvS3Y1UENTRjQKLS0tIHd3aW9MaEpRUFJ0QkUzR2ZHVE1D
ZDNjMEtDUTFYWXA1NkdFNTVia2hQNVkK1yb+LQtESLOo30KWHxpahlV6V0AL7R98
/lxtOCj50zlknAhPKbQg/TSyvHHqbx0TAiEs6xG0R1OUnqTxI/kKfw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-07-02T12:19:43Z"
mac: ENC[AES256_GCM,data:RsTBxbfUtXZtAQp5KRl7YPbagNopbK2upzIOZLrotDgra2QShwllhTOCGcm0x4F3xz+G/yeOYq8g22/p/D/buy/voIz8Z/r9F06OIblc8fO8HaEibJfI1rRf3a2I+wRAmnltMmtdMyp3YN7y9/uAsbIra4iBkVOjcJ5HCE509ug=,iv:BobfQK4ldBupRf5VPc8Vaki+uaiHB1eEmc/UZ6tsUeo=,tag:CQyHEZ+HfwxpvVIkus9BpA==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View file

@ -15,11 +15,9 @@ spec:
labels:
app: nxtgauge-admin-solid
spec:
imagePullSecrets:
- name: forgejo-regcred
containers:
- name: admin-solid
image: ci.nxtgauge.com/ashwin/nxtgauge-admin-solid
image: registry.nxtgauge.com/nxtgauge-admin-solid
imagePullPolicy: Always
ports:
- containerPort: 3000

View file

@ -1,27 +1,12 @@
apiVersion: v1
kind: Secret
metadata:
name: nxtgauge-admin-solid-secrets
namespace: nxtgauge
name: nxtgauge-admin-solid-secrets
namespace: nxtgauge
type: Opaque
stringData:
SMTP_HOST: ENC[AES256_GCM,data:6IGeRaJzzQ3fkX4jVVZ36mg=,iv:8H4BAFFoMd190M4q/85bEffL6yzdBaDjreF/X0xz2aU=,tag:nX+MUmTMYYK1rByglsMjUw==,type:str]
SMTP_PORT: ENC[AES256_GCM,data:s4aS,iv:e5ySOAp00lv8JKYA7+FZgl4naWyoHxBIfnySELQGPdo=,tag:Ofg0gkNGPEG77lOVWvbgmw==,type:str]
SMTP_USER: ENC[AES256_GCM,data:ijOeJ+2xZw0ire4=,iv:jP//72BqKjlYzreXG8oQVgeH0BHT3dxBaXpzKgBBYZ4=,tag:Sue0Eje/HbARTncl3V/UEg==,type:str]
SMTP_PASS: ENC[AES256_GCM,data:uGJFVFarFTVJFfvhdQYiQB+/4jPigE7xNNgYenJt4jpuF8UhMOuM3zuvZ+1x0QlMdYG/Og5SgC/RuHMhrbrNS3YbbJaC2eZjTurH2xyvY6iLLdLQHmcdGR7sCFsyoQ6IZybUrcd+DTCy1safsJm0Mh0fhZEBPq1qWsMZUolswsLj7TFsiXHDiG+ZU/AKHCn1,iv:LY38BvW3CrIfLhflq04X+bCgR4AP8c+VzW3Alpl7zFk=,tag:YIcGD3QViiGcGSAqk0HeyQ==,type:str]
SMTP_FROM: ENC[AES256_GCM,data:bfZgeNSLquqOhtCRlOXPesI8K9o=,iv:n9ApxTDgCG8zWZwEievDPzOGMIIxlFhV2CaL0FHs0mU=,tag:nrk5coQvWgZgslEnSmXQJw==,type:str]
sops:
age:
- recipient: age1sqxc53yvap8763eup99g6eza6fa5u65qetdymlh5ch4ugvvv5q0sf3pm4l
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByUDRidXo3VHJWT2N3Y2Zz
eW1oMXJEb3FPNm1mOHVXOG1HWnRHSHB5UFQ4Ck4rSkc4ZXhyTEtCbWI4YkpKS1Vv
SUt4eG0rWHJUN2hyc2RaQ1VLUzJYQUUKLS0tIEkrSUFVQU1ubk9iRTQxWW9RclF6
VEdhdGdLV0U2c09idHNySVRWd2s2OTAKD2X/8Elyrl1X99JRwKZXe8nQvz92UuvU
fnlqzdjCWaHyd4Ib9t8WjLw5Hm+qLluZpci7UqJaQX9OAN2+HGC8Sg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-07-02T12:17:30Z"
mac: ENC[AES256_GCM,data:OsdePD6gejqfmJck8JCkoRx2iztrQQ2GQQ99jXNYfnRIe0Mx8BHH4fpUQRT853Wr2tjQq0V9Vl8B0uQC05aCnBIhpOExg7Oyq+fm0FC0PmzkcyNsZjspIoux3UqsXh6aXfjaeL9/szCsdwlXplaMWdisibTgQYwt86zEieOPDFE=,iv:x0mEf7r50m089Vnn2VVfyCHBWwuhXce25deJ+TJOnBo=,tag:YocuQO6IzgcKfVrNbSbT7A==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2
SMTP_HOST: "smtp.zeptomail.in"
SMTP_PORT: "587"
SMTP_USER: "emailapikey"
SMTP_PASS: "PHtE6r1ZR+zi3jV88RNW4/O4F8CkPdksqO9iJAhA4YcTD6dQFk1S+dl/wDC3/h97AKYWFfSczo1rt72etOuDLTnrMjlEDWqyqK3sx/VYSPOZsbq6x00esVgYdEfYVYDpcNFj3SPQut7dNA=="
SMTP_FROM: "support@nxtgauge.com"

View file

@ -1,7 +1,9 @@
apiVersion: kustomize.config.k8s.io/v1beta1
namespace: nxtgauge
kind: Kustomization
resources:
- ../../base
patches:
- path: release-patch.yaml
patchesStrategicMerge:
- replicas-patch.yaml
images:
- name: registry.nxtgauge.com/nxtgauge-admin-solid
newTag: high-performance-latest

View file

@ -1,12 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: nxtgauge
name: nxtgauge-admin-solid
spec:
replicas: 1
template:
spec:
containers:
- name: admin-solid
image: ci.nxtgauge.com/ashwin/nxtgauge-admin-solid@sha256:b471288dbf2ea3fac545ea69fa6c0db4890e736cf12c3647205019458692a4a2

View file

@ -0,0 +1,7 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-admin-solid
namespace: nxtgauge
spec:
replicas: 1

View file

@ -14,11 +14,9 @@ spec:
labels:
app: nxtgauge-ai-assistant
spec:
imagePullSecrets:
- name: forgejo-regcred
containers:
- name: ai-assistant
image: registry.nxtgauge.com/nxtgauge-ai-assistant:2f999dfe95a48ea4090a90519dc3950f1e729924
image: registry.nxtgauge.com/nxtgauge-ai-assistant
imagePullPolicy: Always
ports:
- containerPort: 8080
@ -34,29 +32,13 @@ spec:
value: "gemma3:270m"
- name: OLLAMA_EMBED_MODEL
value: "nomic-embed-text"
- name: LLM_PROVIDER
value: "litellm"
- name: LITELLM_BASE_URL
value: "http://litellm.nxtgauge-ai.svc.cluster.local:4000"
- name: LITELLM_MODEL
value: "askash-main"
- name: LITELLM_API_KEY
valueFrom:
secretKeyRef:
name: litellm-secrets
key: LITELLM_MASTER_KEY
- name: NXTGAUGE_USERS_URL
value: "http://nxtgauge-rust-users.nxtgauge.svc.cluster.local:9101"
value: "http://nxtgauge-rust-users:9101"
- name: AI_SERVICE_KEY
valueFrom:
secretKeyRef:
name: nxtgauge-ai-assistant-secrets
key: ai-service-key
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: nxtgauge-ai-assistant-secrets
key: jwt-secret
resources:
requests:
cpu: 100m

View file

@ -1,25 +1,10 @@
apiVersion: v1
kind: Secret
metadata:
name: nxtgauge-ai-assistant-secrets
namespace: nxtgauge
name: nxtgauge-ai-assistant-secrets
namespace: nxtgauge
type: Opaque
stringData:
#ENC[AES256_GCM,data:DzWkRm3f8tFc02M5GVMtvWxLscWMt/AsTW7U0+KenEDguLPOGZjSqTflKwlP11V7v7p3bCkvpmKFvRq3B8Qi0g3zzp0Q,iv:TA8ADbjVM5gw8zc6Synn/Ue6BT8k/PUtyvoNrXEgzd4=,tag:rhFeomxaYhX+pWmKjYW3fQ==,type:comment]
ai-service-key: ENC[AES256_GCM,data:FjKo1h5loCYoXDOC4g37tLTbLU7lE+DewxMkUCXBO5op0tJByaXmBYy5ZZEDpplZxDsEPd4QiKoUg8bM9+2OSA==,iv:I//s3r9wSQujgtXPeFT1IArzu2LbObsFz7d8E0GN6iU=,tag:PkLaujtLklCWHQYGIB9uvQ==,type:str]
jwt-secret: ENC[AES256_GCM,data:yvyOL2w2QBq0yLz2UNf1YlqFpFX522j60h/lGGcjbEPgloYs1W7hAbPBfRsR//tySNRwR24PY5FcR2NPOFxqTg==,iv:JNPrJaCLgQb/JK7FIIy/hn3TwAmSmGj0N9oWtf5yI3w=,tag:cQp4ovPxyrCrF/ON+bmJkQ==,type:str]
sops:
age:
- recipient: age1sqxc53yvap8763eup99g6eza6fa5u65qetdymlh5ch4ugvvv5q0sf3pm4l
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWQWU2UU13Z3dFcFFqeU9J
NThoMVE4UW5jeHFQaE9tY0p2aGliU3EyMVZrCng4RGhGbDVYM1M5WFdZZ3M5Tk1S
NldkdXRSS2dqckpvNUo5d1hqYUZLWE0KLS0tIGUzV2pqbW5ScEllbVBDeG1KNFJB
ckFFMndObTNzaFpyUVU5OTZOTUNiQXcKDPo+nnHRjPlswzW1WHQEde8Ae/icAsxH
+aq9NUpDQ8FTCdIu0rtqVS1VaEyt1kXgBmrjHIJCIVVvFzTKfuXLGA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-07-02T12:29:46Z"
mac: ENC[AES256_GCM,data:sEa957jGG3/hm+B13txCB18JdvOweUnfEf4rrtstzNrP1fnlwJl1/trWP72WDGyTPbY6t6Rh8XYeML8j7rgVjHowlkQdyXk6GTknUjDgwVQd/5mnDPwO9U6SGA5DM9SS49khcDcxvz4AqlAGTLT/l7EOymavwSLomkw4OOxEX3I=,iv:JBHSCDD/2u/xHViFlTJIXbeGkLldgFDGfAvDdqoMyjc=,tag:jrljvtbPEEOzFfAhYMIHCQ==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2
# TODO: set to the shared key expected by callers of the AI assistant.
ai-service-key: ""

View file

@ -1,7 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
namespace: nxtgauge-ai
kind: Kustomization
resources:
- ../../base
patches:
- path: release-patch.yaml
images:
- name: registry.nxtgauge.com/nxtgauge-ai-assistant
newTag: high-performance-latest

View file

@ -1,11 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-ai-assistant
spec:
replicas: 1
template:
spec:
containers:
- name: ai-assistant
image: ci.nxtgauge.com/ashwin/nxtgauge-ai-assistant@sha256:1571b2ce6b518a431e268c6fd5f39bf2774c8aa584362519bb02ecf2b2fdaebb

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-catering-services
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: catering-services
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-catering-services:latest
image: registry.nxtgauge.com/nxtgauge-rust-catering-services:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9115
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9115"
readinessProbe:
httpGet:
path: /health

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-companies
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: companies
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-companies:latest
image: registry.nxtgauge.com/nxtgauge-rust-companies:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9102
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9102"
readinessProbe:
httpGet:
path: /health

View file

@ -10,6 +10,7 @@ data:
USERS_SERVICE_URL: "http://nxtgauge-rust-users:9101"
COMPANIES_SERVICE_URL: "http://nxtgauge-rust-companies:9102"
JOBS_SERVICE_URL: "http://nxtgauge-rust-jobs:9103"
LEADS_SERVICE_URL: "http://nxtgauge-rust-leads:9118"
JOB_SEEKERS_SERVICE_URL: "http://nxtgauge-rust-job-seekers:9104"
CUSTOMERS_SERVICE_URL: "http://nxtgauge-rust-customers:9105"
EMPLOYEES_SERVICE_URL: "http://nxtgauge-rust-employees:9106"
@ -26,4 +27,3 @@ data:
UGC_CONTENT_CREATORS_SERVICE_URL: "http://nxtgauge-rust-ugc-content-creators:9117"
OLLAMA_BASE_URL: "http://ollama.nxtgauge-ai.svc.cluster.local:11434"
OLLAMA_CHAT_MODEL: "gemma3:270m"
BEECEPTOR_URL: "https://nxtgauge.free.beeceptor.com"

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-cron
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: cron
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-cron:latest
image: registry.nxtgauge.com/nxtgauge-rust-cron:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
envFrom:
- configMapRef:

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-customers
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: customers
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-customers:latest
image: registry.nxtgauge.com/nxtgauge-rust-customers:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9105
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9105"
readinessProbe:
httpGet:
path: /health

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-developers
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: developers
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-developers:latest
image: registry.nxtgauge.com/nxtgauge-rust-developers:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9110
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9110"
readinessProbe:
httpGet:
path: /health

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-employees
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: employees
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-employees:latest
image: registry.nxtgauge.com/nxtgauge-rust-employees:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9106
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9106"
readinessProbe:
httpGet:
path: /health

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-fitness-trainers
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: fitness-trainers
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-fitness-trainers:latest
image: registry.nxtgauge.com/nxtgauge-rust-fitness-trainers:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9114
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9114"
readinessProbe:
httpGet:
path: /health

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-gateway
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: gateway
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-gateway:latest
image: registry.nxtgauge.com/nxtgauge-rust-gateway:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9100

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-graphic-designers
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: graphic-designers
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-graphic-designers:latest
image: registry.nxtgauge.com/nxtgauge-rust-graphic-designers:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9112
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9112"
readinessProbe:
httpGet:
path: /health

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-job-seekers
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: job-seekers
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-job-seekers:latest
image: registry.nxtgauge.com/nxtgauge-rust-job-seekers:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9104
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9104"
readinessProbe:
httpGet:
path: /health

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-jobs
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: jobs
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-jobs:latest
image: registry.nxtgauge.com/nxtgauge-rust-jobs:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9103

View file

@ -14,6 +14,8 @@ resources:
- companies-service.yaml
- jobs-deployment.yaml
- jobs-service.yaml
- leads-deployment.yaml
- leads-service.yaml
- job-seekers-deployment.yaml
- job-seekers-service.yaml
- customers-deployment.yaml

View file

@ -0,0 +1,56 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-leads
labels:
app: nxtgauge-rust-leads
spec:
replicas: 1
selector:
matchLabels:
app: nxtgauge-rust-leads
template:
metadata:
labels:
app: nxtgauge-rust-leads
spec:
imagePullSecrets:
- name: regcred
containers:
- name: leads
image: registry.nxtgauge.com/nxtgauge-rust-leads:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9118
name: http
envFrom:
- configMapRef:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9118"
readinessProbe:
httpGet:
path: /health
port: 9118
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
livenessProbe:
httpGet:
path: /health
port: 9118
initialDelaySeconds: 20
periodSeconds: 20
timeoutSeconds: 3
failureThreshold: 5
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 500m
memory: 256Mi

View file

@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: nxtgauge-rust-leads
namespace: nxtgauge
labels:
app: nxtgauge-rust-leads
spec:
type: ClusterIP
selector:
app: nxtgauge-rust-leads
ports:
- name: http
port: 9118
targetPort: 9118
protocol: TCP

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-makeup-artists
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: makeup-artists
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-makeup-artists:latest
image: registry.nxtgauge.com/nxtgauge-rust-makeup-artists:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9109
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9109"
readinessProbe:
httpGet:
path: /health

View file

@ -39,13 +39,11 @@ spec:
ok="false"
fi
payload="$(printf '[{"endpoint":"%s","url":"%s","status_code":%s,"ok":%s,"latency_ms":%s,"checked_at":"%s"}]' "$name" "$url" "$code" "$ok" "$latency_ms" "$checked_at")"
if ! curl -sS -X POST \
curl -sS -X POST \
"${OO_ENDPOINT}/api/${OO_ORG}/${OO_STREAM}/_json" \
-H "Authorization: ${OO_AUTH_HEADER}" \
-H "Content-Type: application/json" \
-d "$payload" >/dev/null; then
echo "openobserve post failed for ${name}" >&2
fi
-d "$payload" >/dev/null
}
post_result "frontend" "https://test111.nxtgauge.com/"

View file

@ -1,26 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: nxtgauge-openobserve-endpoint-monitor-secret
namespace: nxtgauge
name: nxtgauge-openobserve-endpoint-monitor-secret
namespace: nxtgauge
type: Opaque
stringData:
OO_ENDPOINT: ENC[AES256_GCM,data:AS2JCqQO8nKWY5CxK4K8RnfTShgmcETKBU6bo5KYhGX29HZ9S0svPgr7N8f2n2ukP79yxNJhRgoj1g5IHylrcOWHkg==,iv:rCXp7P/KD3OjNey2R4C1mIV1mwJloXY1b3cidQZDsq4=,tag:w1yHshbQAo97IJotL9N40Q==,type:str]
OO_ORG: ENC[AES256_GCM,data:Wr0KPRa6kA==,iv:+vF9x/yTmqsg6vK5cHucLURktlcY0qP/NpoFnF0YuKI=,tag:n0vpNEoNzeVKzCJ44IBXGQ==,type:str]
OO_STREAM: ENC[AES256_GCM,data:ihLyiAbqfZtDstT6aFrh9QUg,iv:V4PkyKL9PSD2k7o+Od7t7q4g3o38mqbPPxZ87YGQAvY=,tag:m3AAVpaI6WwSSkw86pEsUw==,type:str]
OO_AUTH_HEADER: ENC[AES256_GCM,data:VY7qW13SLjUVMb21dsUpKpMZU00QSGAI1oCJHfTC8wxatuw0js4+fwyfLhJk/5ejBV8=,iv:62O+daUXn6OoJ0xiZ6iNTYAOVEI/2phGm4EYsUG/ENc=,tag:/5LXx1a/tG442LPuJCwYnQ==,type:str]
sops:
age:
- recipient: age1sqxc53yvap8763eup99g6eza6fa5u65qetdymlh5ch4ugvvv5q0sf3pm4l
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvWjByejZNaUo0TmVRWnpY
WUpHS3hNeUZ5VnNGNjZ0RXZXZmd3QVdjV1dvCnArSktlaGp0Y0RuUzJTMThsZzhE
aXBQZGRkZDRQM01HOThnamJwY2JGbWsKLS0tIG84ODMybWc5cVZ6TGRLQTRGOU4x
Zm5aZHpmQVU0djB2RkxiOERVRStrclUKgd9O6ldUlge0Kop14t4jUVidQIRfmLzg
+Ci3LgedKLE1Lxbwg9JbTpA9YkVucnLuHPbUYZrud91jn1jnkw6plg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-07-02T12:17:30Z"
mac: ENC[AES256_GCM,data:vAHLnc8tTNxmMnZs66H2MPxjvVpdquV8VYFD9DvWE/cIEEcZLrXtF6F5Nrcn5CSOurWKJoSQKV+s8DZQvuocc5cS5i8QvxSNyj1pcK+JzTUdMoDFY/xwqvVS3tIQn29Cocx2TEU+XUYB0zTVKRYGZjaQEgRquXZmGXCPaPzZvso=,iv:qkieUNf/khdlOArHPFo96x864XufRO8z9xA9HQzTt08=,tag:4PiiRm5F/hicDrTX9PigsQ==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2
OO_ENDPOINT: "http://o2-openobserve-standalone.openobserve.svc.cluster.local:5080"
OO_ORG: "default"
OO_STREAM: "nxtgauge_endpoints"
OO_AUTH_HEADER: "Basic cm9vdEBleGFtcGxlLmNvbTpDb21wbGV4cGFzcyMxMjM="

View file

@ -64,6 +64,8 @@ spec:
err = str(e)
except Exception as e:
err = str(e)
if name == "registry-svc" and status in (200, 401):
ok = True
latency_ms = int((time.time() - start) * 1000)
return {
"kind": "endpoint",
@ -75,7 +77,7 @@ spec:
"error": err,
}
now = datetime.datetime.now(datetime.UTC).replace(microsecond=0).isoformat().replace("+00:00", "Z")
now = datetime.datetime.utcnow().replace(microsecond=0).isoformat() + "Z"
records = []
nodes = kube_get("/api/v1/nodes").get("items", [])
@ -133,7 +135,9 @@ spec:
("frontend-svc", "http://nxtgauge-frontend-solid.nxtgauge.svc.cluster.local/"),
("admin-svc", "http://nxtgauge-admin-solid.nxtgauge.svc.cluster.local/"),
("api-gateway-svc", "http://nxtgauge-rust-gateway.nxtgauge.svc.cluster.local:9100/health"),
("flux-source-controller", "http://source-controller.flux-system.svc.cluster.local/metrics"),
("registry-svc", "http://docker-registry.registry.svc.cluster.local:5000/v2/"),
("woodpecker-svc", "http://woodpecker-server.woodpecker.svc.cluster.local/"),
("argocd-metrics", "http://argocd-server-metrics.argocd.svc.cluster.local:8083/metrics"),
("openobserve-svc", "http://o2-openobserve-standalone.openobserve.svc.cluster.local:5080/healthz"),
]
for name, url in endpoints:
@ -168,8 +172,5 @@ spec:
},
method="POST",
)
try:
with urllib.request.urlopen(req, timeout=30) as resp:
_ = resp.read()
except Exception as exc:
print(f"openobserve post failed: {exc}")
with urllib.request.urlopen(req, timeout=30) as resp:
_ = resp.read()

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-payments
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: payments
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-payments:latest
image: registry.nxtgauge.com/nxtgauge-rust-payments:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9116
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9116"
readinessProbe:
tcpSocket:
port: 9116

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-photographers
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: photographers
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-photographers:latest
image: registry.nxtgauge.com/nxtgauge-rust-photographers:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9107
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9107"
readinessProbe:
httpGet:
path: /health

View file

@ -1,41 +1,23 @@
apiVersion: v1
kind: Secret
metadata:
name: nxtgauge-backend-rust-secrets
namespace: nxtgauge
name: nxtgauge-backend-rust-secrets
namespace: nxtgauge
type: Opaque
stringData:
DATABASE_URL: ENC[AES256_GCM,data:R3qHCG6cS6DTvQ8JdlqK7mkk23VSy82HROYoW5dyQ2B0ZCloh5ht6Kxq3MXph2ajVAm6PFrejkt6KD4GDSUa9kj1F2pgwQZFsALSyymO9bsxi1KUBmP/WoG6WAH+Un0mq76S+S3XWR2Jdd2miT8Fhw9n7wI=,iv:Is4R3J1GvTIPhOR6Cz3SYQ3we/tUVdCckmrLp18SnMo=,tag:lDmQwWo5jJ66zn7uncmulw==,type:str]
JWT_SECRET: ENC[AES256_GCM,data:/SbAXJE3u6kJJfL3Go2JoRwmZt8P0MGV7gYtcpYzE4TSjpLqcVB4PpclrzkxzUt4N8omnOXepousmqSFx0fFiQ==,iv:/+q2UFxNYlagHMynYr1cNWY/MUPek3iVj88Ml3pSSe4=,tag:zNqpr3ZfLGFmqLZVDp14tg==,type:str]
#ENC[AES256_GCM,data:NwWD9qcBt10NLznH1CtFS7jHkMrAECU50KRfBXYfa5ps0RwcNtlGEK5LhxmhNF7Hj+8wN3vRQm31,iv:H6VG1AluCHNINR43oLOfaRXm8N7NhGHGbHp8AZhxO74=,tag:yVGvSzFGkmImKD0+9+vfvQ==,type:comment]
REDIS_URL: ENC[AES256_GCM,data:/CpLZLe197yAFJupL9imWhxtYEs3hIR2iuOxmPHwxnfzyInUltmt20t7215ESGgzraW1nP11+YCxvdqm0zFsxPTv68frFToxp03/2zPxinvwXfFg6uOoZ2W8eGKR,iv:rqaJRVi+5NCy1h1qtljCu13pYme2k2cZ0WucE0CfhOY=,tag:7pJcXZKKcPSo41Jyomjf1Q==,type:str]
SMTP_HOST: ENC[AES256_GCM,data:UrDtzbTtJrIpmsZyU+7I8Fs=,iv:Q2NhRYNEmkeS162BM+ro7KLIv3ybm7Eb3LAd1huOBCI=,tag:OqrIXU4JMWErWzDEoWbEKA==,type:str]
SMTP_PORT: ENC[AES256_GCM,data:SyZ7,iv:IdH6laFQKD0ldeb/jgC+RC/zWX2pfYIo8l6I+a4CmA4=,tag:QIMt0DTq/UrE9+R27kx0Kg==,type:str]
SMTP_USER: ENC[AES256_GCM,data:Kx2A9tjXOWuta/Q=,iv:y4YGN0Tg+94Tpc1BG9vSp4Z77kkOREraXfggkJ4umYs=,tag:DiuETUlGzAHYuq6dRMzNlQ==,type:str]
SMTP_PASS: ENC[AES256_GCM,data:z96REIjbLfwA6Sh1bRBgD1xobNjwLJPecr9OilI9c+ROQD/gzpfaOc/0mmDSN2kYJpyuIY5BGMzDSwtP+hesQzQ/a6MNrelh08JAY96CZnaqbXhzZCjTbHmB/DoSnC3UDoChjoNL6F7Q4L5I1gRVkwGtuyEfTCiKwHEYLrY94iKsuWso86Tga+B8DfhMnAvI,iv:+oF81kyGLzM8Yspb7HOdOI2UDtYpDiqmalw+4f8W2F4=,tag:kG9g9wMx4JCEc650kyZO8A==,type:str]
SMTP_FROM_NAME: ENC[AES256_GCM,data:xTByiZiSRjk=,iv:gqkEHwOJkfFHdzNBK5Hx9s65YZZsNS8OtOfcAQYsOkE=,tag:+7QHKYjOQaFiOWMMzO0A1g==,type:str]
SMTP_FROM_EMAIL: ENC[AES256_GCM,data:hvP00nyhduBnWP9tS6suYtde9S4=,iv:EnP+eSSqfkeddKjlp6VlpZwFH8XZcBjk4XAg8omoJMA=,tag:xwM54O2iY0/3HrliIC87Mg==,type:str]
SMTP_SECURE: ENC[AES256_GCM,data:6mW7rpQ=,iv:9ONifzX5N1YyfWvFTNMJiGKyV25auoiKXFVWd45gDxQ=,tag:UCOpQczeDGDgJ326tFwEtw==,type:str]
B2_BUCKET_NAME: ENC[AES256_GCM,data:L+sRHOxaeicvmSGcyNDR,iv:UMbs+CkgygKm6FhmHA0fyFflUnqAypV5ZQZOQSRqQhc=,tag:d8F6YQGp+Y+EPx91mgjoBA==,type:str]
B2_REGION: ENC[AES256_GCM,data:luhXJET9s1pePd35RMY=,iv:0pe4qXPmr20MbF/LIg1v2fgTwHQRQrDmVI5NfuSe+TM=,tag:L1C1jGcNiqOOSRoJi5xWxQ==,type:str]
B2_ENDPOINT: ENC[AES256_GCM,data:gS8Mfhi9js8/V7VyzZxd1L1wTFz4Qj8+OYRd1gAm24qz,iv:NJL0FO6QY/eXsmZOi0hdJ2U24U3rdfCQ2hDSJhbx9aI=,tag:uwxHGolwss36llXWvCIvMw==,type:str]
B2_ACCESS_KEY_ID: ENC[AES256_GCM,data:igIgrTUQOv4k7WlOA8C5ieb/IBnA3jEmxw==,iv:17jBEpfKpk8CH3UfBQH4klrI5h5CroB3ok5yi/kpmKk=,tag:AArkjTemJHXQL24cA5GIZg==,type:str]
B2_SECRET_ACCESS_KEY: ENC[AES256_GCM,data:xjjtDOV5CH+VMegjaRxofoSch8TpGXI2u9wR80Wl/Q==,iv:VHCUeZMQMjub5o/74e+dd3Src/T3GDs55N7w3xy5JA8=,tag:xGzvtDJJOhLeANp9dDqX3w==,type:str]
AI_SERVICE_KEY: ENC[AES256_GCM,data:ivhSxI1Rvh/5nfe+1R5GFjCbZIzk2Tm58Fi3PpayPWASQR/KNj74kM6MIXg6MtSgJ4ZDKIJ9ZJOGdYPyacRV9A==,iv:KKMfdJGKReYsVGf55Hs3tyInQ761AJ5bhaUfqPY5fpM=,tag:jGmhwI6xxqM5U4oX5Ork6g==,type:str]
PAYU_MERCHANT_KEY: ENC[AES256_GCM,data:EFqfCnQ1SnyCF60IWLFiRwN+zltPQAGiQ53tpwHQ1f9ikzLEJ++CIh8NEzRD5xz8LbfLnGQ7yj9X3tYwbXUPiQ==,iv:sRbzqQyXd0wJDSHPDkilyBP2BHzcA8YZoaQaBa4kWDU=,tag:FH9AV+zayS8PglligeeFMg==,type:str]
PAYU_SALT: ENC[AES256_GCM,data:MydVCaI5,iv:l8aq0pirxcnLYRm0M0yvpmE/lx5r6c9UlrgXvWp2MQM=,tag:WUC1M/2cla0u9tXUMKhZUw==,type:str]
sops:
age:
- recipient: age1sqxc53yvap8763eup99g6eza6fa5u65qetdymlh5ch4ugvvv5q0sf3pm4l
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1VmtFRTFKQmd6dzF6L1R6
MytrL2pNZ2hmQmVVVmZXbHA5Ri9SVC83QndnCmFVQkVpdTA4WHZnMzFCa1pRc3p1
akxJMEtRQkZpSmVvWFhmc1IxeDhiUGMKLS0tIDcyamQrU2dZSHU3UG5aMnRZdmdW
WFk2VkFuaVIxU21wOXlNZy9wL2hPWFkKIs9G/0ah7ng9BqLd3pAQE4wPEhCz601p
fcHXdDkFdNlAwZK5cp1pV4FtZnudl71lRIWEUzb7vXubeaGExQDuFw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-07-26T17:29:17Z"
mac: ENC[AES256_GCM,data:NayJKUb4FRTn+8WI7QGdmd6iqElfpLtWvWTN1SGRfGkK+VQeNMjxgs8kbwpaaLlqfaRETZXvATF1T3r5g4B2u95w7c/hAHILAgy1lhhobnH0JwPkjYRMIEQzP/hikUgW4HoDp/eJL1o7k5MH8IGWj521MU74B2isuCnDhbRdcUw=,iv:5pbmOEckMERW5U3t4EtCrQDHAVY2Fjq8AyhQremHI8I=,tag:Bmtt1OaeBC8SCQ8fMvcbJA==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2
DATABASE_URL: "postgresql://postgres:chandan2026%401@pg-postgresql.data.svc.cluster.local:5432/nxtgauge"
JWT_SECRET: "bPU0RQ/N7JW8CDCioe6AFBw/lBLTm++pGtta20pcsTX36p3OyheplgUyiD66OCuV"
# Password contains '@', so it must be URL-encoded as %40.
REDIS_URL: "redis://:chandan2026%401@redis-master.data.svc.cluster.local:6379"
SMTP_HOST: "smtp.zeptomail.in"
SMTP_PORT: "587"
SMTP_USER: "emailapikey"
SMTP_PASS: "PHtE6r1ZR+zi3jV88RNW4/O4F8CkPdksqO9iJAhA4YcTD6dQFk1S+dl/wDC3/h97AKYWFfSczo1rt72etOuDLTnrMjlEDWqyqK3sx/VYSPOZsbq6x00esVgYdEfYVYDpcNFj3SPQut7dNA=="
SMTP_FROM_NAME: "NXTGAUGE"
SMTP_FROM_EMAIL: "support@nxtgauge.com"
SMTP_SECURE: "false"
B2_BUCKET_NAME: "nxtgauge"
B2_REGION: "eu-central-003"
B2_ENDPOINT: "s3.eu-central-003.backblazeb2.com"
B2_ACCESS_KEY_ID: ""
B2_SECRET_ACCESS_KEY: ""

View file

@ -3,3 +3,5 @@ kind: ServiceAccount
metadata:
name: default
namespace: nxtgauge
imagePullSecrets:
- name: regcred

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-social-media-managers
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: social-media-managers
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-social-media-managers:latest
image: registry.nxtgauge.com/nxtgauge-rust-social-media-managers:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9113
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9113"
readinessProbe:
httpGet:
path: /health

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-tutors
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: tutors
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-tutors:latest
image: registry.nxtgauge.com/nxtgauge-rust-tutors:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9108
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9108"
readinessProbe:
httpGet:
path: /health

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-ugc-content-creators
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: ugc-content-creators
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-ugc-content-creators:latest
image: registry.nxtgauge.com/nxtgauge-rust-ugc-content-creators:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9117
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9117"
readinessProbe:
httpGet:
path: /health

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-users
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: users
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-users:latest
image: registry.nxtgauge.com/nxtgauge-rust-users
imagePullPolicy: Always
ports:
- containerPort: 9101

View file

@ -15,10 +15,10 @@ spec:
app: nxtgauge-rust-video-editors
spec:
imagePullSecrets:
- name: forgejo-regcred
- name: regcred
containers:
- name: video-editors
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-video-editors:latest
image: registry.nxtgauge.com/nxtgauge-rust-video-editors:e6d85ffc8367885050b9434494f291724cc523c0
imagePullPolicy: Always
ports:
- containerPort: 9111
@ -28,9 +28,6 @@ spec:
name: nxtgauge-backend-rust-config
- secretRef:
name: nxtgauge-backend-rust-secrets
env:
- name: PORT
value: "9111"
readinessProbe:
httpGet:
path: /health

View file

@ -1,19 +0,0 @@
gateway sha256:f3e8780a1da3f847a9a9a5f22104d821caa9e88dba73826c171d1d95f4ebfa34 2
companies sha256:a775a7bcea26c6ed23ea26cc80ab1020ecef074d97ae49e4413130078618603d 1
users sha256:346b6ed0098af13e82982ff008023f7aec9eeb434b0d721e14802e3c9c6caaed 1
jobs sha256:52cee97cdea043dcb7665b44ab575bbd4ed5b89516131e31c2779c4b986c2ae5 1
job-seekers sha256:b4035f07e40e052c560f1efdbcddd9c2853e5d1874f3a20ca365192e3568c42b 1
customers sha256:8d52c9d82615f8da0171d19c9c7e68921f269e7cbdad40606862be90744eb511 1
payments sha256:b1afcf2ca876817cb7177565bd61fef47cf0efa5282c87bef675cc03933920f8 1
employees sha256:5a12b3dc66341db78c21f58d267f1ba8a70974733b3226b8d530a15d7d28cac2 1
photographers sha256:02af42853dec12c19f1eee7757ca8a5691a71343e0d0289f4d06e7b30f6290ed 1
makeup-artists sha256:ce6c72ee42fbb079dc25dc32b971b604b7270a6e2304acfde7269de96391ba90 1
tutors sha256:05e5f2704673637a8a5d1db99516e0fbba42455c0d95f53ae6be78e1ef1639c0 1
developers sha256:dd11cc3704faebb1aa135dada721a0c289f80aafaf35b65dd4c66a6908c5f4e3 1
video-editors sha256:d1f78c413d538d89fbc75510cf08ee7623fdd6738508117dfa95320da53bdfe4 1
graphic-designers sha256:a6fd8cc5779e79c9098cc018d00944be29af3ed7982f91dab6d67eb705b2c4cd 1
social-media-managers sha256:da228122c37fa46bdaf4e129e17388fba3961a7626babf3237134426e32b4f46 1
fitness-trainers sha256:ecbbae844138bb714747a8833e3f908448eaa2115d85f952ff13dbed0929e010 1
catering-services sha256:6cf480a15360a9a8dfee61ac5a3c6acac801428afddc446e1de71f3cbcdbad04 1
ugc-content-creators sha256:bb8e969f4ef67216c9a596fa9598066e4bb71775a48e551aceac778edb5539cb 1
cron sha256:e8f3294dbb4fa493881ef3faf72c80f1c8507e67124014962fbbabcaf6b7c0df 1
1 gateway sha256:f3e8780a1da3f847a9a9a5f22104d821caa9e88dba73826c171d1d95f4ebfa34 2
2 companies sha256:a775a7bcea26c6ed23ea26cc80ab1020ecef074d97ae49e4413130078618603d 1
3 users sha256:346b6ed0098af13e82982ff008023f7aec9eeb434b0d721e14802e3c9c6caaed 1
4 jobs sha256:52cee97cdea043dcb7665b44ab575bbd4ed5b89516131e31c2779c4b986c2ae5 1
5 job-seekers sha256:b4035f07e40e052c560f1efdbcddd9c2853e5d1874f3a20ca365192e3568c42b 1
6 customers sha256:8d52c9d82615f8da0171d19c9c7e68921f269e7cbdad40606862be90744eb511 1
7 payments sha256:b1afcf2ca876817cb7177565bd61fef47cf0efa5282c87bef675cc03933920f8 1
8 employees sha256:5a12b3dc66341db78c21f58d267f1ba8a70974733b3226b8d530a15d7d28cac2 1
9 photographers sha256:02af42853dec12c19f1eee7757ca8a5691a71343e0d0289f4d06e7b30f6290ed 1
10 makeup-artists sha256:ce6c72ee42fbb079dc25dc32b971b604b7270a6e2304acfde7269de96391ba90 1
11 tutors sha256:05e5f2704673637a8a5d1db99516e0fbba42455c0d95f53ae6be78e1ef1639c0 1
12 developers sha256:dd11cc3704faebb1aa135dada721a0c289f80aafaf35b65dd4c66a6908c5f4e3 1
13 video-editors sha256:d1f78c413d538d89fbc75510cf08ee7623fdd6738508117dfa95320da53bdfe4 1
14 graphic-designers sha256:a6fd8cc5779e79c9098cc018d00944be29af3ed7982f91dab6d67eb705b2c4cd 1
15 social-media-managers sha256:da228122c37fa46bdaf4e129e17388fba3961a7626babf3237134426e32b4f46 1
16 fitness-trainers sha256:ecbbae844138bb714747a8833e3f908448eaa2115d85f952ff13dbed0929e010 1
17 catering-services sha256:6cf480a15360a9a8dfee61ac5a3c6acac801428afddc446e1de71f3cbcdbad04 1
18 ugc-content-creators sha256:bb8e969f4ef67216c9a596fa9598066e4bb71775a48e551aceac778edb5539cb 1
19 cron sha256:e8f3294dbb4fa493881ef3faf72c80f1c8507e67124014962fbbabcaf6b7c0df 1

View file

@ -1,16 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-companies
spec:
template:
spec:
volumes:
- name: nxtgauge-uploads
persistentVolumeClaim:
claimName: nxtgauge-uploads-pvc
containers:
- name: companies
volumeMounts:
- name: nxtgauge-uploads
mountPath: /var/lib/nxtgauge-uploads

View file

@ -1,11 +1,50 @@
apiVersion: kustomize.config.k8s.io/v1beta1
namespace: nxtgauge
kind: Kustomization
resources:
- ../../base
patches:
- path: release-patches.yaml
- path: companies-volume-patch.yaml
- path: replicas-patch.yaml
target:
kind: Deployment
name: nxtgauge-rust-companies
name: nxtgauge-rust-gateway
images:
- name: registry.nxtgauge.com/nxtgauge-rust-gateway
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-users
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-companies
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-job-seekers
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-jobs
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-leads
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-customers
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-payments
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-employees
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-photographers
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-makeup-artists
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-tutors
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-developers
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-video-editors
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-graphic-designers
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-social-media-managers
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-fitness-trainers
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-catering-services
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-ugc-content-creators
newTag: e6d85ffc8367885050b9434494f291724cc523c0
- name: registry.nxtgauge.com/nxtgauge-rust-cron
newTag: e6d85ffc8367885050b9434494f291724cc523c0

View file

@ -1,227 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-gateway
spec:
replicas: 2
template:
spec:
containers:
- name: gateway
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-gateway@sha256:f3e8780a1da3f847a9a9a5f22104d821caa9e88dba73826c171d1d95f4ebfa34
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-companies
spec:
replicas: 1
template:
spec:
containers:
- name: companies
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-companies@sha256:a775a7bcea26c6ed23ea26cc80ab1020ecef074d97ae49e4413130078618603d
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-users
spec:
replicas: 1
template:
spec:
containers:
- name: users
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-users@sha256:346b6ed0098af13e82982ff008023f7aec9eeb434b0d721e14802e3c9c6caaed
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-jobs
spec:
replicas: 1
template:
spec:
containers:
- name: jobs
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-jobs@sha256:52cee97cdea043dcb7665b44ab575bbd4ed5b89516131e31c2779c4b986c2ae5
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-job-seekers
spec:
replicas: 1
template:
spec:
containers:
- name: job-seekers
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-job-seekers@sha256:b4035f07e40e052c560f1efdbcddd9c2853e5d1874f3a20ca365192e3568c42b
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-customers
spec:
replicas: 1
template:
spec:
containers:
- name: customers
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-customers@sha256:8d52c9d82615f8da0171d19c9c7e68921f269e7cbdad40606862be90744eb511
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-payments
spec:
replicas: 1
template:
spec:
containers:
- name: payments
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-payments@sha256:b1afcf2ca876817cb7177565bd61fef47cf0efa5282c87bef675cc03933920f8
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-employees
spec:
replicas: 1
template:
spec:
containers:
- name: employees
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-employees@sha256:5a12b3dc66341db78c21f58d267f1ba8a70974733b3226b8d530a15d7d28cac2
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-photographers
spec:
replicas: 1
template:
spec:
containers:
- name: photographers
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-photographers@sha256:02af42853dec12c19f1eee7757ca8a5691a71343e0d0289f4d06e7b30f6290ed
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-makeup-artists
spec:
replicas: 1
template:
spec:
containers:
- name: makeup-artists
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-makeup-artists@sha256:ce6c72ee42fbb079dc25dc32b971b604b7270a6e2304acfde7269de96391ba90
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-tutors
spec:
replicas: 1
template:
spec:
containers:
- name: tutors
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-tutors@sha256:05e5f2704673637a8a5d1db99516e0fbba42455c0d95f53ae6be78e1ef1639c0
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-developers
spec:
replicas: 1
template:
spec:
containers:
- name: developers
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-developers@sha256:dd11cc3704faebb1aa135dada721a0c289f80aafaf35b65dd4c66a6908c5f4e3
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-video-editors
spec:
replicas: 1
template:
spec:
containers:
- name: video-editors
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-video-editors@sha256:d1f78c413d538d89fbc75510cf08ee7623fdd6738508117dfa95320da53bdfe4
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-graphic-designers
spec:
replicas: 1
template:
spec:
containers:
- name: graphic-designers
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-graphic-designers@sha256:a6fd8cc5779e79c9098cc018d00944be29af3ed7982f91dab6d67eb705b2c4cd
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-social-media-managers
spec:
replicas: 1
template:
spec:
containers:
- name: social-media-managers
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-social-media-managers@sha256:da228122c37fa46bdaf4e129e17388fba3961a7626babf3237134426e32b4f46
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-fitness-trainers
spec:
replicas: 1
template:
spec:
containers:
- name: fitness-trainers
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-fitness-trainers@sha256:ecbbae844138bb714747a8833e3f908448eaa2115d85f952ff13dbed0929e010
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-catering-services
spec:
replicas: 1
template:
spec:
containers:
- name: catering-services
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-catering-services@sha256:6cf480a15360a9a8dfee61ac5a3c6acac801428afddc446e1de71f3cbcdbad04
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-ugc-content-creators
spec:
replicas: 1
template:
spec:
containers:
- name: ugc-content-creators
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-ugc-content-creators@sha256:bb8e969f4ef67216c9a596fa9598066e4bb71775a48e551aceac778edb5539cb
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-cron
spec:
replicas: 1
template:
spec:
containers:
- name: cron
image: ci.nxtgauge.com/ashwin/nxtgauge-rust-cron@sha256:e8f3294dbb4fa493881ef3faf72c80f1c8507e67124014962fbbabcaf6b7c0df

View file

@ -0,0 +1,6 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-rust-gateway
spec:
replicas: 2

View file

@ -15,11 +15,9 @@ spec:
labels:
app: nxtgauge-frontend-solid
spec:
imagePullSecrets:
- name: forgejo-regcred
containers:
- name: frontend-solid
image: ci.nxtgauge.com/ashwin/nxtgauge-frontend-solid
image: registry.nxtgauge.com/nxtgauge-frontend-solid
imagePullPolicy: Always
ports:
- containerPort: 3000

View file

@ -12,63 +12,10 @@ spec:
- hosts:
- test111.nxtgauge.com
secretName: test111-tls
# nxtgauge.com/www serve the SAME app/deployment as test111 - the only
# difference is src/middleware.ts redirects "/" on these two hosts to
# /coming-soon (pre-launch placeholder) while test111 shows the real
# app. No separate service/deployment needed.
- hosts:
- nxtgauge.com
- www.nxtgauge.com
secretName: nxtgauge-com-tls
rules:
- host: test111.nxtgauge.com
http:
paths:
# /api/* routes to Rust gateway directly (signup, login, KB, etc.)
# so the SolidStart frontend (which has no /api/auth/* handler due to
# the Vinxi 0.5.7 file-based-route bug) does not have to proxy itself.
# More specific paths must come first — Traefik matches the longest prefix.
- path: /api
pathType: Prefix
backend:
service:
name: nxtgauge-rust-gateway
port:
number: 9100
- path: /
pathType: Prefix
backend:
service:
name: nxtgauge-frontend-solid
port:
number: 80
- host: nxtgauge.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: nxtgauge-rust-gateway
port:
number: 9100
- path: /
pathType: Prefix
backend:
service:
name: nxtgauge-frontend-solid
port:
number: 80
- host: www.nxtgauge.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: nxtgauge-rust-gateway
port:
number: 9100
- path: /
pathType: Prefix
backend:

View file

@ -1,27 +1,12 @@
apiVersion: v1
kind: Secret
metadata:
name: nxtgauge-frontend-solid-secrets
namespace: nxtgauge
name: nxtgauge-frontend-solid-secrets
namespace: nxtgauge
type: Opaque
stringData:
SMTP_HOST: ENC[AES256_GCM,data:ZyymsH6KNKIC9DMftVRKtyY=,iv:8l7Ue6qlUTyJqlSqyfFHwCpM4gkgaaucVX2Q6izaYN4=,tag:SC7NAtA9/er24PLnGV0oOQ==,type:str]
SMTP_PORT: ENC[AES256_GCM,data:+23C,iv:LZOuM1GiI1unVINYvBkH8c6LF0vBNDSrEQSjz3EXK2Y=,tag:ZjyJ4lZ3PgPGxRuOFFkT/A==,type:str]
SMTP_USER: ENC[AES256_GCM,data:ehnFRXh1w2SWCoo=,iv:s3w/Xgms8kNKF9PImHx5JpM0uvM7FC35jl9sCVmrek8=,tag:RagZTnqLwC06+MwK2Av0Rw==,type:str]
SMTP_PASS: ENC[AES256_GCM,data:LOMzp/mGddcwiJLfSB69fIn0mQvJVs14WjF/MNtO0qgW6LDX0erhsCtwPCoE73WUCiLKOKL0CwZPdZqxfAK9OE+edSF1CqnQdhOjuYtR4wElD1yj54t1/5wHRTFRTUXkPO/gnqKT3jWez3pxEc6rWpsLT2ZIwEWSP0E9SIKZW10K27G8+vNosuYrDc0yTmc9,iv:zrV5+/pHMjult/2kLDHZr3EuGyF5uFu3TrCvvms+2fA=,tag:g25HmbNv2Q7s/pXV/namCQ==,type:str]
SMTP_FROM: ENC[AES256_GCM,data:+R7du3/Bb2tE17FE9aJh8Y1NPa8=,iv:PjTsr/Nj1caWjxENmFMctjjxA995Fr1NWeYo7SC1PwY=,tag:NkqJxcJHUoWKqqkQcp9xQQ==,type:str]
sops:
age:
- recipient: age1sqxc53yvap8763eup99g6eza6fa5u65qetdymlh5ch4ugvvv5q0sf3pm4l
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvKyt1WFZjUWxNY3BDdGZG
cnVnczgvVmFmYnIvK0M1OGptOE1tYUIrTUh3CnVPb0xMdnZPR2YwenpjK3h0QTZK
NEdQRFRjUXRPdHVZdDJZenF0NG9CWlEKLS0tIDZzNElsYm9RMTNZZS8xVnJhSCsx
NFgvM1VtUUJ0emVYandXcUJFRTRDdVEKoRum9CpLygcum+VUz4Ur79KeX+BxqDO/
f7oSAzdLYgLPyc867Fg8vKBQDUfZsARHudDtIhL2t+YFp2FHFZ9M6g==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-07-02T12:17:30Z"
mac: ENC[AES256_GCM,data:bc+mb3RSM4rLj6K2l4SrNNrFMg2evfVkNo7yzkgVC2RieJFpryfwf2Hfuq4qlXgI8KXh2eSyKWX3+UBlgZY17dneKP/1kSfVkgaAk46Uly448JHw6Vs94++7FlemLCe8t1EMCTtSfwK/AvKeCoOr1+BdbgDxCA8TBkTEp3Y5djM=,iv:kpBSTE04LLdjryiZD0pGCYjYV3Haitxxc67aamkkpMI=,tag:bJzs4R9vK5AwbdvhX7QZoA==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2
SMTP_HOST: "smtp.zeptomail.in"
SMTP_PORT: "587"
SMTP_USER: "emailapikey"
SMTP_PASS: "PHtE6r1ZR+zi3jV88RNW4/O4F8CkPdksqO9iJAhA4YcTD6dQFk1S+dl/wDC3/h97AKYWFfSczo1rt72etOuDLTnrMjlEDWqyqK3sx/VYSPOZsbq6x00esVgYdEfYVYDpcNFj3SPQut7dNA=="
SMTP_FROM: "support@nxtgauge.com"

View file

@ -1,7 +1,9 @@
apiVersion: kustomize.config.k8s.io/v1beta1
namespace: nxtgauge
kind: Kustomization
resources:
- ../../base
patches:
- path: release-patch.yaml
patchesStrategicMerge:
- replicas-patch.yaml
images:
- name: registry.nxtgauge.com/nxtgauge-frontend-solid
newTag: d888466

View file

@ -1,12 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: nxtgauge
name: nxtgauge-frontend-solid
spec:
replicas: 1
template:
spec:
containers:
- name: frontend-solid
image: ci.nxtgauge.com/ashwin/nxtgauge-frontend-solid@sha256:d2cbf09d391aa300beaf383f3cfc342454c45b0ca22fa58693ff73273123551f

View file

@ -0,0 +1,7 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nxtgauge-frontend-solid
namespace: nxtgauge
spec:
replicas: 1

View file

@ -7,14 +7,6 @@ metadata:
app: ollama
spec:
replicas: 1
# Default RollingUpdate deadlocks here: the new pod can't mount the
# ollama-models PVC (ReadWriteOnce) until the old pod releases it, but
# the old pod isn't terminated until the new one is Ready — a rollout
# that discovered this the hard way (stuck ContainerCreating). Recreate
# accepts a brief gap in availability in exchange for actually rolling
# out.
strategy:
type: Recreate
selector:
matchLabels:
app: ollama
@ -32,30 +24,16 @@ spec:
env:
- name: OLLAMA_HOST
value: "0.0.0.0:11434"
# Keep a loaded model resident for 30 min of inactivity instead
# of Ollama's 5-minute default — job-description/resume/cover-
# letter traffic is bursty, and reloading a 2.5-5GB model from
# disk on every request would add multi-second latency to each
# first call after a gap.
- name: OLLAMA_KEEP_ALIVE
value: "30m"
volumeMounts:
- name: ollama-models
mountPath: /root/.ollama
resources:
requests:
cpu: 1000m
memory: 3Gi
cpu: 500m
memory: 700Mi
limits:
# qwen3:4b (~2.5GB on disk) and qwen3:8b (~5.2GB) are already
# pulled onto the PVC, but the previous 1500Mi limit could
# only ever load gemma3:270m — which is why every LiteLLM
# model alias was mapped to gemma3:270m regardless of name
# (see apps/litellm/base/configmap.yaml). Sized to comfortably
# hold qwen3:8b plus KV cache/runtime overhead, with headroom;
# node has 16GB total and was at ~26% memory use.
cpu: 4000m
memory: 8Gi
cpu: 1000m
memory: 1500Mi
volumes:
- name: ollama-models
persistentVolumeClaim:

View file

@ -1,67 +0,0 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: pg-postgresql-backup
namespace: data
spec:
schedule: "30 2 * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 5
jobTemplate:
spec:
backoffLimit: 2
template:
spec:
restartPolicy: OnFailure
containers:
- name: pg-backup
image: postgres:16-alpine
envFrom:
- secretRef:
name: pg-postgresql-backup-secret
command: ["/bin/sh", "-ec"]
args:
- |
apk add --no-cache aws-cli python3 >/dev/null
TIMESTAMP="$(date -u +%Y%m%dT%H%M%SZ)"
RAW_FILE="/tmp/${PGDATABASE}-${TIMESTAMP}.sql"
DUMP_FILE="${RAW_FILE}.gz"
pg_dump -h "$PGHOST" -p "$PGPORT" -U "$PGUSER" -d "$PGDATABASE" -f "$RAW_FILE"
gzip -9 "$RAW_FILE"
export AWS_ACCESS_KEY_ID="$B2_ACCESS_KEY_ID"
export AWS_SECRET_ACCESS_KEY="$B2_SECRET_ACCESS_KEY"
export AWS_DEFAULT_REGION="$B2_REGION"
aws --endpoint-url "$B2_ENDPOINT" s3 cp "$DUMP_FILE" "s3://${B2_BUCKET_NAME}/${BACKUP_PREFIX}/$(basename "$DUMP_FILE")"
rm -f "$DUMP_FILE"
echo "Uploaded $(basename "$DUMP_FILE") to s3://${B2_BUCKET_NAME}/${BACKUP_PREFIX}/"
python3 - <<'PYEOF'
import subprocess, json, datetime, os
bucket = os.environ["B2_BUCKET_NAME"]
prefix = os.environ["BACKUP_PREFIX"]
endpoint = os.environ["B2_ENDPOINT"]
retention_days = int(os.environ.get("RETENTION_DAYS", "30"))
cutoff = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=retention_days)
out = subprocess.run(
["aws", "--endpoint-url", endpoint, "s3api", "list-objects-v2",
"--bucket", bucket, "--prefix", prefix],
capture_output=True, text=True, check=True,
)
listing = json.loads(out.stdout or "{}")
for obj in listing.get("Contents", []):
last_modified = datetime.datetime.fromisoformat(obj["LastModified"].replace("Z", "+00:00"))
if last_modified < cutoff:
subprocess.run(
["aws", "--endpoint-url", endpoint, "s3api", "delete-object",
"--bucket", bucket, "--key", obj["Key"]],
check=True,
)
print("deleted expired backup:", obj["Key"])
PYEOF

View file

@ -1,34 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: pg-postgresql-backup-secret
namespace: data
type: Opaque
stringData:
PGHOST: ENC[AES256_GCM,data:q9CYJ8BfUmV34FarbQ==,iv:0c4EK546jGjc7XWejS/lqC1VKuEGWCcDikHQmCLzaik=,tag:wkEODY8ZYjE6E1sGoIqDiw==,type:str]
PGPORT: ENC[AES256_GCM,data:EmsjAQ==,iv:YLvsGmVgHm9k0tDheWgMZufCW2Im/VOxWa4hhntOFNU=,tag:m8KBwpVUXX/RAjz/Chy0nw==,type:str]
PGUSER: ENC[AES256_GCM,data:99mVYPGLdmM=,iv:FW/6THa6vkzUDEKqBqNfgYBhMFTIzUiMgelYzNBgNiM=,tag:xFryuyqEdXv+oJ969Q+3Cw==,type:str]
PGPASSWORD: ENC[AES256_GCM,data:3YfO5dd7TE1Sh/ZwoihvYrnqkJq0R/C9702dm+ZH35B7wytfLA5iU/Hmxw==,iv:iiXpitEOSUtes7j3zPQOIgrkDIVBtgQNpQQ2JetGRlc=,tag:dBGVlRzl9edCWGCdEsE7JA==,type:str]
PGDATABASE: ENC[AES256_GCM,data:VQ3sBkUwgQo=,iv:BA20my9o+1KNNohx1EBD8E281rqoz6Z4lJZiGCyvP+A=,tag:+7D/KGTMMN8cB5TYnvDdWA==,type:str]
B2_ACCESS_KEY_ID: ENC[AES256_GCM,data:GIzq8wdTtvgYEI61nmPVdaKdNePY5bWUsA==,iv:gxvexXRO4hp/+0trsI77sbTzGD5dbJqdAqfvD8Vyd3Y=,tag:TKdpqdg7iSM3mE7EWmJ4IA==,type:str]
B2_SECRET_ACCESS_KEY: ENC[AES256_GCM,data:acJclcstPO3tr2RtfHuBZahZvCRnlNNfbAjl6G7oCg==,iv:vOTGiQkO8nObvRSiikHf1+UMpqcJILgpixvehC4rSoo=,tag:vct0vuY2vvI2Iy/tTmwFSw==,type:str]
B2_BUCKET_NAME: ENC[AES256_GCM,data:vlArED2zywHcFb1P28ko,iv:ehOZiT6D5JuqyIprdwCuGKBO0j+tfcYbJXusay4X9Dk=,tag:HTmhgLPtQ+hRMHnPDxm+EQ==,type:str]
B2_ENDPOINT: ENC[AES256_GCM,data:T5VP8p99RxswSf+izejtzFlG/PWTqCj/R0fUqpUgmI9KaXI6K0eN8HY=,iv:CJJ0qa2Snfi6hz0/yr1A/yjcoEq4UtZMig/I8vRPTWg=,tag:7tbKKZPFeB2Yqnogw7/tsg==,type:str]
B2_REGION: ENC[AES256_GCM,data:Ca3TwWstC1kvZJ+W3VI=,iv:0EkdXRPxKs7WKle0htL9LSMc9EJwMaRn+IKu9tEXrPY=,tag:ZJC6Izx6M9ziHapyBMelcQ==,type:str]
BACKUP_PREFIX: ENC[AES256_GCM,data:qMI/Fj4ODTM3OhxocjXBo3E=,iv:FEljbqYmnclrDuVJXej3lS/q4HhxaFDu+DZma13QJb8=,tag:RXMek4SgCbi5JUyFMeYR9w==,type:str]
RETENTION_DAYS: ENC[AES256_GCM,data:NJ4=,iv:CPMogSsUKz2m2ubDZ11fSkbbGLI03loBgS7/fY3+iXo=,tag:kH/hy+5K06YEZuK4BeY/6g==,type:str]
sops:
age:
- recipient: age1sqxc53yvap8763eup99g6eza6fa5u65qetdymlh5ch4ugvvv5q0sf3pm4l
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6cmgwSHJtYWk3QzNKTWJz
L2dBZFRUS3VZVlFBWFc3VDk4N1lIa2g5RW5zCi9yQmFjQ3JRMHVhaEhwWDQzZEEz
bVRidUF0QU5xK3ArellHVDhaRmZ5REUKLS0tIGdWdS9JSDh1aDUvaEdJUDBzOHdj
a3MwSFVtZ3RpdzVCN1FBOGxtekRmYVUKJRIo/Bavm9OisrwrqKNNSYc6NquVkBrp
+d3hHuC1JYsBGndjxSzSyiP6YYbkuC1Y303vVac+To6fXdFLZW63eQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-08-15T17:03:21Z"
mac: ENC[AES256_GCM,data:mDx+iKI92dZTrGcyepYyO4ZdpPgpe+KLm7oQauZzRWeG5dbLc0jAwf4oRXlYFBJ5U5BVvVEL1bButrShzW/uBAbHig0zJS4x7iJfFmZv1uuWQtzsawL0E59NQD97Tz4dktgRrRwqu0C2+qy5+IsHpo3msSfVwhhSnkbIHPZ76Sg=,iv:YJjrcL29jjHF2mVZ7BE8g33wEB/FqcCaq9OoU9I3Lp4=,tag:zJ3JbX/W/4b01bOntWdlrg==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View file

@ -1,58 +0,0 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: pg-postgresql
namespace: data
spec:
serviceName: pg-postgresql
replicas: 1
selector:
matchLabels:
app: pg-postgresql
template:
metadata:
labels:
app: pg-postgresql
spec:
containers:
- name: postgresql
image: registry.nxtgauge.com/postgres:16-alpine
ports:
- name: tcp-postgresql
containerPort: 5432
env:
- name: POSTGRES_USER
value: postgres
- name: POSTGRES_PASSWORD
value: chandan2026@1
- name: POSTGRES_DB
value: nxtgauge
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: longhorn-2
resources:
requests:
storage: 30Gi
---
apiVersion: v1
kind: Service
metadata:
name: pg-postgresql
namespace: data
spec:
type: NodePort
selector:
app: pg-postgresql
ports:
- name: tcp-postgresql
port: 5432
targetPort: 5432
nodePort: 30870

View file

@ -1,6 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- retention-script.yaml
- retention-cronjob.yaml
namespace: registry

View file

@ -1,63 +0,0 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: docker-registry
namespace: registry
spec:
serviceName: docker-registry
replicas: 1
selector:
matchLabels:
app: docker-registry
template:
metadata:
labels:
app: docker-registry
spec:
containers:
- name: registry
image: registry:3
ports:
- containerPort: 5000
name: registry
env:
- name: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY
value: /var/lib/registry
- name: REGISTRY_AUTH
value: htpasswd
- name: REGISTRY_AUTH_HTPASSWD_REALM
value: Registry Realm
- name: REGISTRY_AUTH_HTPASSWD_PATH
value: /auth/htpasswd
volumeMounts:
- name: registry-storage
mountPath: /var/lib/registry
- name: auth
mountPath: /auth
readOnly: true
volumes:
- name: auth
secret:
secretName: registry-auth
volumeClaimTemplates:
- metadata:
name: registry-storage
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: longhorn
resources:
requests:
storage: 30Gi
---
apiVersion: v1
kind: Service
metadata:
name: docker-registry
namespace: registry
spec:
selector:
app: docker-registry
ports:
- port: 5000
targetPort: 5000
clusterIP: 10.43.17.31

View file

@ -1,42 +0,0 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: registry-keep-last-3-builds
namespace: registry
spec:
schedule: "*/15 * * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 2
failedJobsHistoryLimit: 3
jobTemplate:
spec:
backoffLimit: 1
template:
spec:
serviceAccountName: registry-gc-runner
restartPolicy: Never
containers:
- name: prune
image: python:3.12-slim
command: ["sh", "-c"]
args:
- |
# Install kubectl
apt-get update && apt-get install -y curl --no-install-recommends && rm -rf /var/lib/apt/lists/*
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# Run the prune script
python3 /scripts/prune.py
volumeMounts:
- name: script
mountPath: /scripts
- name: auth
mountPath: /auth
readOnly: true
volumes:
- name: script
configMap:
name: registry-retention-script
- name: auth
secret:
secretName: registry-regcred

View file

@ -1,203 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: registry-retention-script
namespace: registry
data:
prune.py: |
import base64, json, re, urllib.request, urllib.error
REG='https://registry.nxtgauge.com'
CFG='/auth/.dockerconfigjson'
PATTERN=re.compile(r'^[0-9a-f]{40}$')
# Base images that MUST NEVER be deleted. These are FROM lines in our Dockerfiles.
# They are pulled from Docker Hub and pushed to our private registry for reliability.
# If any are deleted, the entire build pipeline breaks.
BASE_IMAGES = {
'alpine', # runtime base image
'node', # frontend/admin builder
'rust', # backend builder
'python', # used by retention cronjob and other tools
'docker', # dind for forgejo runner
'busybox', # init containers
'registry', # docker registry itself
}
# Additional patterns to NEVER delete - images matching these patterns are protected
PROTECTED_PATTERNS = [
'node:', # any node tag
'rust:', # any rust tag
'alpine:', # any alpine tag
'python:', # any python tag
'docker:', # docker dind images
'busybox:', # busybox images
'registry:', # registry images
]
# Project-image prefix that we DO prune. Anything outside this is sacred.
PROJECT_PREFIX = 'nxtgauge-'
with open(CFG,'r') as f:
dcfg=json.load(f)
auth=dcfg['auths']['registry.nxtgauge.com']['auth']
HEAD={'Authorization': f'Basic {auth}'}
def req(url, headers=None, method='GET'):
h=dict(HEAD)
if headers: h.update(headers)
r=urllib.request.Request(url, headers=h, method=method)
with urllib.request.urlopen(r, timeout=30) as resp:
return resp.status, dict(resp.headers), resp.read()
_, _, body = req(f'{REG}/v2/_catalog?n=1000')
all_repos=json.loads(body.decode()).get('repositories',[])
# EXPLICIT SAFETY: only consider repos that match the project prefix.
# Protected base images (alpine/node/rust/python/docker/busybox/registry) are NEVER deleted.
def is_protected(repo_name):
"""Check if a repo is protected - base images or matches protected patterns"""
if repo_name in BASE_IMAGES:
return True
for pattern in PROTECTED_PATTERNS:
if repo_name.startswith(pattern.rstrip(':')):
return True
return False
repos=[r for r in all_repos if r.startswith(PROJECT_PREFIX) and not is_protected(r)]
# Sanity check: log if any base image is missing
present = set(all_repos)
for b in BASE_IMAGES:
if b not in present:
print(f'[WARN] base image {b} not in registry catalog - re-push required!')
else:
print(f'[PROTECTED] base image {b} will NEVER be deleted')
deleted=0
for repo in sorted(repos):
try:
_, _, tb=req(f'{REG}/v2/{repo}/tags/list')
tags=(json.loads(tb.decode()).get('tags') or [])
except Exception as e:
print(f'[{repo}] tags/list failed: {e}')
continue
sha=[t for t in tags if PATTERN.match(t)]
if len(sha)<=1:
print(f'[{repo}] sha={len(sha)} no prune')
continue
rows=[]
for t in sha:
created='1970-01-01T00:00:00Z'
digest=None
try:
_, h, mb=req(f'{REG}/v2/{repo}/manifests/{t}', headers={'Accept':'application/vnd.docker.distribution.manifest.v2+json'})
digest=h.get('Docker-Content-Digest')
m=json.loads(mb.decode())
cfg=(m.get('config') or {}).get('digest')
if cfg:
_, _, cb=req(f'{REG}/v2/{repo}/blobs/{cfg}')
created=json.loads(cb.decode()).get('created', created)
except Exception:
created='9999-12-31T23:59:59Z'
rows.append((created, t, digest))
rows.sort(key=lambda x: x[0], reverse=True)
KEEP_N=10 # keep last 10 SHA builds (current + 9 previous)
keep_set=set(t for _, t, _ in rows[:KEEP_N])
# preserve buildcache for performance
keep_set.update(t for t in tags if t == 'buildcache')
# always keep 'latest' tag
keep_set.update(t for t in tags if t == 'latest')
keep_list=sorted(keep_set)
print(f'[{repo}] sha_total={len(rows)} keep={keep_list} remove={max(0, len(rows)-len(keep_set))}')
for _, t, d in rows:
if t in keep_set or not d:
continue
try:
req(f'{REG}/v2/{repo}/manifests/{d}', method='DELETE')
deleted+=1
print(f' deleted {repo}:{t}')
except urllib.error.HTTPError as e:
print(f' delete failed {repo}:{t} code={e.code}')
except Exception as e:
print(f' delete failed {repo}:{t} err={e}')
print(f'deleted_manifests={deleted}')
# Trigger garbage collection to delete unreferenced blob layers
if deleted > 0:
print('\n=== Triggering Garbage Collection ===')
try:
# Scale down registry to run GC
import subprocess
subprocess.run(['kubectl', 'scale', 'deployment', 'docker-registry', '--replicas=0', '-n', 'registry'], check=True)
print('Scaled down docker-registry deployment')
# Wait for deployment to be fully down
import time
time.sleep(5)
# Run GC job
gc_job = {
'apiVersion': 'batch/v1',
'kind': 'Job',
'metadata': {'name': 'registry-gc-once', 'namespace': 'registry'},
'spec': {
'backoffLimit': 0,
'template': {
'spec': {
'restartPolicy': 'Never',
'containers': [{
'name': 'gc',
'image': 'registry:3',
'command': ['registry', 'garbage-collect', '--delete-untagged', '/etc/distribution/config.yml'],
'volumeMounts': [
{'name': 'storage', 'mountPath': '/var/lib/registry'},
{'name': 'config', 'mountPath': '/etc/distribution'}
]
}],
'volumes': [
{'name': 'storage', 'persistentVolumeClaim': {'claimName': 'registry-pvc'}},
{'name': 'config', 'configMap': {'name': 'registry-config'}}
]
}
}
}
}
# Delete old GC job if exists
subprocess.run(['kubectl', 'delete', 'job', 'registry-gc-once', '-n', 'registry', '--ignore-not-found=true'], check=False)
time.sleep(2)
# Create and wait for GC job
import tempfile
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
json.dump(gc_job, f)
f.flush()
subprocess.run(['kubectl', 'apply', '-f', f.name], check=True)
print('GC job created, waiting for completion...')
# Wait up to 10 minutes for GC to complete
for i in range(120):
result = subprocess.run(['kubectl', 'get', 'job', 'registry-gc-once', '-n', 'registry', '-o', 'jsonpath={.status.succeeded}'], capture_output=True, text=True)
if result.stdout.strip() == '1':
print('Garbage collection completed successfully')
break
result = subprocess.run(['kubectl', 'get', 'job', 'registry-gc-once', '-n', 'registry', '-o', 'jsonpath={.status.failed}'], capture_output=True, text=True)
if result.stdout.strip() == '1':
print('GC job failed')
break
time.sleep(5)
# Scale back up
subprocess.run(['kubectl', 'scale', 'deployment', 'docker-registry', '--replicas=1', '-n', 'registry'], check=True)
print('Scaled up docker-registry deployment')
except Exception as e:
print(f'GC trigger failed: {e}')
# Ensure registry is scaled back up even if GC failed
try:
subprocess.run(['kubectl', 'scale', 'deployment', 'docker-registry', '--replicas=1', '-n', 'registry'], check=False)
except:
pass

View file

@ -1,17 +0,0 @@
# Traceworks2026 GitOps
This app is deployed from `apps/traceworks2026/overlays/prod`.
Flux image automation watches these Forgejo registry images:
- `ci.nxtgauge.com/admin/traceworks2026-frontend`
- `ci.nxtgauge.com/admin/traceworks2026-api`
Expected CI flow:
1. GitHub mirrors the app repo to Forgejo.
2. Forgejo Actions builds and pushes timestamped image tags.
3. Flux updates `overlays/prod/release-patch.yaml` to the newest tags.
4. Flux applies the updated manifests to the cluster.
Before this works in-cluster, create a `forgejo-regcred` secret in the `flux-system` namespace so Flux can read the private registry.

View file

@ -1,48 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: traceworks-api
namespace: traceworks
labels:
app: traceworks-api
spec:
replicas: 1
selector:
matchLabels:
app: traceworks-api
template:
metadata:
labels:
app: traceworks-api
spec:
imagePullSecrets:
- name: forgejo-regcred
containers:
- name: api
image: ci.nxtgauge.com/admin/traceworks2026-api:19700101000000-000000000000
imagePullPolicy: Always
ports:
- containerPort: 3001
name: http
envFrom:
- secretRef:
name: traceworks-api-env
readinessProbe:
httpGet:
path: /api/health
port: 3001
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /api/health
port: 3001
initialDelaySeconds: 15
periodSeconds: 20
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi

View file

@ -1,21 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: traceworks-api-env
namespace: traceworks
type: Opaque
stringData:
ZEPTO_SMTP_HOST: smtp.zeptomail.in
ZEPTO_SMTP_PORT: "587"
ZEPTO_SMTP_USER: emailapikey
ZEPTO_SMTP_PASS: replace_me
EMAIL_FROM: Traceworks <support@traceworks.in>
EMAIL_TO: ashwin@traceworks.in
PAYU_MERCHANT_KEY: replace_me
PAYU_MERCHANT_SALT: replace_me
PAYU_MODE: live
API_BASE_URL: https://learn.traceworks.in
FRONTEND_URL: https://learn.traceworks.in
SELLER_GSTIN: replace_me
SELLER_NAME: Traceworks Technologies LLP
SELLER_ADDRESS: Plot no 1547, 13th Main Road, Anna Nagar West, Chennai - 600040

View file

@ -1,12 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: traceworks-api
namespace: traceworks
spec:
selector:
app: traceworks-api
ports:
- name: http
port: 3001
targetPort: 3001

View file

@ -1,45 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: traceworks-frontend
namespace: traceworks
labels:
app: traceworks-frontend
spec:
replicas: 2
selector:
matchLabels:
app: traceworks-frontend
template:
metadata:
labels:
app: traceworks-frontend
spec:
imagePullSecrets:
- name: forgejo-regcred
containers:
- name: nginx
image: ci.nxtgauge.com/admin/traceworks2026-frontend:19700101000000-000000000000
imagePullPolicy: Always
ports:
- containerPort: 80
name: http
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 15
periodSeconds: 20
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi

View file

@ -1,12 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: traceworks-frontend
namespace: traceworks
spec:
selector:
app: traceworks-frontend
ports:
- name: http
port: 80
targetPort: 80

View file

@ -1,70 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traceworks
namespace: traceworks
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
# Add custom headers for geo detection
traefik.ingress.kubernetes.io/request-headers: "X-Forwarded-Host:{host},X-Country-Code:FR"
spec:
ingressClassName: traefik
tls:
- hosts:
- traceworks.in
- www.traceworks.in
- traceworks.eu
- www.traceworks.eu
- learn.traceworks.in
secretName: traceworks-tls
rules:
- host: learn.traceworks.in
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: traceworks-frontend
port:
number: 80
- host: traceworks.in
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: traceworks-frontend
port:
number: 80
- host: www.traceworks.in
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: traceworks-frontend
port:
number: 80
- host: traceworks.eu
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: traceworks-frontend
port:
number: 80
- host: www.traceworks.eu
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: traceworks-frontend
port:
number: 80

Some files were not shown because too many files have changed in this diff Show more