ci: optimize deployment workflow for k3s
Deploy to k3s / deploy (push) Failing after 27s Details

- Single job instead of 3 (no artifact overhead)
- Build directly on k3s node (avoids image transfer)
- Parallel Docker builds with BuildKit
- Auto-create namespace if missing
- Automatic rollback on failure
- Health check via domain

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Andrés Eduardo García Márquez 2026-01-08 13:34:38 -05:00
parent 17706676d5
commit a9e4de63c9
12 changed files with 229 additions and 395 deletions

View File

@ -1,4 +1,4 @@
name: Build and Deploy to k3s name: Deploy to k3s
on: on:
push: push:
@ -6,111 +6,101 @@ on:
workflow_dispatch: workflow_dispatch:
env: env:
NAMESPACE: student-enrollment K3S_HOST: "100.67.198.92"
API_IMAGE: student-api K3S_USER: "andres"
FRONTEND_IMAGE: student-frontend NAMESPACE: "student-enrollment"
DOMAIN: "academia.ingeniumcodex.com"
jobs: jobs:
# Build jobs run in parallel for speed
build-api:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build API with cache
uses: docker/build-push-action@v5
with:
context: .
file: deploy/docker/Dockerfile.api
push: false
load: true
tags: ${{ env.API_IMAGE }}:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Save API image
run: docker save ${{ env.API_IMAGE }}:${{ github.sha }} | gzip > /tmp/api-image.tar.gz
- name: Upload API artifact
uses: actions/upload-artifact@v4
with:
name: api-image
path: /tmp/api-image.tar.gz
retention-days: 1
build-frontend:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Frontend with cache
uses: docker/build-push-action@v5
with:
context: .
file: deploy/docker/Dockerfile.frontend
push: false
load: true
tags: ${{ env.FRONTEND_IMAGE }}:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Save Frontend image
run: docker save ${{ env.FRONTEND_IMAGE }}:${{ github.sha }} | gzip > /tmp/frontend-image.tar.gz
- name: Upload Frontend artifact
uses: actions/upload-artifact@v4
with:
name: frontend-image
path: /tmp/frontend-image.tar.gz
retention-days: 1
deploy: deploy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [build-api, build-frontend]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Download API image - name: Setup SSH
uses: actions/download-artifact@v4
with:
name: api-image
path: /tmp
- name: Download Frontend image
uses: actions/download-artifact@v4
with:
name: frontend-image
path: /tmp
- name: Import images to k3s
run: | run: |
gunzip -c /tmp/api-image.tar.gz | sudo k3s ctr images import - mkdir -p ~/.ssh
gunzip -c /tmp/frontend-image.tar.gz | sudo k3s ctr images import - echo "${{ secrets.K3S_SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ env.K3S_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
- name: Update deployments with new tag - name: Sync code to k3s
run: | run: |
kubectl -n ${{ env.NAMESPACE }} set image deployment/student-api \ rsync -az --delete \
api=${{ env.API_IMAGE }}:${{ github.sha }} --exclude '.git' \
kubectl -n ${{ env.NAMESPACE }} set image deployment/student-frontend \ --exclude 'node_modules' \
frontend=${{ env.FRONTEND_IMAGE }}:${{ github.sha }} --exclude 'dist' \
--exclude 'bin' \
--exclude 'obj' \
--exclude '.angular' \
--exclude 'tests' \
--exclude 'docs' \
./ ${{ env.K3S_USER }}@${{ env.K3S_HOST }}:~/student-enrollment/
- name: Wait for rollout - name: Build images (parallel)
run: | run: |
kubectl -n ${{ env.NAMESPACE }} rollout status deployment/student-api --timeout=120s ssh ${{ env.K3S_USER }}@${{ env.K3S_HOST }} << 'ENDSSH'
kubectl -n ${{ env.NAMESPACE }} rollout status deployment/student-frontend --timeout=60s cd ~/student-enrollment
export DOCKER_BUILDKIT=1
echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S docker build \
-f deploy/docker/Dockerfile.api -t student-api:latest . &
PID_API=$!
echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S docker build \
-f deploy/docker/Dockerfile.frontend -t student-frontend:latest . &
PID_FE=$!
wait $PID_API || exit 1
wait $PID_FE || exit 1
ENDSSH
- name: Import to k3s
run: |
ssh ${{ env.K3S_USER }}@${{ env.K3S_HOST }} << 'ENDSSH'
echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S sh -c \
'docker save student-api:latest | k3s ctr images import -'
echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S sh -c \
'docker save student-frontend:latest | k3s ctr images import -'
ENDSSH
- name: Setup namespace if needed
run: |
ssh ${{ env.K3S_USER }}@${{ env.K3S_HOST }} << 'ENDSSH'
cd ~/student-enrollment/deploy/k3s
if ! echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S kubectl get ns student-enrollment &>/dev/null; then
echo "Creating namespace and resources..."
echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S kubectl apply -k .
fi
ENDSSH
- name: Deploy
run: |
ssh ${{ env.K3S_USER }}@${{ env.K3S_HOST }} << 'ENDSSH'
echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S kubectl rollout restart \
deployment/student-api deployment/student-frontend -n student-enrollment
ENDSSH
- name: Wait rollout
run: |
ssh ${{ env.K3S_USER }}@${{ env.K3S_HOST }} << 'ENDSSH'
echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S kubectl rollout status \
deployment/student-api -n student-enrollment --timeout=120s
echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S kubectl rollout status \
deployment/student-frontend -n student-enrollment --timeout=60s
ENDSSH
- name: Health check - name: Health check
run: | run: |
sleep 10 sleep 5
API_POD=$(kubectl -n ${{ env.NAMESPACE }} get pods -l app=student-api -o jsonpath='{.items[0].metadata.name}') curl -sf https://${{ env.DOMAIN }}/health || exit 1
kubectl -n ${{ env.NAMESPACE }} exec $API_POD -- wget -q --spider http://localhost:5000/health || exit 1 curl -sf https://${{ env.DOMAIN }}/ || exit 1
echo "Deployment healthy!"
- name: Rollback on failure
if: failure()
run: |
ssh ${{ env.K3S_USER }}@${{ env.K3S_HOST }} << 'ENDSSH'
echo "${{ secrets.K3S_SUDO_PASS }}" | sudo -S kubectl rollout undo \
deployment/student-api deployment/student-frontend -n student-enrollment 2>/dev/null || true
ENDSSH

