workspace/projects/gamilit/k8s/backend/deployment.yaml
rckrdmrd ea1879f4ad feat: Initial workspace structure with multi-level Git configuration
- Configure workspace Git repository with comprehensive .gitignore
- Add Odoo as submodule for ERP reference code
- Include documentation: SETUP.md, GIT-STRUCTURE.md
- Add gitignore templates for projects (backend, frontend, database)
- Structure supports independent repos per project/subproject level

Workspace includes:
- core/ - Reusable patterns, modules, orchestration system
- projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.)
- knowledge-base/ - Reference code and patterns (includes Odoo submodule)
- devtools/ - Development tools and templates
- customers/ - Client implementations template

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 10:44:23 -06:00

302 lines
8.1 KiB
YAML

# =============================================================================
# GAMILIT Backend - Kubernetes Deployment
# =============================================================================
# Purpose: Deploys GAMILIT backend API with horizontal pod autoscaling
# Namespace: gamilit-production
# Replicas: 3 (min) - 10 (max with HPA)
# Resources: CPU 250m-500m, Memory 512Mi-1Gi per pod
# =============================================================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: gamilit-backend
namespace: gamilit-production
labels:
app: gamilit
component: backend
tier: api
version: v1.0.0
annotations:
deployment.kubernetes.io/revision: "1"
description: "GAMILIT Platform Backend API - Node.js + Express + TypeScript"
spec:
replicas: 3
revisionHistoryLimit: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Maximum number of pods that can be created above desired replicas
maxUnavailable: 0 # Ensure zero-downtime during rolling updates
selector:
matchLabels:
app: gamilit
component: backend
tier: api
template:
metadata:
labels:
app: gamilit
component: backend
tier: api
version: v1.0.0
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "3006"
prometheus.io/path: "/metrics"
spec:
# Security context for pod
securityContext:
runAsNonRoot: true
runAsUser: 1001
fsGroup: 1001
seccompProfile:
type: RuntimeDefault
# Service account (for RBAC)
serviceAccountName: gamilit-backend
# Init containers (run before main container)
initContainers:
# Check database connectivity before starting
- name: wait-for-database
image: postgres:16-alpine
command:
- sh
- -c
- |
echo "Waiting for PostgreSQL to be ready..."
until pg_isready -h gamilit-postgres -p 5432 -U gamilit_user; do
echo "PostgreSQL is unavailable - sleeping"
sleep 2
done
echo "PostgreSQL is ready!"
env:
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: gamilit-db-secret
key: password
# Main application containers
containers:
- name: backend
image: ghcr.io/gamilit/backend:1.0.0 # Replace with your registry
imagePullPolicy: Always
# Security context for container
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1001
capabilities:
drop:
- ALL
ports:
- name: http
containerPort: 3006
protocol: TCP
# Environment variables
env:
# General
- name: NODE_ENV
value: "production"
- name: PORT
value: "3006"
- name: LOG_LEVEL
value: "info"
# Database - Connection from ConfigMap
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: gamilit-backend-config
key: db_host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: gamilit-backend-config
key: db_port
- name: DB_NAME
valueFrom:
configMapKeyRef:
name: gamilit-backend-config
key: db_name
- name: DB_USER
valueFrom:
secretKeyRef:
name: gamilit-db-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: gamilit-db-secret
key: password
- name: DB_POOL_MIN
value: "10"
- name: DB_POOL_MAX
value: "100"
- name: DB_SSL
value: "true"
# JWT Secrets
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: gamilit-jwt-secret
key: jwt_secret
- name: JWT_EXPIRES_IN
value: "7d"
- name: JWT_REFRESH_EXPIRES_IN
value: "30d"
# CORS
- name: CORS_ORIGIN
valueFrom:
configMapKeyRef:
name: gamilit-backend-config
key: cors_origin
# Redis (optional)
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: gamilit-redis-secret
key: redis_url
optional: true
# Resource limits and requests
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 500m
memory: 1Gi
# Liveness probe - restart if unhealthy
livenessProbe:
httpGet:
path: /api/health
port: http
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
# Readiness probe - remove from service if not ready
readinessProbe:
httpGet:
path: /api/health
port: http
scheme: HTTP
initialDelaySeconds: 15
periodSeconds: 5
timeoutSeconds: 3
successThreshold: 1
failureThreshold: 2
# Startup probe - for slow-starting containers
startupProbe:
httpGet:
path: /api/health
port: http
initialDelaySeconds: 0
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 30 # 30 * 5s = 150s max startup time
# Volume mounts
volumeMounts:
- name: tmp
mountPath: /tmp
- name: logs
mountPath: /app/logs
# Volumes
volumes:
- name: tmp
emptyDir: {}
- name: logs
emptyDir: {}
# Node affinity (prefer different nodes for HA)
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: component
operator: In
values:
- backend
topologyKey: kubernetes.io/hostname
# Tolerations (if using tainted nodes)
tolerations:
- key: "app"
operator: "Equal"
value: "gamilit"
effect: "NoSchedule"
# DNS policy
dnsPolicy: ClusterFirst
# Restart policy
restartPolicy: Always
# Termination grace period
terminationGracePeriodSeconds: 30
---
# =============================================================================
# GAMILIT Backend - Service Account
# =============================================================================
apiVersion: v1
kind: ServiceAccount
metadata:
name: gamilit-backend
namespace: gamilit-production
labels:
app: gamilit
component: backend
---
# =============================================================================
# GAMILIT Backend - ConfigMap
# =============================================================================
apiVersion: v1
kind: ConfigMap
metadata:
name: gamilit-backend-config
namespace: gamilit-production
labels:
app: gamilit
component: backend
data:
# Database
db_host: "gamilit-postgres.gamilit-production.svc.cluster.local"
db_port: "5432"
db_name: "gamilit_platform"
# CORS
cors_origin: "https://gamilit.com,https://www.gamilit.com"
# Application
node_env: "production"
port: "3006"
log_level: "info"