# services/bstein-dev-home/backend-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: bstein-dev-home-backend namespace: bstein-dev-home spec: replicas: 1 revisionHistoryLimit: 3 selector: matchLabels: app: bstein-dev-home-backend template: metadata: labels: app: bstein-dev-home-backend annotations: vault.hashicorp.com/agent-inject: "true" vault.hashicorp.com/role: "bstein-dev-home" vault.hashicorp.com/agent-inject-secret-portal-env.sh: "kv/data/atlas/portal/atlas-portal-db" vault.hashicorp.com/agent-inject-template-portal-env.sh: | {{ with secret "kv/data/atlas/portal/atlas-portal-db" }} export PORTAL_DATABASE_URL="{{ .Data.data.PORTAL_DATABASE_URL }}" {{ end }} {{ with secret "kv/data/atlas/portal/bstein-dev-home-keycloak-admin" }} export KEYCLOAK_ADMIN_CLIENT_SECRET="{{ .Data.data.client_secret }}" {{ end }} {{ with secret "kv/data/atlas/shared/chat-ai-keys-runtime" }} export CHAT_KEY_MATRIX="{{ .Data.data.matrix }}" export CHAT_KEY_HOMEPAGE="{{ .Data.data.homepage }}" {{ end }} {{ with secret "kv/data/atlas/shared/portal-e2e-client" }} export PORTAL_E2E_CLIENT_ID="{{ .Data.data.client_id }}" export PORTAL_E2E_CLIENT_SECRET="{{ .Data.data.client_secret }}" {{ end }} {{ with secret "kv/data/atlas/shared/postmark-relay" }} export SMTP_HOST="smtp.postmarkapp.com" export SMTP_PORT="587" export SMTP_STARTTLS="true" export SMTP_USE_TLS="false" export SMTP_USERNAME="{{ index .Data.data "apikey" }}" export SMTP_PASSWORD="{{ index .Data.data "apikey" }}" export SMTP_FROM="no-reply-portal@bstein.dev" {{ end }} spec: automountServiceAccountToken: true serviceAccountName: bstein-dev-home nodeSelector: kubernetes.io/arch: arm64 node-role.kubernetes.io/worker: "true" imagePullSecrets: - name: harbor-regcred containers: - name: backend image: registry.bstein.dev/bstein/bstein-dev-home-backend:0.1.1-95 imagePullPolicy: Always command: ["/bin/sh", "-c"] args: - >- . /vault/secrets/portal-env.sh && exec gunicorn -b 0.0.0.0:8080 --workers 2 --timeout 180 app:app env: - name: AI_CHAT_API value: http://ollama.ai.svc.cluster.local:11434 - name: AI_CHAT_MODEL value: qwen2.5-coder:7b-instruct-q4_0 - name: AI_CHAT_TIMEOUT_SEC value: "60" - name: AI_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: AI_NODE_GPU_MAP value: | {"titan-20": "Jetson Xavier (edge GPU)", "titan-21": "Jetson Xavier (edge GPU)", "titan-22": "RTX 3050 8GB (local GPU)", "titan-24": "RTX 3080 8GB (local GPU)"} - name: KEYCLOAK_ENABLED value: "true" - name: KEYCLOAK_URL value: https://sso.bstein.dev - name: KEYCLOAK_REALM value: atlas - name: KEYCLOAK_CLIENT_ID value: bstein-dev-home - name: KEYCLOAK_ISSUER value: https://sso.bstein.dev/realms/atlas - name: KEYCLOAK_JWKS_URL value: http://keycloak.sso.svc.cluster.local/realms/atlas/protocol/openid-connect/certs - name: KEYCLOAK_ADMIN_URL value: http://keycloak.sso.svc.cluster.local - name: KEYCLOAK_ADMIN_REALM value: atlas - name: KEYCLOAK_ADMIN_CLIENT_ID value: bstein-dev-home-admin - name: ACCOUNT_ALLOWED_GROUPS value: "" - name: HTTP_CHECK_TIMEOUT_SEC value: "2" - name: ACCESS_REQUEST_SUBMIT_RATE_LIMIT value: "30" - name: ACCESS_REQUEST_SUBMIT_RATE_WINDOW_SEC value: "3600" - name: ACCESS_REQUEST_STATUS_RATE_LIMIT value: "120" - name: ACCESS_REQUEST_STATUS_RATE_WINDOW_SEC value: "60" - name: ACCESS_REQUEST_INTERNAL_EMAIL_ALLOWLIST value: robotuser@bstein.dev - name: WGER_NAMESPACE value: health - name: WGER_USER_SYNC_CRONJOB value: wger-user-sync - name: WGER_USER_SYNC_WAIT_TIMEOUT_SEC value: "90" - name: FIREFLY_NAMESPACE value: finance - name: FIREFLY_USER_SYNC_CRONJOB value: firefly-user-sync - name: FIREFLY_USER_SYNC_WAIT_TIMEOUT_SEC value: "90" ports: - name: http containerPort: 8080 readinessProbe: httpGet: path: /api/healthz port: http initialDelaySeconds: 2 periodSeconds: 5 timeoutSeconds: 3 livenessProbe: httpGet: path: /api/healthz port: http initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 3 resources: requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 512Mi