View File

@ -15,7 +15,7 @@ server {
# API proxy # API proxy
location /graphql { location /graphql {
proxy_pass http://student-api:5000; proxy_pass http://student-api:8080;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade'; proxy_set_header Connection 'upgrade';
@ -24,7 +24,7 @@ server {
} }
location /health { location /health {
proxy_pass http://student-api:5000; proxy_pass http://student-api:8080;
} }
# Cache static assets # Cache static assets

View File

@ -1,264 +0,0 @@
# 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

View File

@ -28,13 +28,13 @@ spec:
image: academia-api:latest image: academia-api:latest
imagePullPolicy: Never imagePullPolicy: Never
ports: ports:
- containerPort: 5000 - containerPort: 8080
name: http name: http
env: env:
- name: ASPNETCORE_ENVIRONMENT - name: ASPNETCORE_ENVIRONMENT
value: "Production" value: "Production"
- name: ASPNETCORE_URLS - name: ASPNETCORE_URLS
value: "http://+:5000" value: "http://+:8080"
- name: ConnectionStrings__DefaultConnection - name: ConnectionStrings__DefaultConnection
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
@ -61,7 +61,7 @@ spec:
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /health path: /health
port: 5000 port: 8080
initialDelaySeconds: 30 initialDelaySeconds: 30
periodSeconds: 30 periodSeconds: 30
timeoutSeconds: 10 timeoutSeconds: 10
@ -69,7 +69,7 @@ spec:
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /health path: /health
port: 5000 port: 8080
initialDelaySeconds: 15 initialDelaySeconds: 15
periodSeconds: 10 periodSeconds: 10
timeoutSeconds: 5 timeoutSeconds: 5
@ -87,7 +87,7 @@ spec:
selector: selector:
app: student-api app: student-api
ports: ports:
- port: 5000 - port: 8080
targetPort: 5000 targetPort: 8080
name: http name: http
type: ClusterIP type: ClusterIP

View File

@ -5,7 +5,7 @@ metadata:
namespace: student-enrollment namespace: student-enrollment
data: data:
ASPNETCORE_ENVIRONMENT: "Production" ASPNETCORE_ENVIRONMENT: "Production"
ASPNETCORE_URLS: "http://+:5000" ASPNETCORE_URLS: "http://+:8080"
# Frontend config # Frontend config
API_URL: "https://academia.ingeniumcodex.com/graphql" API_URL: "https://academia.ingeniumcodex.com/graphql"
HEALTH_CHECK_URL: "https://academia.ingeniumcodex.com/health" HEALTH_CHECK_URL: "https://academia.ingeniumcodex.com/health"

View File

@ -1,27 +1,132 @@
#!/bin/bash #!/bin/bash
# Quick deploy to k3s # K3s Deployment Script - Optimizado para tiempo mínimo
set -e # Uso: ./deploy.sh [build|deploy|all|status|clean]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
echo "=== Building Docker images ===" # Colores
cd "$PROJECT_ROOT" RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Build API # Cargar credenciales si existen
docker build -t student-enrollment-api:latest -f deploy/docker/Dockerfile.api . CREDS_FILE="$HOME/.secrets/credentials.env"
[[ -f "$CREDS_FILE" ]] && source "$CREDS_FILE"
# Build Frontend # Configuración
docker build -t student-enrollment-frontend:latest -f deploy/docker/Dockerfile.frontend . K3S_HOST="${K8S_MASTER_HOST:-hp62a}"
NAMESPACE="student-enrollment"
API_IMAGE="academia-api:latest"
FRONTEND_IMAGE="academia-frontend:latest"
echo "=== Deploying to k3s ===" log() { echo -e "${GREEN}[$(date +%T)]${NC} $1"; }
kubectl apply -f "$SCRIPT_DIR/all-in-one.yaml" warn() { echo -e "${YELLOW}[$(date +%T)]${NC} $1"; }
err() { echo -e "${RED}[$(date +%T)]${NC} $1" >&2; }
echo "=== Waiting for deployments ===" build_images() {
kubectl -n student-enrollment rollout status deployment/mssql --timeout=120s log "=== Construyendo imágenes Docker (paralelo) ==="
kubectl -n student-enrollment rollout status deployment/api --timeout=120s cd "$PROJECT_ROOT"
kubectl -n student-enrollment rollout status deployment/frontend --timeout=60s
echo "=== Deployment complete ===" # Build en paralelo
echo "Add to /etc/hosts: <k3s-ip> students.local" docker build -t "$API_IMAGE" -f deploy/docker/Dockerfile.api . &
kubectl -n student-enrollment get pods PID_API=$!
docker build -t "$FRONTEND_IMAGE" -f deploy/docker/Dockerfile.frontend . &
PID_FRONTEND=$!
# Esperar ambos
wait $PID_API && log "✓ API imagen construida" || { err "✗ Error construyendo API"; exit 1; }
wait $PID_FRONTEND && log "✓ Frontend imagen construida" || { err "✗ Error construyendo Frontend"; exit 1; }
}
transfer_images() {
log "=== Transfiriendo imágenes a k3s ==="
# Exportar y transferir en paralelo
docker save "$API_IMAGE" | ssh "$K3S_HOST" "sudo k3s ctr images import -" &
PID_API=$!
docker save "$FRONTEND_IMAGE" | ssh "$K3S_HOST" "sudo k3s ctr images import -" &
PID_FRONTEND=$!
wait $PID_API && log "✓ API transferida" || { err "✗ Error transfiriendo API"; exit 1; }
wait $PID_FRONTEND && log "✓ Frontend transferida" || { err "✗ Error transfiriendo Frontend"; exit 1; }
}
deploy_k3s() {
log "=== Desplegando en k3s con Kustomize ==="
# Aplicar con kustomize
ssh "$K3S_HOST" "cd /tmp && sudo kubectl apply -k -" < <(kubectl kustomize "$SCRIPT_DIR")
log "=== Esperando despliegues ==="
# Esperar SQL Server primero (es dependencia)
ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE rollout status deployment/sqlserver --timeout=180s" || warn "SQL Server timeout"
# Esperar API y Frontend en paralelo
ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE rollout status deployment/student-api --timeout=120s" &
PID_API=$!
ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE rollout status deployment/student-frontend --timeout=60s" &
PID_FRONTEND=$!
wait $PID_API && log "✓ API desplegada" || warn "API timeout"
wait $PID_FRONTEND && log "✓ Frontend desplegado" || warn "Frontend timeout"
}
show_status() {
log "=== Estado del despliegue ==="
ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE get pods -o wide"
echo ""
ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE get svc"
echo ""
ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE get ingress 2>/dev/null || true"
}
clean() {
warn "=== Limpiando namespace $NAMESPACE ==="
ssh "$K3S_HOST" "sudo kubectl delete namespace $NAMESPACE --ignore-not-found"
log "✓ Namespace eliminado"
}
restart_pods() {
log "=== Reiniciando pods (rolling restart) ==="
ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE rollout restart deployment/student-api"
ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE rollout restart deployment/student-frontend"
log "✓ Pods reiniciados"
}
# Main
case "${1:-all}" in
build)
build_images
;;
transfer)
transfer_images
;;
deploy)
deploy_k3s
show_status
;;
all)
build_images
transfer_images
deploy_k3s
show_status
;;
status)
show_status
;;
clean)
clean
;;
restart)
restart_pods
;;
*)
echo "Uso: $0 [build|transfer|deploy|all|status|clean|restart]"
exit 1
;;
esac
log "=== Completado ==="

