Update Helm chart to use unified app image (API + Frontend)

Changes:
- Replaced separate api and frontend deployments with single unified app deployment
- Updated values.yaml: Changed from api/frontend configs to single app config
- Renamed templates: api-deployment.yaml → app-deployment.yaml
- Removed frontend-deployment.yaml and frontend-service.yaml (no longer needed)
- Updated app image to warehouse13/app (multi-stage Docker build)
- Combined resource allocations: 384Mi memory, 350m CPU (up from separate totals)
- Updated all example values files (dev, production, air-gapped)
- Updated NOTES.txt to reflect single service on port 8000
- Updated ingress to route all traffic to single app service
- Added ARCHITECTURE.md documenting the unified container approach

Architecture:
The application now uses a multi-stage Docker build:
1. Stage 1: Builds Angular frontend with Node
2. Stage 2: Python FastAPI backend that serves static frontend from /static

Benefits:
- Simplified deployment (1 container instead of 2)
- Reduced resource usage (no separate nginx)
- Easier scaling (1 deployment to manage)
- Consistent versioning (frontend/backend always match)

Access pattern:
- http://localhost:8000     → Angular frontend
- http://localhost:8000/api → FastAPI REST API
- http://localhost:8000/docs → API documentation
- http://localhost:8000/health → Health check

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-16 17:11:39 -05:00
parent 59001222a0
commit 4641cbb3fa
11 changed files with 355 additions and 251 deletions

View File

@@ -19,18 +19,13 @@ Namespace: {{ .Release.Namespace }}
DEPLOYMENT INFORMATION:
{{- if .Values.frontend.enabled }}
Frontend:
Service: warehouse13-frontend
Replicas: {{ .Values.frontend.replicas }}
Image: {{ .Values.frontend.image.repository }}:{{ .Values.frontend.image.tag }}
{{- end }}
{{- if .Values.api.enabled }}
API:
Service: warehouse13-api
Replicas: {{ .Values.api.replicas }}
Image: {{ .Values.api.image.repository }}:{{ .Values.api.image.tag }}
{{- if .Values.app.enabled }}
Application (Unified API + Frontend):
Service: warehouse13-app
Replicas: {{ .Values.app.replicas }}
Image: {{ .Values.app.image.repository }}:{{ .Values.app.image.tag }}
Port: {{ .Values.app.service.port }}
Note: Multi-stage build includes both Angular frontend and FastAPI backend
{{- end }}
{{- if .Values.postgres.enabled }}
@@ -62,13 +57,12 @@ ACCESSING YOUR APPLICATION:
1. Using Port Forwarding:
# Frontend
kubectl port-forward -n {{ .Release.Namespace }} svc/warehouse13-frontend 4200:80
Then visit: http://localhost:4200
# API
kubectl port-forward -n {{ .Release.Namespace }} svc/warehouse13-api 8000:8000
Then visit: http://localhost:8000/docs
# Application (Frontend + API)
kubectl port-forward -n {{ .Release.Namespace }} svc/warehouse13-app 8000:8000
Then visit:
- Frontend: http://localhost:8000
- API Docs: http://localhost:8000/docs
- Health: http://localhost:8000/health
# MinIO Console
kubectl port-forward -n {{ .Release.Namespace }} svc/warehouse13-minio 9001:9001
@@ -91,8 +85,7 @@ CHECKING STATUS:
kubectl get svc -n {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }}
# View logs
kubectl logs -n {{ .Release.Namespace }} -l app.kubernetes.io/component=api -f
kubectl logs -n {{ .Release.Namespace }} -l app.kubernetes.io/component=frontend -f
kubectl logs -n {{ .Release.Namespace }} -l app.kubernetes.io/component=app -f
---

View File

