From 427baf0e719dee701ba092deba0bb35a47610bb3 Mon Sep 17 00:00:00 2001 From: Bakery Admin Date: Sat, 24 Jan 2026 08:39:29 +0100 Subject: [PATCH] Fix Forntend build issues --- frontend/Dockerfile.kubernetes | 76 +++------------------------ frontend/index.html | 3 -- frontend/nginx-main.conf | 12 ----- frontend/src/config/pilot.ts | 94 ++++------------------------------ frontend/src/config/runtime.ts | 72 ++++---------------------- frontend/src/vite-env.d.ts | 20 ++------ frontend/substitute-env.sh | 40 --------------- 7 files changed, 29 insertions(+), 288 deletions(-) delete mode 100644 frontend/nginx-main.conf delete mode 100644 frontend/substitute-env.sh diff --git a/frontend/Dockerfile.kubernetes b/frontend/Dockerfile.kubernetes index f82888b2..131464d0 100644 --- a/frontend/Dockerfile.kubernetes +++ b/frontend/Dockerfile.kubernetes @@ -1,85 +1,21 @@ -# Kubernetes-optimized Dockerfile for Frontend -# Multi-stage build for production deployment +# Frontend Dockerfile for Kubernetes +# Simple two-stage build: node for build, nginx for serve -# Stage 1: Build the application +# Stage 1: Build FROM node:18-alpine AS builder - WORKDIR /app - -# Copy package files COPY package*.json ./ - -# Install all dependencies for building -RUN npm ci --verbose && \ - npm cache clean --force - -# Copy source code (excluding unnecessary files like node_modules, dist, etc.) +RUN npm ci COPY . . - -# Create a default runtime config in the public directory if it doesn't exist to satisfy the reference in index.html -RUN if [ ! -f public/runtime-config.js ]; then \ - mkdir -p public && \ - echo "window.__RUNTIME_CONFIG__ = {};" > public/runtime-config.js; \ - fi - -# Set build-time environment variables to prevent hanging on undefined variables ENV NODE_ENV=production -ENV CI=true ENV VITE_API_URL=/api ENV VITE_APP_TITLE="BakeWise" ENV VITE_APP_VERSION="1.0.0" -ENV VITE_PILOT_MODE_ENABLED="false" -ENV VITE_PILOT_COUPON_CODE="PILOT2025" -ENV VITE_PILOT_TRIAL_MONTHS="3" -ENV VITE_STRIPE_PUBLISHABLE_KEY="pk_test_" -# Set Node.js memory limit for the build process -ENV NODE_OPTIONS="--max-old-space-size=4096" RUN npm run build -# Stage 2: Production server with Nginx -FROM nginx:1.25-alpine AS production - -# Install curl for health checks -RUN apk add --no-cache curl - -# Copy main nginx configuration that sets the PID file location -COPY nginx-main.conf /etc/nginx/nginx.conf - -# Remove default nginx configuration +# Stage 2: Serve with nginx +FROM nginx:1.25-alpine RUN rm /etc/nginx/conf.d/default.conf - -# Copy custom nginx configuration COPY nginx.conf /etc/nginx/conf.d/ - -# Copy built application from builder stage COPY --from=builder /app/dist /usr/share/nginx/html - -# Copy and setup environment substitution script -COPY substitute-env.sh /docker-entrypoint.d/30-substitute-env.sh - -# Make the script executable -RUN chmod +x /docker-entrypoint.d/30-substitute-env.sh - -# Set proper permissions -RUN chown -R nginx:nginx /usr/share/nginx/html && \ - chown -R nginx:nginx /var/cache/nginx && \ - chown -R nginx:nginx /var/log/nginx && \ - chown -R nginx:nginx /etc/nginx/conf.d - -# Create nginx PID directory and fix permissions -RUN mkdir -p /var/run/nginx /var/lib/nginx/tmp && \ - chown -R nginx:nginx /var/run/nginx /var/lib/nginx /etc/nginx - -# Switch to non-root user -USER nginx - -# Expose port 3000 (to match current setup) EXPOSE 3000 - -# Health check -HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ - CMD curl -f http://localhost:3000/health || exit 1 - -# Start nginx -CMD ["nginx", "-g", "daemon off;"] - diff --git a/frontend/index.html b/frontend/index.html index b02906cc..0f6702b6 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -18,9 +18,6 @@ - - - BakeWise - Gestión Inteligente para Panaderías diff --git a/frontend/nginx-main.conf b/frontend/nginx-main.conf deleted file mode 100644 index 0dc97974..00000000 --- a/frontend/nginx-main.conf +++ /dev/null @@ -1,12 +0,0 @@ -pid /var/run/nginx/nginx.pid; -worker_processes auto; - -events { - worker_connections 1024; -} - -http { - include /etc/nginx/mime.types; - default_type application/octet-stream; - include /etc/nginx/conf.d/*.conf; -} \ No newline at end of file diff --git a/frontend/src/config/pilot.ts b/frontend/src/config/pilot.ts index 1f848678..34bc01fd 100644 --- a/frontend/src/config/pilot.ts +++ b/frontend/src/config/pilot.ts @@ -1,92 +1,16 @@ /** * Pilot Program Configuration - * - * Centralized configuration for pilot mode features. - * - * Works in two modes: - * 1. Kubernetes/Docker: Reads from window.__RUNTIME_CONFIG__ (injected at container startup) - * 2. Local Development: Reads from import.meta.env (build-time variables from .env) + * Uses build-time environment variables */ -/** - * Helper function to get environment variable value - * Tries runtime config first (Kubernetes), falls back to build-time (local dev) - */ -const getEnvVar = (key: string): string | undefined => { - // Try runtime config first (Kubernetes/Docker environment) - if (typeof window !== 'undefined' && (window as any).__RUNTIME_CONFIG__) { - const value = (window as any).__RUNTIME_CONFIG__[key]; - if (value !== undefined) { - return value; - } - } - - // Fallback to build-time environment variables (local development) - return import.meta.env[key]; +export const PILOT_CONFIG = { + enabled: import.meta.env.VITE_PILOT_MODE_ENABLED === 'true', + couponCode: import.meta.env.VITE_PILOT_COUPON_CODE || 'PILOT2025', + trialMonths: parseInt(import.meta.env.VITE_PILOT_TRIAL_MONTHS || '3'), + get trialDays(): number { + return this.trialMonths * 30; + }, + lifetimeDiscount: 20, }; -/** - * Create pilot config with getter functions to ensure we always read fresh values - * This is important because runtime-config.js might load after this module - */ -const createPilotConfig = () => { - return { - /** - * Master switch for pilot mode - * When false, all pilot features are disabled globally - */ - get enabled(): boolean { - const value = getEnvVar('VITE_PILOT_MODE_ENABLED'); - return value === 'true'; - }, - - /** - * Coupon code for pilot participants - */ - get couponCode(): string { - return getEnvVar('VITE_PILOT_COUPON_CODE') || 'PILOT2025'; - }, - - /** - * Trial period in months for pilot participants - */ - get trialMonths(): number { - return parseInt(getEnvVar('VITE_PILOT_TRIAL_MONTHS') || '3'); - }, - - /** - * Trial period in days (calculated from months) - */ - get trialDays(): number { - return this.trialMonths * 30; - }, - - /** - * Lifetime discount percentage for pilot participants - */ - lifetimeDiscount: 20, - }; -}; - -export const PILOT_CONFIG = createPilotConfig(); - -// Debug logging -console.log('🔧 Pilot Config Loading:', { - source: typeof window !== 'undefined' && (window as any).__RUNTIME_CONFIG__ ? 'runtime' : 'build-time', - raw: getEnvVar('VITE_PILOT_MODE_ENABLED'), - type: typeof getEnvVar('VITE_PILOT_MODE_ENABLED'), - enabled: PILOT_CONFIG.enabled, - runtimeConfigExists: typeof window !== 'undefined' && !!(window as any).__RUNTIME_CONFIG__, - runtimeConfigKeys: typeof window !== 'undefined' && (window as any).__RUNTIME_CONFIG__ - ? Object.keys((window as any).__RUNTIME_CONFIG__) - : [] -}); - -console.log('✅ Pilot Config:', { - enabled: PILOT_CONFIG.enabled, - couponCode: PILOT_CONFIG.couponCode, - trialMonths: PILOT_CONFIG.trialMonths, - trialDays: PILOT_CONFIG.trialDays -}); - export default PILOT_CONFIG; diff --git a/frontend/src/config/runtime.ts b/frontend/src/config/runtime.ts index c1ec1263..b55733dc 100644 --- a/frontend/src/config/runtime.ts +++ b/frontend/src/config/runtime.ts @@ -1,83 +1,33 @@ -// Runtime configuration for Kubernetes deployments -// This allows environment variables to be injected at container startup +// Configuration - uses build-time environment variables +export const config = { + VITE_API_URL: import.meta.env.VITE_API_URL || '/api', + VITE_APP_TITLE: import.meta.env.VITE_APP_TITLE || 'BakeWise', + VITE_APP_VERSION: import.meta.env.VITE_APP_VERSION || '1.0.0', + VITE_OTEL_ENABLED: import.meta.env.VITE_OTEL_ENABLED || 'true', + VITE_OTEL_TRACES_ENDPOINT: import.meta.env.VITE_OTEL_TRACES_ENDPOINT || '/api/v1/telemetry/v1/traces', + VITE_OTEL_METRICS_ENDPOINT: import.meta.env.VITE_OTEL_METRICS_ENDPOINT || '/api/v1/telemetry/v1/metrics', +}; -interface RuntimeConfig { - VITE_API_URL: string; - VITE_APP_TITLE: string; - VITE_APP_VERSION: string; - VITE_OTEL_TRACES_ENDPOINT?: string; - VITE_OTEL_METRICS_ENDPOINT?: string; - VITE_OTEL_ENABLED?: string; -} - -declare global { - interface Window { - __RUNTIME_CONFIG__?: RuntimeConfig; - } -} - -// Types are defined in vite-env.d.ts - -// Get configuration from runtime or fall back to build-time environment variables -function getRuntimeConfig(): RuntimeConfig { - // First try to get from window (injected at runtime in Kubernetes) - if (typeof window !== 'undefined' && window.__RUNTIME_CONFIG__) { - return window.__RUNTIME_CONFIG__; - } - - // Fall back to build-time environment variables (development/local) - return { - VITE_API_URL: import.meta.env.VITE_API_URL || 'http://localhost:8000', - VITE_APP_TITLE: import.meta.env.VITE_APP_TITLE || 'PanIA Dashboard', - VITE_APP_VERSION: import.meta.env.VITE_APP_VERSION || '1.0.0', - VITE_OTEL_TRACES_ENDPOINT: import.meta.env.VITE_OTEL_TRACES_ENDPOINT || '/api/v1/telemetry/v1/traces', - VITE_OTEL_METRICS_ENDPOINT: import.meta.env.VITE_OTEL_METRICS_ENDPOINT || '/api/v1/telemetry/v1/metrics', - VITE_OTEL_ENABLED: import.meta.env.VITE_OTEL_ENABLED || 'true', - }; -} - -export const config = getRuntimeConfig(); - -// Helper function to get the API base URL export function getApiUrl(): string { return config.VITE_API_URL; } -// Helper function to get app title export function getAppTitle(): string { return config.VITE_APP_TITLE; } -// Helper function to get app version export function getAppVersion(): string { return config.VITE_APP_VERSION; } -// Helper to check if running in Kubernetes -export function isKubernetesEnvironment(): boolean { - return typeof window !== 'undefined' && !!window.__RUNTIME_CONFIG__; -} - -// Helper to check if OpenTelemetry is enabled export function isOpenTelemetryEnabled(): boolean { return config.VITE_OTEL_ENABLED?.toLowerCase() !== 'false'; } -// Helper to get OpenTelemetry traces endpoint export function getOtelTracesEndpoint(): string { - return config.VITE_OTEL_TRACES_ENDPOINT || '/api/v1/telemetry/v1/traces'; + return config.VITE_OTEL_TRACES_ENDPOINT; } -// Helper to get OpenTelemetry metrics endpoint export function getOtelMetricsEndpoint(): string { - return config.VITE_OTEL_METRICS_ENDPOINT || '/api/v1/telemetry/v1/metrics'; + return config.VITE_OTEL_METRICS_ENDPOINT; } - -// Debug function to log current configuration -export function logConfig(): void { - console.log('Current configuration:', { - ...config, - isKubernetes: isKubernetesEnvironment(), - source: isKubernetesEnvironment() ? 'runtime' : 'build-time' - }); -} \ No newline at end of file diff --git a/frontend/src/vite-env.d.ts b/frontend/src/vite-env.d.ts index 06927336..88096da3 100644 --- a/frontend/src/vite-env.d.ts +++ b/frontend/src/vite-env.d.ts @@ -2,30 +2,16 @@ interface ImportMetaEnv { readonly VITE_API_URL: string - readonly VITE_API_BASE_URL: string readonly VITE_APP_TITLE: string readonly VITE_APP_VERSION: string - readonly VITE_ENVIRONMENT: string + readonly VITE_OTEL_ENABLED?: string + readonly VITE_OTEL_TRACES_ENDPOINT?: string + readonly VITE_OTEL_METRICS_ENDPOINT?: string readonly VITE_PILOT_MODE_ENABLED?: string readonly VITE_PILOT_COUPON_CODE?: string readonly VITE_PILOT_TRIAL_MONTHS?: string - readonly VITE_STRIPE_PUBLISHABLE_KEY?: string - // more env variables... } interface ImportMeta { readonly env: ImportMetaEnv } - -// Runtime configuration injected by Kubernetes at container startup -interface Window { - __RUNTIME_CONFIG__?: { - VITE_API_URL?: string; - VITE_APP_TITLE?: string; - VITE_APP_VERSION?: string; - VITE_PILOT_MODE_ENABLED?: string; - VITE_PILOT_COUPON_CODE?: string; - VITE_PILOT_TRIAL_MONTHS?: string; - VITE_STRIPE_PUBLISHABLE_KEY?: string; - }; -} \ No newline at end of file diff --git a/frontend/substitute-env.sh b/frontend/substitute-env.sh deleted file mode 100644 index 2a8f4a91..00000000 --- a/frontend/substitute-env.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh -set -e - -# Handle VITE_API_URL specially to preserve empty values -# If VITE_API_URL is unset, use default; if empty, preserve empty; otherwise use value -if [ -z "${VITE_API_URL+x}" ]; then - export VITE_API_URL="/api" -elif [ -z "$VITE_API_URL" ]; then - # If VITE_API_URL is explicitly set to empty string, use relative API path - export VITE_API_URL="/api" -fi - -# Default values for environment variables -export VITE_APP_TITLE=${VITE_APP_TITLE:-"BakeWise"} -export VITE_APP_VERSION=${VITE_APP_VERSION:-"1.0.0"} - -# Default values for pilot program configuration -export VITE_PILOT_MODE_ENABLED=${VITE_PILOT_MODE_ENABLED:-"false"} -export VITE_PILOT_COUPON_CODE=${VITE_PILOT_COUPON_CODE:-"PILOT2025"} -export VITE_PILOT_TRIAL_MONTHS=${VITE_PILOT_TRIAL_MONTHS:-"3"} -export VITE_STRIPE_PUBLISHABLE_KEY=${VITE_STRIPE_PUBLISHABLE_KEY:-"pk_test_"} - -# Create a runtime configuration file that can be loaded by the frontend -cat > /usr/share/nginx/html/runtime-config.js << EOL -window.__RUNTIME_CONFIG__ = { - VITE_API_URL: '${VITE_API_URL}', - VITE_APP_TITLE: '${VITE_APP_TITLE}', - VITE_APP_VERSION: '${VITE_APP_VERSION}', - VITE_PILOT_MODE_ENABLED: '${VITE_PILOT_MODE_ENABLED}', - VITE_PILOT_COUPON_CODE: '${VITE_PILOT_COUPON_CODE}', - VITE_PILOT_TRIAL_MONTHS: '${VITE_PILOT_TRIAL_MONTHS}', - VITE_STRIPE_PUBLISHABLE_KEY: '${VITE_STRIPE_PUBLISHABLE_KEY}' -}; -EOL - -echo "Runtime configuration created:" -echo " API URL: ${VITE_API_URL}" -echo " Pilot Mode: ${VITE_PILOT_MODE_ENABLED}" -echo " Pilot Coupon: ${VITE_PILOT_COUPON_CODE}" -echo " Trial Months: ${VITE_PILOT_TRIAL_MONTHS}"