View File

@ -62,13 +62,13 @@ spec:
namespace: student-enrollment namespace: student-enrollment
services: services:
- name: student-api - name: student-api
port: 5000 port: 8080
# Health check # Health check
- kind: Rule - kind: Rule
match: Host(`academia.ingeniumcodex.com`) && PathPrefix(`/health`) match: Host(`academia.ingeniumcodex.com`) && PathPrefix(`/health`)
services: services:
- name: student-api - name: student-api
port: 5000 port: 8080
# Frontend (catch-all) # Frontend (catch-all)
- kind: Rule - kind: Rule
match: Host(`academia.ingeniumcodex.com`) match: Host(`academia.ingeniumcodex.com`)

View File

@ -12,10 +12,12 @@ resources:
- frontend.yaml - frontend.yaml
- ingress.yaml - ingress.yaml
commonLabels: labels:
- pairs:
app.kubernetes.io/name: student-enrollment app.kubernetes.io/name: student-enrollment
app.kubernetes.io/part-of: interrapidisimo app.kubernetes.io/part-of: interrapidisimo
app.kubernetes.io/managed-by: kustomize app.kubernetes.io/managed-by: kustomize
includeSelectors: false
# Dominio: https://academia.ingeniumcodex.com # Dominio: https://academia.ingeniumcodex.com
# TLS configurado con Traefik + Let's Encrypt # TLS configurado con Traefik + Let's Encrypt