@@ -1,32 +1,32 @@
{{- if .Values.api.enabled }}
{{- if .Values.app.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: warehouse13-api
name: warehouse13-app
labels:
{{- include "warehouse13.labels" . | nindent 4 }}
app.kubernetes.io/component: api
app.kubernetes.io/component: app
spec:
replicas: {{ .Values.api.replicas }}
replicas: {{ .Values.app.replicas }}
selector:
matchLabels:
{{- include "warehouse13.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: api
app.kubernetes.io/component: app
template:
metadata:
labels:
{{- include "warehouse13.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: api
app.kubernetes.io/component: app
spec:
serviceAccountName: {{ include "warehouse13.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: api
- name: app
securityContext:
{{- toYaml .Values.securityContext | nindent 10 }}
image: "{{ .Values.api.image.repository }}:{{ .Values.api.image.tag }}"
imagePullPolicy: {{ .Values.api.image.pullPolicy }}
image: "{{ .Values.app.image.repository }}:{{ .Values.app.image.tag }}"
imagePullPolicy: {{ .Values.app.image.pullPolicy }}
ports:
- name: http
containerPort: 8000
@@ -57,26 +57,30 @@ spec:
secretKeyRef:
name: warehouse13-secrets
key: minio-root-password
- name: MINIO_BUCKET_NAME
value: "test-artifacts"
- name: MINIO_SECURE
value: "false"
- name: DEPLOYMENT_MODE
valueFrom:
configMapKeyRef:
name: warehouse13-config
key: DEPLOYMENT_MODE
resources:
{{- toYaml .Values.api.resources | nindent 10 }}
{{- if .Values.api.healthCheck.enabled }}
{{- toYaml .Values.app.resources | nindent 10 }}
{{- if .Values.app.healthCheck.enabled }}
livenessProbe:
httpGet:
path: {{ .Values.api.healthCheck.liveness.path }}
path: {{ .Values.app.healthCheck.liveness.path }}
port: http
initialDelaySeconds: {{ .Values.api.healthCheck.liveness.initialDelaySeconds }}
periodSeconds: {{ .Values.api.healthCheck.liveness.periodSeconds }}
initialDelaySeconds: {{ .Values.app.healthCheck.liveness.initialDelaySeconds }}
periodSeconds: {{ .Values.app.healthCheck.liveness.periodSeconds }}
readinessProbe:
httpGet:
path: {{ .Values.api.healthCheck.readiness.path }}
path: {{ .Values.app.healthCheck.readiness.path }}
port: http
initialDelaySeconds: {{ .Values.api.healthCheck.readiness.initialDelaySeconds }}
periodSeconds: {{ .Values.api.healthCheck.readiness.periodSeconds }}
initialDelaySeconds: {{ .Values.app.healthCheck.readiness.initialDelaySeconds }}
periodSeconds: {{ .Values.app.healthCheck.readiness.periodSeconds }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:

View File

@@ -1,19 +1,19 @@
{{- if .Values.api.enabled }}
{{- if .Values.app.enabled }}
apiVersion: v1
kind: Service
metadata:
name: warehouse13-api
name: warehouse13-app
labels:
{{- include "warehouse13.labels" . | nindent 4 }}
app.kubernetes.io/component: api
app.kubernetes.io/component: app
spec:
type: {{ .Values.api.service.type }}
type: {{ .Values.app.service.type }}
ports:
- port: {{ .Values.api.service.port }}
- port: {{ .Values.app.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "warehouse13.selectorLabels" . | nindent 4 }}
app.kubernetes.io/component: api
app.kubernetes.io/component: app
{{- end }}

View File

@@ -1,73 +0,0 @@
{{- if .Values.frontend.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: warehouse13-frontend
labels:
{{- include "warehouse13.labels" . | nindent 4 }}
app.kubernetes.io/component: frontend
spec:
replicas: {{ .Values.frontend.replicas }}
selector:
matchLabels:
{{- include "warehouse13.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: frontend
template:
metadata:
labels:
{{- include "warehouse13.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: frontend
spec:
serviceAccountName: {{ include "warehouse13.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: frontend
securityContext:
{{- toYaml .Values.securityContext | nindent 10 }}
image: "{{ .Values.frontend.image.repository }}:{{ .Values.frontend.image.tag }}"
imagePullPolicy: {{ .Values.frontend.image.pullPolicy }}
ports:
- name: http
containerPort: 80
protocol: TCP
env:
- name: DEPLOYMENT_MODE
valueFrom:
configMapKeyRef:
name: warehouse13-config
key: DEPLOYMENT_MODE
- name: STORAGE_BACKEND
valueFrom:
configMapKeyRef:
name: warehouse13-config
key: STORAGE_BACKEND
resources:
{{- toYaml .Values.frontend.resources | nindent 10 }}
{{- if .Values.frontend.healthCheck.enabled }}
livenessProbe:
httpGet:
path: {{ .Values.frontend.healthCheck.liveness.path }}
port: http
initialDelaySeconds: {{ .Values.frontend.healthCheck.liveness.initialDelaySeconds }}
periodSeconds: {{ .Values.frontend.healthCheck.liveness.periodSeconds }}
readinessProbe:
httpGet:
path: {{ .Values.frontend.healthCheck.readiness.path }}
port: http
initialDelaySeconds: {{ .Values.frontend.healthCheck.readiness.initialDelaySeconds }}
periodSeconds: {{ .Values.frontend.healthCheck.readiness.periodSeconds }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}

View File

@@ -1,19 +0,0 @@
{{- if .Values.frontend.enabled }}
apiVersion: v1
kind: Service
metadata:
name: warehouse13-frontend
labels:
{{- include "warehouse13.labels" . | nindent 4 }}
app.kubernetes.io/component: frontend
spec:
type: {{ .Values.frontend.service.type }}
ports:
- port: {{ .Values.frontend.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "warehouse13.selectorLabels" . | nindent 4 }}
app.kubernetes.io/component: frontend
{{- end }}

View File

@@ -35,7 +35,7 @@ spec:
service:
name: {{ printf "warehouse13-%s" .backend }}
port:
number: {{ if eq .backend "frontend" }}{{ $.Values.frontend.service.port }}{{ else }}{{ $.Values.api.service.port }}{{ end }}
number: {{ $.Values.app.service.port }}
{{- end }}
{{- end }}
{{- end }}