# Student Enrollment System - K3s All-in-One Deployment # Deploy: kubectl apply -f all-in-one.yaml # Delete: kubectl delete -f all-in-one.yaml --- apiVersion: v1 kind: Namespace metadata: name: student-enrollment --- # ===== SECRETS ===== apiVersion: v1 kind: Secret metadata: name: app-secrets namespace: student-enrollment type: Opaque stringData: SA_PASSWORD: "Admin123!" JWT_SECRET: "super-secret-key-for-jwt-tokens-minimum-32-chars-long!" ADMIN_PASSWORD: "admin123" --- # ===== SQL SERVER ===== apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mssql-data namespace: student-enrollment spec: accessModes: [ReadWriteOnce] resources: requests: storage: 2Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: mssql namespace: student-enrollment spec: replicas: 1 selector: matchLabels: app: mssql template: metadata: labels: app: mssql spec: containers: - name: mssql image: mcr.microsoft.com/mssql/server:2022-latest ports: - containerPort: 1433 env: - name: ACCEPT_EULA value: "Y" - name: MSSQL_SA_PASSWORD valueFrom: secretKeyRef: name: app-secrets key: SA_PASSWORD resources: limits: memory: "2Gi" cpu: "1000m" requests: memory: "1Gi" cpu: "500m" volumeMounts: - name: mssql-data mountPath: /var/opt/mssql readinessProbe: exec: command: ["/opt/mssql-tools18/bin/sqlcmd", "-S", "localhost", "-U", "sa", "-P", "$(MSSQL_SA_PASSWORD)", "-C", "-Q", "SELECT 1"] initialDelaySeconds: 30 periodSeconds: 10 volumes: - name: mssql-data persistentVolumeClaim: claimName: mssql-data --- apiVersion: v1 kind: Service metadata: name: mssql namespace: student-enrollment spec: selector: app: mssql ports: - port: 1433 targetPort: 1433 --- # ===== BACKEND API ===== apiVersion: apps/v1 kind: Deployment metadata: name: api namespace: student-enrollment spec: replicas: 2 selector: matchLabels: app: api template: metadata: labels: app: api spec: initContainers: - name: wait-for-db image: busybox:1.36 command: ['sh', '-c', 'until nc -z mssql 1433; do echo waiting for mssql; sleep 5; done'] containers: - name: api image: student-enrollment-api:latest imagePullPolicy: IfNotPresent ports: - containerPort: 8080 env: - name: ASPNETCORE_ENVIRONMENT value: "Production" - name: ASPNETCORE_URLS value: "http://+:8080" - name: ConnectionStrings__DefaultConnection value: "Server=mssql;Database=StudentEnrollment;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True" - name: SA_PASSWORD valueFrom: secretKeyRef: name: app-secrets key: SA_PASSWORD - name: JwtSettings__Secret valueFrom: secretKeyRef: name: app-secrets key: JWT_SECRET - name: JwtSettings__Issuer value: "student-enrollment-api" - name: JwtSettings__Audience value: "student-enrollment-app" - name: JwtSettings__ExpirationMinutes value: "60" - name: ADMIN_USERNAME value: "admin" - name: ADMIN_PASSWORD valueFrom: secretKeyRef: name: app-secrets key: ADMIN_PASSWORD resources: limits: memory: "512Mi" cpu: "500m" requests: memory: "256Mi" cpu: "250m" readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 15 periodSeconds: 10 livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 30 --- apiVersion: v1 kind: Service metadata: name: api namespace: student-enrollment spec: selector: app: api ports: - port: 5000 targetPort: 8080 --- # ===== FRONTEND ===== apiVersion: apps/v1 kind: Deployment metadata: name: frontend namespace: student-enrollment spec: replicas: 2 selector: matchLabels: app: frontend template: metadata: labels: app: frontend spec: containers: - name: frontend image: student-enrollment-frontend:latest imagePullPolicy: IfNotPresent ports: - containerPort: 80 resources: limits: memory: "128Mi" cpu: "100m" requests: memory: "64Mi" cpu: "50m" readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 periodSeconds: 10 --- apiVersion: v1 kind: Service metadata: name: frontend namespace: student-enrollment spec: selector: app: frontend ports: - port: 80 targetPort: 80 --- # ===== INGRESS ===== apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: student-enrollment-ingress namespace: student-enrollment annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: traefik rules: - host: students.local http: paths: - path: /graphql pathType: Prefix backend: service: name: api port: number: 5000 - path: /health pathType: Prefix backend: service: name: api port: number: 5000 - path: / pathType: Prefix backend: service: name: frontend port: number: 80