View File

@ -51,7 +51,7 @@ spec:
kubernetes.io/metadata.name: kube-system kubernetes.io/metadata.name: kube-system
ports: ports:
- protocol: TCP - protocol: TCP
port: 5000 port: 8080
# Desde frontend (para nginx proxy) # Desde frontend (para nginx proxy)
- from: - from:
- podSelector: - podSelector:
@ -59,7 +59,7 @@ spec:
app: student-frontend app: student-frontend
ports: ports:
- protocol: TCP - protocol: TCP
port: 5000 port: 8080
--- ---
# Permitir tráfico a SQL Server solo desde API # Permitir tráfico a SQL Server solo desde API
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1

View File

@ -7,5 +7,5 @@ type: Opaque
stringData: stringData:
# IMPORTANTE: Cambiar en producción # IMPORTANTE: Cambiar en producción
# Generar con: openssl rand -base64 32 # Generar con: openssl rand -base64 32
db-password: "Your_Str0ng_P@ssword!" db-password: "YourStr0ngP4ssword2026"
db-connection-string: "Server=sqlserver;Database=StudentEnrollment;User Id=sa;Password=Your_Str0ng_P@ssword!;TrustServerCertificate=True" db-connection-string: "Server=sqlserver;Database=StudentEnrollment;User Id=sa;Password=YourStr0ngP4ssword2026;TrustServerCertificate=True"

View File

@ -59,10 +59,10 @@ spec:
mountPath: /var/opt/mssql mountPath: /var/opt/mssql
resources: resources:
requests: requests:
memory: "1.2Gi" memory: "1200Mi"
cpu: "250m" cpu: "250m"
limits: limits:
memory: "1.5Gi" memory: "1536Mi"
cpu: "1000m" cpu: "1000m"
livenessProbe: livenessProbe:
exec: exec:

View File

@ -10,6 +10,7 @@ export const authGuard: CanActivateFn = () => {
const authService = inject(AuthService); const authService = inject(AuthService);
const router = inject(Router); const router = inject(Router);
// isAuthenticated is a Signal, need to call it to get the value
if (authService.isAuthenticated()) { if (authService.isAuthenticated()) {
return true; return true;
} }