From 954387a8cfae058f1b612c2b56a6af86869f96a2 Mon Sep 17 00:00:00 2001 From: "Ehsan.Asadi" Date: Tue, 30 Dec 2025 20:55:11 +0330 Subject: [PATCH] [FEAT] Add separate frontend/backend Ingress and runtime API_URL configuration - Add two Ingress: peikarband.ir (frontend) and api.peikarband.ir (backend) - Add runtime script to update .web/env.json from API_URL env var - Remove --backend-only flag to enable both frontend and backend - Configure API_URL from Helm values instead of build-time args - Update .dockerignore to include update-env-json.sh script --- Dockerfile | 8 ++- helm/peikarband/templates/ingress.yaml | 47 +++++++++++++++++- helm/peikarband/values-production.yaml | 18 ++++++- helm/peikarband/values.yaml | 9 ++++ scripts/update-env-json.sh | 69 ++++++++++++++++++++++++++ 5 files changed, 147 insertions(+), 4 deletions(-) create mode 100755 scripts/update-env-json.sh diff --git a/Dockerfile b/Dockerfile index c8f69b6..eb02497 100644 --- a/Dockerfile +++ b/Dockerfile @@ -63,6 +63,7 @@ RUN pip install --no-cache-dir --upgrade pip setuptools wheel && \ COPY --chown=root:root . . # Build and export Reflex app for production +# Note: API_URL will be updated at runtime from environment variable # Export creates .web directory with frontend static files # bun is now pre-installed, so reflex export won't try to download it RUN python -m reflex export --no-zip @@ -128,6 +129,10 @@ COPY --from=builder /root/.local /home/peikarband/.local # Copy application code from builder COPY --from=builder /build /app +# Copy and set up runtime script +COPY --chown=peikarband:peikarband scripts/update-env-json.sh /app/scripts/update-env-json.sh +RUN chmod +x /app/scripts/update-env-json.sh + # Fix ownership RUN chown -R peikarband:peikarband /home/peikarband/.local /app @@ -159,7 +164,8 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD curl -f -s -o /dev/null -w "%{http_code}" http://localhost:8000/ping | grep -q "200" || exit 1 # Use tini as init system for proper signal handling -ENTRYPOINT ["/usr/bin/tini", "--"] +# Update .web/env.json from API_URL env var, then run the app +ENTRYPOINT ["/usr/bin/tini", "--", "/app/scripts/update-env-json.sh"] # Run application (both frontend and backend) CMD ["python", "-m", "reflex", "run", "--env", "prod"] diff --git a/helm/peikarband/templates/ingress.yaml b/helm/peikarband/templates/ingress.yaml index 6c722fe..f624994 100644 --- a/helm/peikarband/templates/ingress.yaml +++ b/helm/peikarband/templates/ingress.yaml @@ -1,8 +1,9 @@ {{- if .Values.ingress.enabled -}} +# Frontend Ingress (peikarband.ir -> port 3000) apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - name: {{ include "peikarband.fullname" . }} + name: {{ include "peikarband.fullname" . }}-frontend labels: {{- include "peikarband.labels" . | nindent 4 }} {{- with .Values.ingress.annotations }} @@ -35,8 +36,50 @@ spec: service: name: {{ include "peikarband.fullname" $ }} port: - number: {{ $.Values.service.backend.port }} + number: {{ $.Values.service.frontend.port }} {{- end }} {{- end }} {{- end }} +{{- if .Values.ingress.apiEnabled -}} +# Backend API Ingress (api.peikarband.ir -> port 8000) +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "peikarband.fullname" . }}-api + labels: + {{- include "peikarband.labels" . | nindent 4 }} + {{- with .Values.ingress.apiAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.apiTls }} + tls: + {{- range .Values.ingress.apiTls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.apiHosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "peikarband.fullname" $ }} + port: + number: {{ $.Values.service.backend.port }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/peikarband/values-production.yaml b/helm/peikarband/values-production.yaml index d148409..cc1a810 100644 --- a/helm/peikarband/values-production.yaml +++ b/helm/peikarband/values-production.yaml @@ -27,7 +27,7 @@ appSecrets: # Reflex configuration for production reflex: - apiUrl: "https://peikarband.ir" # Production API URL + apiUrl: "https://api.peikarband.ir" # Production API URL (backend) podAnnotations: prometheus.io/scrape: "true" @@ -72,6 +72,22 @@ ingress: hosts: - peikarband.ir - www.peikarband.ir + + # Backend API Ingress (api.peikarband.ir -> port 8000) + apiEnabled: true + apiAnnotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + traefik.ingress.kubernetes.io/router.entrypoints: "websecure" + traefik.ingress.kubernetes.io/router.tls: "true" + apiHosts: + - host: api.peikarband.ir + paths: + - path: / + pathType: Prefix + apiTls: + - secretName: peikarband-api-tls + hosts: + - api.peikarband.ir postgresql: enabled: false # Using SQLite for now diff --git a/helm/peikarband/values.yaml b/helm/peikarband/values.yaml index 46094e9..9e6e857 100644 --- a/helm/peikarband/values.yaml +++ b/helm/peikarband/values.yaml @@ -81,6 +81,15 @@ ingress: hosts: - peikarband.ir - www.peikarband.ir + + # Backend API Ingress (api.peikarband.ir -> port 8000) + apiEnabled: false # Enable in production values + apiAnnotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + traefik.ingress.kubernetes.io/router.entrypoints: "websecure" + traefik.ingress.kubernetes.io/router.tls: "true" + apiHosts: [] + apiTls: [] resources: limits: diff --git a/scripts/update-env-json.sh b/scripts/update-env-json.sh new file mode 100755 index 0000000..34259a5 --- /dev/null +++ b/scripts/update-env-json.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# Update .web/env.json with API_URL from environment variable at runtime + +set -e + +API_URL="${API_URL:-http://localhost:8000}" + +# Extract protocol, host, and port from API_URL +if [[ "$API_URL" =~ ^(https?://)([^:/]+)(:([0-9]+))? ]]; then + PROTOCOL="${BASH_REMATCH[1]}" + HOST="${BASH_REMATCH[2]}" + PORT="${BASH_REMATCH[4]:-8000}" + + # Remove trailing slash + API_URL="${API_URL%/}" + + # Update .web/env.json + if [ -f "/app/.web/env.json" ]; then + # Use Python to properly update JSON + python3 <