🎉 Major enhancement: Full migration from shell script deployment to Kustomize ## New Features ### Kustomize Infrastructure - ✅ Complete base resources for all Kubernetes manifests - ✅ Development overlay with optimized dev settings - ✅ Production overlay with enterprise-grade security and performance - ✅ ConfigMap and Secret generation from environment variables - ✅ Image tag and replica management per environment ### Environment Variable Integration - ✅ Multi-source environment loading (~/.env, .env.dev, .env.prod, .env.local) - ✅ Static configuration generation from environment variables - ✅ Dynamic runtime environment variable injection - ✅ Comprehensive variable documentation and examples - ✅ Secrets template generation for secure credential management ### Enhanced Makefile - ✅ 20+ new Kustomize-specific deployment targets - ✅ Environment-aware configuration generation commands - ✅ Validation, dry-run, and debugging capabilities - ✅ Backward compatibility with legacy shell script deployment ### New Scripts & Tools - ✅ scripts/generate-config.sh - Environment variable to Kustomize config generator - ✅ scripts/deploy-with-env.sh - Runtime environment variable deployment tool - ✅ Comprehensive help and usage documentation ### Documentation - ✅ k8s-kustomize/README.md - Complete Kustomize deployment guide - ✅ docs/ENVIRONMENT_VARIABLES.md - Environment variable integration guide - ✅ KUSTOMIZE_MIGRATION.md - Migration summary and next steps ## Benefits - 🚀 Simplified deployment: make deploy-dev vs complex shell scripts - 🔒 Environment isolation: Clear dev/staging/prod separation - 🔧 GitOps ready: Works seamlessly with ArgoCD, Flux - ✅ Better validation: Built-in YAML validation catches errors early - 📈 Standard approach: Industry-standard Kubernetes deployment method - 🛡️ Enhanced security: Production security contexts, network policies, TLS ## Usage Examples [34mGenerating development configuration...[0m [0;34m[INFO][0m Kustomize Config Generator [0;34m[INFO][0m Environment: dev [0;34m[INFO][0m Loading environment variables... [1;33m[WARNING][0m File not found: /home/will/.env [0;34m[INFO][0m Loading: /home/will/Code/meds/.env [1;33m[WARNING][0m File not found: /home/will/Code/meds/.env.dev [1;33m[WARNING][0m File not found: /home/will/Code/meds/.env.local [0;34m[INFO][0m Generating base config.env... [0;32m[SUCCESS][0m Generated: /home/will/Code/meds/k8s-kustomize/base/config.env [0;34m[INFO][0m Generating environment-specific config for: dev [0;32m[SUCCESS][0m Generated development config: /home/will/Code/meds/k8s-kustomize/overlays/dev/config.env [0;34m[INFO][0m Validating generated configuration... [0;32m[SUCCESS][0m Configuration validation passed! [0;32m[SUCCESS][0m Configuration generation completed! [0;34m[INFO][0m Next steps: 1. Review generated files in k8s-kustomize/ 2. Update any environment-specific values 3. Create secrets.env files for sensitive data 4. Test with: make kustomize-dry-run-dev [34mDeploying to Kubernetes with Kustomize (dev)...[0m [34mDeploying to production with environment variables...[0m [0;34m[INFO][0m Kustomize Deployment with Environment Variables [0;34m[INFO][0m Environment: prod [0;34m[INFO][0m Action: apply [0;34m[INFO][0m Validating prerequisites... [0;32m[SUCCESS][0m Prerequisites validated [0;34m[INFO][0m Loading environment variables for: prod [0;34m[INFO][0m Loading: /home/will/Code/meds/.env [0;32m[SUCCESS][0m Environment loaded: prod [0;34m[INFO][0m Key variables: APP_NAME: rxminder NODE_ENV: production IMAGE_TAG: latest NAMESPACE: rxminder-prod INGRESS_HOST: rxminder.192.168.153.243.nip.io [0;34m[INFO][0m Generating dynamic configuration... [34mValidating Kustomize configuration (dev)...[0m configmap/rxminder-config-4229dg76t6 created (dry run) secret/couchdb-secret-7ck2cc96g5 created (dry run) service/rxminder-couchdb-service created (dry run) service/rxminder-frontend-service created (dry run) persistentvolumeclaim/rxminder-couchdb-pvc created (dry run) deployment.apps/rxminder-frontend created (dry run) statefulset.apps/rxminder-couchdb created (dry run) horizontalpodautoscaler.autoscaling/rxminder-frontend-hpa created (dry run) job.batch/rxminder-db-seed created (dry run) ingress.networking.k8s.io/rxminder-ingress created (dry run) networkpolicy.networking.k8s.io/rxminder-database-policy created (dry run) networkpolicy.networking.k8s.io/rxminder-frontend-policy created (dry run) [34mValidating Kustomize configuration (prod)...[0m configmap/rxminder-config-2979gkcf9c created (dry run) secret/couchdb-secret-6k9794bgg2 created (dry run) service/rxminder-couchdb-service created (dry run) service/rxminder-frontend-service created (dry run) persistentvolumeclaim/rxminder-couchdb-pvc created (dry run) deployment.apps/rxminder-frontend created (dry run) statefulset.apps/rxminder-couchdb created (dry run) horizontalpodautoscaler.autoscaling/rxminder-frontend-hpa created (dry run) job.batch/rxminder-db-seed created (dry run) ingress.networking.k8s.io/rxminder-ingress created (dry run) networkpolicy.networking.k8s.io/rxminder-database-policy created (dry run) networkpolicy.networking.k8s.io/rxminder-frontend-policy created (dry run) [32mKustomize validation completed![0m [34mDry run Kustomize deployment (dev)...[0m apiVersion: v1 items: - apiVersion: v1 data: APP_NAME: rxminder APP_VERSION: 1.0.0 CACHE_TTL: "1800" CERT_MANAGER_ISSUER: letsencrypt-prod CORS_ORIGIN: '*' COUCHDB_DATABASE_NAME: meds_app DB_HOST: rxminder-couchdb-service DB_PORT: "5984" DEBUG: "true" DEV_MODE: "false" ENABLE_CORS: "true" ENABLE_METRICS: "false" ENABLE_MONITORING: "false" ENABLE_TRACING: "false" HEALTH_CHECK_INTERVAL: "30" HOT_RELOAD: "false" IMAGE_REPOSITORY: will/rxminder INGRESS_CLASS: nginx LOG_FORMAT: json LOG_LEVEL: debug LOG_TIMESTAMP: "true" MAX_CONNECTIONS: "100" METRICS_PORT: "9090" NODE_ENV: development REACT_APP_API_URL: http://rxminder-couchdb-service:5984 READINESS_CHECK_TIMEOUT: "5" REGISTRY_URL: gitea-http.taildb3494.ts.net REQUEST_TIMEOUT: "30000" kind: ConfigMap metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","data":{"APP_NAME":"rxminder","APP_VERSION":"1.0.0","CACHE_TTL":"1800","CERT_MANAGER_ISSUER":"letsencrypt-prod","CORS_ORIGIN":"*","COUCHDB_DATABASE_NAME":"meds_app","DB_HOST":"rxminder-couchdb-service","DB_PORT":"5984","DEBUG":"true","DEV_MODE":"false","ENABLE_CORS":"true","ENABLE_METRICS":"false","ENABLE_MONITORING":"false","ENABLE_TRACING":"false","HEALTH_CHECK_INTERVAL":"30","HOT_RELOAD":"false","IMAGE_REPOSITORY":"will/rxminder","INGRESS_CLASS":"nginx","LOG_FORMAT":"json","LOG_LEVEL":"debug","LOG_TIMESTAMP":"true","MAX_CONNECTIONS":"100","METRICS_PORT":"9090","NODE_ENV":"development","REACT_APP_API_URL":"http://rxminder-couchdb-service:5984","READINESS_CHECK_TIMEOUT":"5","REGISTRY_URL":"gitea-http.taildb3494.ts.net","REQUEST_TIMEOUT":"30000"},"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app":"rxminder","environment":"dev","version":"v1.0.0"},"name":"rxminder-config-4229dg76t6","namespace":"rxminder-dev"}} labels: app: rxminder environment: dev version: v1.0.0 name: rxminder-config-4229dg76t6 namespace: rxminder-dev - apiVersion: v1 data: password: ZGV2cGFzczEyMw== username: YWRtaW4= kind: Secret metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","data":{"password":"ZGV2cGFzczEyMw==","username":"YWRtaW4="},"kind":"Secret","metadata":{"annotations":{},"labels":{"app":"rxminder","environment":"dev","version":"v1.0.0"},"name":"couchdb-secret-7ck2cc96g5","namespace":"rxminder-dev"},"type":"Opaque"} labels: app: rxminder environment: dev version: v1.0.0 name: couchdb-secret-7ck2cc96g5 namespace: rxminder-dev type: Opaque - apiVersion: v1 kind: Service metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"rxminder","component":"database","environment":"dev","version":"v1.0.0"},"name":"rxminder-couchdb-service","namespace":"rxminder-dev"},"spec":{"ports":[{"name":"couchdb","port":5984,"protocol":"TCP","targetPort":5984}],"selector":{"app":"rxminder","component":"database"},"type":"ClusterIP"}} labels: app: rxminder component: database environment: dev version: v1.0.0 name: rxminder-couchdb-service namespace: rxminder-dev spec: ports: - name: couchdb port: 5984 protocol: TCP targetPort: 5984 selector: app: rxminder component: database type: ClusterIP - apiVersion: v1 kind: Service metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"rxminder","component":"frontend","environment":"dev","version":"v1.0.0"},"name":"rxminder-frontend-service","namespace":"rxminder-dev"},"spec":{"ports":[{"name":"http","port":80,"protocol":"TCP","targetPort":80}],"selector":{"app":"rxminder","component":"frontend"},"type":"ClusterIP"}} labels: app: rxminder component: frontend environment: dev version: v1.0.0 name: rxminder-frontend-service namespace: rxminder-dev spec: ports: - name: http port: 80 protocol: TCP targetPort: 80 selector: app: rxminder component: frontend type: ClusterIP - apiVersion: v1 kind: PersistentVolumeClaim metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"labels":{"app":"rxminder","component":"database","environment":"dev","version":"v1.0.0"},"name":"rxminder-couchdb-pvc","namespace":"rxminder-dev"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"1Gi"}},"storageClassName":"standard"}} labels: app: rxminder component: database environment: dev version: v1.0.0 name: rxminder-couchdb-pvc namespace: rxminder-dev spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: standard - apiVersion: apps/v1 kind: Deployment metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"rxminder","component":"frontend","environment":"dev","version":"v1.0.0"},"name":"rxminder-frontend","namespace":"rxminder-dev"},"spec":{"replicas":1,"selector":{"matchLabels":{"component":"frontend"}},"template":{"metadata":{"labels":{"component":"frontend"}},"spec":{"containers":[{"env":[{"name":"NODE_ENV","value":"development"},{"name":"LOG_LEVEL","value":"debug"}],"envFrom":[{"configMapRef":{"name":"rxminder-config-4229dg76t6"}}],"image":"gitea-http.taildb3494.ts.net/will/rxminder:dev","livenessProbe":{"httpGet":{"path":"/","port":80},"initialDelaySeconds":30,"periodSeconds":30},"name":"frontend","ports":[{"containerPort":80}],"readinessProbe":{"httpGet":{"path":"/","port":80},"initialDelaySeconds":5,"periodSeconds":5},"resources":{"limits":{"cpu":"40m","memory":"32Mi"},"requests":{"cpu":"20m","memory":"16Mi"}}}],"imagePullSecrets":[{"name":"rxminder-registry-secret"}]}}}} labels: app: rxminder component: frontend environment: dev version: v1.0.0 name: rxminder-frontend namespace: rxminder-dev spec: replicas: 1 selector: matchLabels: component: frontend template: metadata: labels: component: frontend spec: containers: - env: - name: NODE_ENV value: development - name: LOG_LEVEL value: debug envFrom: - configMapRef: name: rxminder-config-4229dg76t6 image: gitea-http.taildb3494.ts.net/will/rxminder:dev livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 30 periodSeconds: 30 name: frontend ports: - containerPort: 80 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 periodSeconds: 5 resources: limits: cpu: 40m memory: 32Mi requests: cpu: 20m memory: 16Mi imagePullSecrets: - name: rxminder-registry-secret - apiVersion: apps/v1 kind: StatefulSet metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"apps/v1","kind":"StatefulSet","metadata":{"annotations":{},"labels":{"app":"rxminder","component":"database","environment":"dev","version":"v1.0.0"},"name":"rxminder-couchdb","namespace":"rxminder-dev"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"rxminder","component":"database"}},"serviceName":"rxminder-couchdb-service","template":{"metadata":{"labels":{"app":"rxminder","component":"database"}},"spec":{"containers":[{"env":[{"name":"COUCHDB_USER","valueFrom":{"secretKeyRef":{"key":"username","name":"couchdb-secret-7ck2cc96g5"}}},{"name":"COUCHDB_PASSWORD","valueFrom":{"secretKeyRef":{"key":"password","name":"couchdb-secret-7ck2cc96g5"}}}],"image":"couchdb:3.3.2","livenessProbe":{"httpGet":{"path":"/_up","port":5984},"initialDelaySeconds":60,"periodSeconds":30},"name":"couchdb","ports":[{"containerPort":5984}],"readinessProbe":{"httpGet":{"path":"/_up","port":5984},"initialDelaySeconds":10,"periodSeconds":5},"resources":{"limits":{"cpu":"60m","memory":"128Mi"},"requests":{"cpu":"30m","memory":"64Mi"}},"volumeMounts":[{"mountPath":"/opt/couchdb/data","name":"couchdb-data"}]}]}},"volumeClaimTemplates":[{"metadata":{"labels":{"app":"rxminder","component":"database"},"name":"couchdb-data"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"1Gi"}},"storageClassName":"standard"}}]}} labels: app: rxminder component: database environment: dev version: v1.0.0 name: rxminder-couchdb namespace: rxminder-dev spec: replicas: 1 selector: matchLabels: app: rxminder component: database serviceName: rxminder-couchdb-service template: metadata: labels: app: rxminder component: database spec: containers: - env: - name: COUCHDB_USER valueFrom: secretKeyRef: key: username name: couchdb-secret-7ck2cc96g5 - name: COUCHDB_PASSWORD valueFrom: secretKeyRef: key: password name: couchdb-secret-7ck2cc96g5 image: couchdb:3.3.2 livenessProbe: httpGet: path: /_up port: 5984 initialDelaySeconds: 60 periodSeconds: 30 name: couchdb ports: - containerPort: 5984 readinessProbe: httpGet: path: /_up port: 5984 initialDelaySeconds: 10 periodSeconds: 5 resources: limits: cpu: 60m memory: 128Mi requests: cpu: 30m memory: 64Mi volumeMounts: - mountPath: /opt/couchdb/data name: couchdb-data volumeClaimTemplates: - metadata: labels: app: rxminder component: database name: couchdb-data spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: standard - apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"autoscaling/v2","kind":"HorizontalPodAutoscaler","metadata":{"annotations":{},"labels":{"app":"rxminder","component":"frontend","environment":"dev","version":"v1.0.0"},"name":"rxminder-frontend-hpa","namespace":"rxminder-dev"},"spec":{"maxReplicas":3,"metrics":[{"resource":{"name":"cpu","target":{"averageUtilization":50,"type":"Utilization"}},"type":"Resource"}],"minReplicas":1,"scaleTargetRef":{"apiVersion":"apps/v1","kind":"Deployment","name":"rxminder-frontend"}}} labels: app: rxminder component: frontend environment: dev version: v1.0.0 name: rxminder-frontend-hpa namespace: rxminder-dev spec: maxReplicas: 3 metrics: - resource: name: cpu target: averageUtilization: 50 type: Utilization type: Resource minReplicas: 1 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: rxminder-frontend - apiVersion: batch/v1 kind: Job metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"batch/v1","kind":"Job","metadata":{"annotations":{},"labels":{"app":"rxminder","component":"database","environment":"dev","version":"v1.0.0"},"name":"rxminder-db-seed","namespace":"rxminder-dev"},"spec":{"backoffLimit":4,"template":{"metadata":{"labels":{"app":"rxminder","component":"database"}},"spec":{"containers":[{"args":["# Wait for CouchDB to be ready\necho \"Waiting for CouchDB to be ready...\"\nuntil curl -f http://couchdb-service:5984/_up 2\u003e/dev/null; do\n sleep 2\ndone\n\n# Create databases\necho \"Creating databases...\"\ncurl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app\n\n# Create default admin user\necho \"Creating default admin user...\"\ncurl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/_users/org.couchdb.user:$COUCHDB_USER \\\n -H \"Content-Type: application/json\" \\\n -d \"{\n \\\"name\\\": \\\"$COUCHDB_USER\\\",\n \\\"password\\\": \\\"$COUCHDB_PASSWORD\\\",\n \\\"roles\\\": [\\\"admin\\\"],\n \\\"type\\\": \\\"user\\\"\n }\"\n\n# Create design documents for views\necho \"Creating design documents...\"\ncurl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app/_design/medications \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"views\": {\n \"by_name\": {\n \"map\": \"function(doc) { if (doc.type === \\\"medication\\\") emit(doc.name, doc); }\"\n },\n \"by_user\": {\n \"map\": \"function(doc) { if (doc.type === \\\"medication\\\") emit(doc.userId, doc); }\"\n }\n }\n }'\n\ncurl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app/_design/reminders \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"views\": {\n \"by_medication\": {\n \"map\": \"function(doc) { if (doc.type === \\\"reminder\\\") emit(doc.medicationId, doc); }\"\n },\n \"by_user\": {\n \"map\": \"function(doc) { if (doc.type === \\\"reminder\\\") emit(doc.userId, doc); }\"\n }\n }\n }'\n\n# Create a sample user document for reference\n # Create design document for authentication users\n curl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app/_design/auth \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"views\": {\n \"by_username\": {\n \"map\": \"function(doc) { if (doc.type === \\\"user\\\" \u0026\u0026 doc.username) emit(doc.username, doc); }\"\n },\n \"by_email\": {\n \"map\": \"function(doc) { if (doc.type === \\\"user\\\" \u0026\u0026 doc.email) emit(doc.email, doc); }\"\n }\n }\n }'\necho \"Creating sample user document...\"\ncurl -X POST http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"type\": \"user\",\n \"name\": \"sample_user\",\n \"email\": \"user@example.com\",\n \"createdAt\": \"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'\"\n }'\n\necho \"Database seeding completed with default admin user\"\n"],"command":["/bin/sh","-c"],"env":[{"name":"COUCHDB_USER","valueFrom":{"secretKeyRef":{"key":"username","name":"couchdb-secret-7ck2cc96g5"}}},{"name":"COUCHDB_PASSWORD","valueFrom":{"secretKeyRef":{"key":"password","name":"couchdb-secret-7ck2cc96g5"}}}],"image":"couchdb:3.3.2","name":"db-seeder"}],"restartPolicy":"Never"}}}} labels: app: rxminder component: database environment: dev version: v1.0.0 name: rxminder-db-seed namespace: rxminder-dev spec: backoffLimit: 4 template: metadata: labels: app: rxminder component: database spec: containers: - args: - | # Wait for CouchDB to be ready echo "Waiting for CouchDB to be ready..." until curl -f http://couchdb-service:5984/_up 2>/dev/null; do sleep 2 done # Create databases echo "Creating databases..." curl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app # Create default admin user echo "Creating default admin user..." curl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/_users/org.couchdb.user:$COUCHDB_USER \ -H "Content-Type: application/json" \ -d "{ \"name\": \"$COUCHDB_USER\", \"password\": \"$COUCHDB_PASSWORD\", \"roles\": [\"admin\"], \"type\": \"user\" }" # Create design documents for views echo "Creating design documents..." curl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app/_design/medications \ -H "Content-Type: application/json" \ -d '{ "views": { "by_name": { "map": "function(doc) { if (doc.type === \"medication\") emit(doc.name, doc); }" }, "by_user": { "map": "function(doc) { if (doc.type === \"medication\") emit(doc.userId, doc); }" } } }' curl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app/_design/reminders \ -H "Content-Type: application/json" \ -d '{ "views": { "by_medication": { "map": "function(doc) { if (doc.type === \"reminder\") emit(doc.medicationId, doc); }" }, "by_user": { "map": "function(doc) { if (doc.type === \"reminder\") emit(doc.userId, doc); }" } } }' # Create a sample user document for reference # Create design document for authentication users curl -X PUT http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app/_design/auth \ -H "Content-Type: application/json" \ -d '{ "views": { "by_username": { "map": "function(doc) { if (doc.type === \"user\" && doc.username) emit(doc.username, doc); }" }, "by_email": { "map": "function(doc) { if (doc.type === \"user\" && doc.email) emit(doc.email, doc); }" } } }' echo "Creating sample user document..." curl -X POST http://$COUCHDB_USER:$COUCHDB_PASSWORD@couchdb-service:5984/meds_app \ -H "Content-Type: application/json" \ -d '{ "type": "user", "name": "sample_user", "email": "user@example.com", "createdAt": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'" }' echo "Database seeding completed with default admin user" command: - /bin/sh - -c env: - name: COUCHDB_USER valueFrom: secretKeyRef: key: username name: couchdb-secret-7ck2cc96g5 - name: COUCHDB_PASSWORD valueFrom: secretKeyRef: key: password name: couchdb-secret-7ck2cc96g5 image: couchdb:3.3.2 name: db-seeder restartPolicy: Never - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{},"labels":{"app":"rxminder","component":"frontend","environment":"dev","version":"v1.0.0"},"name":"rxminder-ingress","namespace":"rxminder-dev"},"spec":{"ingressClassName":"nginx","rules":[{"host":"rxminder-dev.local","http":{"paths":[{"backend":{"service":{"name":"rxminder-frontend-service","port":{"number":80}}},"path":"/","pathType":"Prefix"}]}}]}} labels: app: rxminder component: frontend environment: dev version: v1.0.0 name: rxminder-ingress namespace: rxminder-dev spec: ingressClassName: nginx rules: - host: rxminder-dev.local http: paths: - backend: service: name: rxminder-frontend-service port: number: 80 path: / pathType: Prefix - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"networking.k8s.io/v1","kind":"NetworkPolicy","metadata":{"annotations":{},"labels":{"app":"rxminder","component":"database","environment":"dev","version":"v1.0.0"},"name":"rxminder-database-policy","namespace":"rxminder-dev"},"spec":{"egress":[{"ports":[{"port":5984,"protocol":"TCP"}],"to":[{"podSelector":{"matchLabels":{"component":"database"}}}]}],"ingress":[{"from":[{"podSelector":{"matchLabels":{"component":"frontend"}}}],"ports":[{"port":5984,"protocol":"TCP"}]}],"podSelector":{"matchLabels":{"component":"database"}},"policyTypes":["Ingress","Egress"]}} labels: app: rxminder component: database environment: dev version: v1.0.0 name: rxminder-database-policy namespace: rxminder-dev spec: egress: - ports: - port: 5984 protocol: TCP to: - podSelector: matchLabels: component: database ingress: - from: - podSelector: matchLabels: component: frontend ports: - port: 5984 protocol: TCP podSelector: matchLabels: component: database policyTypes: - Ingress - Egress - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"networking.k8s.io/v1","kind":"NetworkPolicy","metadata":{"annotations":{},"labels":{"app":"rxminder","component":"frontend","environment":"dev","version":"v1.0.0"},"name":"rxminder-frontend-policy","namespace":"rxminder-dev"},"spec":{"egress":[{"ports":[{"port":5984,"protocol":"TCP"}],"to":[{"podSelector":{"matchLabels":{"component":"database"}}}]},{"ports":[{"port":80,"protocol":"TCP"}],"to":[{"podSelector":{"matchLabels":{"component":"frontend"}}}]}],"ingress":[{"from":[{"podSelector":{"matchLabels":{"component":"frontend"}}}],"ports":[{"port":80,"protocol":"TCP"}]}],"podSelector":{"matchLabels":{"component":"frontend"}},"policyTypes":["Ingress","Egress"]}} labels: app: rxminder component: frontend environment: dev version: v1.0.0 name: rxminder-frontend-policy namespace: rxminder-dev spec: egress: - ports: - port: 5984 protocol: TCP to: - podSelector: matchLabels: component: database - ports: - port: 80 protocol: TCP to: - podSelector: matchLabels: component: frontend ingress: - from: - podSelector: matchLabels: component: frontend ports: - port: 80 protocol: TCP podSelector: matchLabels: component: frontend policyTypes: - Ingress - Egress kind: List metadata: {} ## Migration Path - Legacy shell scripts remain available for backward compatibility - Gradual migration: dev → staging → production - Zero-downtime deployment capability Co-authored-by: Assistant <assistant@anthropic.com>
472 lines
18 KiB
Makefile
472 lines
18 KiB
Makefile
# Makefile for Medication Reminder App
|
|
# Acts as a wrapper for package.json scripts with organized targets
|
|
|
|
.PHONY: help install clean build dev test lint deploy undeploy docker gitea k8s
|
|
|
|
# Default target
|
|
.DEFAULT_GOAL := help
|
|
|
|
# Colors for output
|
|
BLUE := \033[34m
|
|
GREEN := \033[32m
|
|
YELLOW := \033[33m
|
|
RED := \033[31m
|
|
RESET := \033[0m
|
|
|
|
##@ General
|
|
|
|
help: ## Display this help message
|
|
@printf "$(BLUE)Medication Reminder App - Available Commands$(RESET)\n"
|
|
@printf "\n"
|
|
@awk 'BEGIN {FS = ":.*##"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " $(GREEN)%-20s$(RESET) %s\n", $$1, $$2 } /^##@/ { printf "\n$(YELLOW)%s$(RESET)\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
|
|
|
install: ## Install dependencies
|
|
@printf "$(BLUE)Installing dependencies...$(RESET)\n"
|
|
@bun install
|
|
|
|
clean: ## Clean build artifacts and dependencies
|
|
@printf "$(BLUE)Cleaning up...$(RESET)\n"
|
|
@rm -rf node_modules dist build .cache
|
|
|
|
##@ Development
|
|
|
|
dev: ## Start development server
|
|
@printf "$(BLUE)Starting development server...$(RESET)\n"
|
|
@bun run dev
|
|
|
|
build: ## Build the application
|
|
@printf "$(BLUE)Building application...$(RESET)\n"
|
|
@bun run build
|
|
|
|
preview: ## Preview the built application
|
|
@printf "$(BLUE)Starting preview server...$(RESET)\n"
|
|
@bun run preview
|
|
|
|
##@ Testing
|
|
|
|
test: ## Run unit tests
|
|
@printf "$(BLUE)Running unit tests...$(RESET)\n"
|
|
@bun run test
|
|
|
|
test-watch: ## Run unit tests in watch mode
|
|
@printf "$(BLUE)Running tests in watch mode...$(RESET)\n"
|
|
@bun run test:watch
|
|
|
|
test-coverage: ## Run tests with coverage
|
|
@printf "$(BLUE)Running tests with coverage...$(RESET)\n"
|
|
@bun run test:coverage
|
|
|
|
test-integration: ## Run integration tests
|
|
@printf "$(BLUE)Running integration tests...$(RESET)\n"
|
|
@bun run test:integration
|
|
|
|
test-e2e: ## Run end-to-end tests
|
|
@printf "$(BLUE)Running e2e tests...$(RESET)\n"
|
|
@bun run test:e2e
|
|
|
|
test-e2e-ui: ## Run e2e tests with UI
|
|
@printf "$(BLUE)Running e2e tests with UI...$(RESET)\n"
|
|
@bun run test:e2e:ui
|
|
|
|
test-e2e-debug: ## Debug e2e tests
|
|
@printf "$(BLUE)Debugging e2e tests...$(RESET)\n"
|
|
@bun run test:e2e:debug
|
|
|
|
test-e2e-report: ## Show e2e test report
|
|
@printf "$(BLUE)Showing e2e test report...$(RESET)\n"
|
|
@bun run test:e2e:report
|
|
|
|
test-backend: ## Run backend tests (unit + integration)
|
|
@printf "$(BLUE)Running backend tests...$(RESET)\n"
|
|
@bun run test && bun run test:integration
|
|
|
|
test-all: ## Run all tests (unit + integration + e2e)
|
|
@printf "$(BLUE)Running all tests...$(RESET)\n"
|
|
@bun run test:all
|
|
|
|
##@ Code Quality
|
|
|
|
lint: ## Run all linting checks
|
|
@printf "$(BLUE)Running linting checks...$(RESET)\n"
|
|
@bun run lint
|
|
|
|
lint-fix: ## Fix linting issues
|
|
@printf "$(BLUE)Fixing linting issues...$(RESET)\n"
|
|
@bun run lint:fix
|
|
|
|
lint-markdown: ## Lint markdown files
|
|
@printf "$(BLUE)Linting markdown files...$(RESET)\n"
|
|
@bun run lint:markdown
|
|
|
|
lint-markdown-fix: ## Fix markdown linting issues
|
|
@printf "$(BLUE)Fixing markdown linting issues...$(RESET)\n"
|
|
@bun run lint:markdown:fix
|
|
|
|
lint-docker: ## Lint Dockerfile
|
|
@printf "$(BLUE)Linting Dockerfile...$(RESET)\n"
|
|
@bun run lint:docker
|
|
|
|
check-secrets: ## Check for secrets in code
|
|
@printf "$(BLUE)Checking for secrets...$(RESET)\n"
|
|
@bun run check:secrets
|
|
|
|
check-editorconfig: ## Check EditorConfig compliance
|
|
@printf "$(BLUE)Checking EditorConfig compliance...$(RESET)\n"
|
|
@bun run check:editorconfig
|
|
|
|
fix-editorconfig: ## Fix EditorConfig issues
|
|
@printf "$(BLUE)Fixing EditorConfig issues...$(RESET)\n"
|
|
@bun run fix:editorconfig
|
|
|
|
pre-commit: ## Run pre-commit checks
|
|
@printf "$(BLUE)Running pre-commit checks...$(RESET)\n"
|
|
@bun run pre-commit
|
|
|
|
##@ Setup & Deployment
|
|
|
|
setup: ## Setup the project
|
|
@printf "$(BLUE)Setting up project...$(RESET)\n"
|
|
@bun run setup
|
|
|
|
deploy: ## Deploy the application
|
|
@printf "$(BLUE)Deploying application...$(RESET)\n"
|
|
@bun run deploy
|
|
|
|
undeploy: ## Undeploy the application (both k8s and docker)
|
|
@printf "$(BLUE)Undeploying application...$(RESET)\n"
|
|
@$(MAKE) undeploy-k8s
|
|
@$(MAKE) undeploy-docker
|
|
|
|
undeploy-k8s: ## Undeploy from Kubernetes only
|
|
@printf "$(BLUE)Undeploying from Kubernetes...$(RESET)\n"
|
|
@if kubectl get deployment -l app=rxminder 2>/dev/null | grep -q rxminder; then \
|
|
$(MAKE) k8s-undeploy; \
|
|
else \
|
|
printf "$(YELLOW)No Kubernetes deployments found for rxminder$(RESET)\n"; \
|
|
fi
|
|
|
|
undeploy-docker: ## Stop and remove Docker Compose services
|
|
@printf "$(BLUE)Undeploying Docker containers...$(RESET)\n"
|
|
@if docker-compose -f docker/docker-compose.yaml ps --services 2>/dev/null | grep -q .; then \
|
|
$(MAKE) docker-down; \
|
|
else \
|
|
printf "$(YELLOW)No Docker Compose services found running$(RESET)\n"; \
|
|
fi
|
|
|
|
undeploy-docker-full: ## Stop, remove containers and delete volumes
|
|
@printf "$(BLUE)Full Docker undeploy (includes volumes)...$(RESET)\n"
|
|
@if docker-compose -f docker/docker-compose.yaml ps --services 2>/dev/null | grep -q .; then \
|
|
$(MAKE) docker-down-volumes; \
|
|
else \
|
|
printf "$(YELLOW)No Docker Compose services found running$(RESET)\n"; \
|
|
fi
|
|
|
|
validate-env: ## Validate environment configuration
|
|
@printf "$(BLUE)Validating environment...$(RESET)\n"
|
|
@bun run validate:env
|
|
|
|
validate-deployment: ## Validate deployment
|
|
@printf "$(BLUE)Validating deployment...$(RESET)\n"
|
|
@bun run validate:deployment
|
|
|
|
seed-production: ## Seed production database
|
|
@printf "$(BLUE)Seeding production database...$(RESET)\n"
|
|
@bun run seed:production
|
|
|
|
##@ Kubernetes
|
|
|
|
k8s-deploy: ## Deploy to Kubernetes (legacy shell script)
|
|
@printf "$(BLUE)Deploying to Kubernetes (legacy)...$(RESET)\n"
|
|
@bun run deploy:k8s
|
|
|
|
k8s-undeploy: ## Remove from Kubernetes (legacy shell script)
|
|
@printf "$(BLUE)Removing from Kubernetes (legacy)...$(RESET)\n"
|
|
@bun run undeploy:k8s
|
|
|
|
k8s-deploy-dry: ## Dry run Kubernetes deployment (legacy)
|
|
@printf "$(BLUE)Dry run Kubernetes deployment (legacy)...$(RESET)\n"
|
|
@bun run deploy:k8s --dry-run
|
|
|
|
k8s-undeploy-dry: ## Dry run Kubernetes removal (legacy)
|
|
@printf "$(BLUE)Dry run Kubernetes removal (legacy)...$(RESET)\n"
|
|
@bun run undeploy:k8s --dry-run
|
|
|
|
k8s-status: ## Show Kubernetes deployment status
|
|
@printf "$(BLUE)Showing Kubernetes status...$(RESET)\n"
|
|
@bun run deploy:k8s --status
|
|
|
|
##@ Kustomize (Recommended)
|
|
|
|
kustomize-deploy-dev: ## Deploy to Kubernetes using Kustomize (development)
|
|
@printf "$(BLUE)Deploying to Kubernetes with Kustomize (dev)...$(RESET)\n"
|
|
@kubectl apply -k k8s-kustomize/overlays/dev
|
|
|
|
kustomize-deploy-prod: ## Deploy to Kubernetes using Kustomize (production)
|
|
@printf "$(BLUE)Deploying to Kubernetes with Kustomize (prod)...$(RESET)\n"
|
|
@kubectl apply -k k8s-kustomize/overlays/prod
|
|
|
|
kustomize-undeploy-dev: ## Remove from Kubernetes using Kustomize (development)
|
|
@printf "$(BLUE)Removing from Kubernetes with Kustomize (dev)...$(RESET)\n"
|
|
@kubectl delete -k k8s-kustomize/overlays/dev --ignore-not-found=true
|
|
|
|
kustomize-undeploy-prod: ## Remove from Kubernetes using Kustomize (production)
|
|
@printf "$(BLUE)Removing from Kubernetes with Kustomize (prod)...$(RESET)\n"
|
|
@kubectl delete -k k8s-kustomize/overlays/prod --ignore-not-found=true
|
|
|
|
kustomize-dry-run-dev: ## Dry run Kustomize deployment (development)
|
|
@printf "$(BLUE)Dry run Kustomize deployment (dev)...$(RESET)\n"
|
|
@kubectl apply -k k8s-kustomize/overlays/dev --dry-run=client -o yaml
|
|
|
|
kustomize-dry-run-prod: ## Dry run Kustomize deployment (production)
|
|
@printf "$(BLUE)Dry run Kustomize deployment (prod)...$(RESET)\n"
|
|
@kubectl apply -k k8s-kustomize/overlays/prod --dry-run=client -o yaml
|
|
|
|
kustomize-validate-dev: ## Validate Kustomize configuration (development)
|
|
@printf "$(BLUE)Validating Kustomize configuration (dev)...$(RESET)\n"
|
|
@kubectl kustomize k8s-kustomize/overlays/dev | kubectl apply --dry-run=client --validate=true -f -
|
|
|
|
kustomize-validate-prod: ## Validate Kustomize configuration (production)
|
|
@printf "$(BLUE)Validating Kustomize configuration (prod)...$(RESET)\n"
|
|
@kubectl kustomize k8s-kustomize/overlays/prod | kubectl apply --dry-run=client --validate=true -f -
|
|
|
|
##@ Environment Configuration
|
|
|
|
generate-config-dev: ## Generate development configuration from environment variables
|
|
@printf "$(BLUE)Generating development configuration...$(RESET)\n"
|
|
@./scripts/generate-config.sh dev
|
|
|
|
generate-config-prod: ## Generate production configuration from environment variables
|
|
@printf "$(BLUE)Generating production configuration...$(RESET)\n"
|
|
@./scripts/generate-config.sh prod
|
|
|
|
generate-config-staging: ## Generate staging configuration from environment variables
|
|
@printf "$(BLUE)Generating staging configuration...$(RESET)\n"
|
|
@./scripts/generate-config.sh staging
|
|
|
|
generate-config-all: ## Generate all environment configurations
|
|
@printf "$(BLUE)Generating all environment configurations...$(RESET)\n"
|
|
@./scripts/generate-config.sh dev
|
|
@./scripts/generate-config.sh prod
|
|
@./scripts/generate-config.sh staging
|
|
|
|
validate-config: ## Validate generated configuration
|
|
@printf "$(BLUE)Validating generated configuration...$(RESET)\n"
|
|
@./scripts/generate-config.sh --validate
|
|
|
|
generate-secrets-template: ## Generate secrets template files
|
|
@printf "$(BLUE)Generating secrets templates...$(RESET)\n"
|
|
@./scripts/generate-config.sh dev --secrets
|
|
@./scripts/generate-config.sh prod --secrets
|
|
|
|
kustomize-diff-dev: ## Show diff for Kustomize deployment (development)
|
|
@printf "$(BLUE)Showing Kustomize diff (dev)...$(RESET)\n"
|
|
@kubectl diff -k k8s-kustomize/overlays/dev || true
|
|
|
|
kustomize-diff-prod: ## Show diff for Kustomize deployment (production)
|
|
@printf "$(BLUE)Showing Kustomize diff (prod)...$(RESET)\n"
|
|
@kubectl diff -k k8s-kustomize/overlays/prod || true
|
|
|
|
kustomize-build-dev: ## Build Kustomize manifests (development)
|
|
@printf "$(BLUE)Building Kustomize manifests (dev)...$(RESET)\n"
|
|
@kubectl kustomize k8s-kustomize/overlays/dev
|
|
|
|
kustomize-build-prod: ## Build Kustomize manifests (production)
|
|
@printf "$(BLUE)Building Kustomize manifests (prod)...$(RESET)\n"
|
|
@kubectl kustomize k8s-kustomize/overlays/prod
|
|
|
|
kustomize-status-dev: ## Show Kustomize deployment status (development)
|
|
@printf "$(BLUE)Showing Kustomize deployment status (dev)...$(RESET)\n"
|
|
@kubectl get all -n rxminder-dev -l app=rxminder
|
|
|
|
kustomize-status-prod: ## Show Kustomize deployment status (production)
|
|
@printf "$(BLUE)Showing Kustomize deployment status (prod)...$(RESET)\n"
|
|
@kubectl get all -n rxminder-prod -l app=rxminder
|
|
|
|
##@ Docker
|
|
|
|
docker-setup: ## Setup Docker buildx
|
|
@printf "$(BLUE)Setting up Docker buildx...$(RESET)\n"
|
|
@bun run docker:setup
|
|
|
|
docker-build: ## Build multi-platform Docker images
|
|
@printf "$(BLUE)Building multi-platform Docker images...$(RESET)\n"
|
|
@bun run docker:build
|
|
|
|
docker-build-local: ## Build local Docker image
|
|
@printf "$(BLUE)Building local Docker image...$(RESET)\n"
|
|
@bun run docker:build-local
|
|
|
|
docker-bake: ## Build with Docker Bake
|
|
@printf "$(BLUE)Building with Docker Bake...$(RESET)\n"
|
|
@bun run docker:bake
|
|
|
|
docker-inspect: ## Inspect Docker buildx
|
|
@printf "$(BLUE)Inspecting Docker buildx...$(RESET)\n"
|
|
@bun run docker:inspect
|
|
|
|
docker-cleanup: ## Cleanup Docker buildx
|
|
@printf "$(BLUE)Cleaning up Docker buildx...$(RESET)\n"
|
|
@bun run docker:cleanup
|
|
|
|
docker-stop: ## Stop Docker Compose services
|
|
@printf "$(BLUE)Stopping Docker Compose services...$(RESET)\n"
|
|
@if docker-compose -f docker/docker-compose.yaml ps --services 2>/dev/null | grep -q .; then \
|
|
docker-compose -f docker/docker-compose.yaml stop; \
|
|
printf "$(GREEN)Docker Compose services stopped$(RESET)\n"; \
|
|
else \
|
|
printf "$(YELLOW)No Docker Compose services found running$(RESET)\n"; \
|
|
fi
|
|
|
|
docker-down: ## Stop and remove Docker Compose containers
|
|
@printf "$(BLUE)Stopping and removing Docker Compose containers...$(RESET)\n"
|
|
@if docker-compose -f docker/docker-compose.yaml ps --services 2>/dev/null | grep -q .; then \
|
|
docker-compose -f docker/docker-compose.yaml down; \
|
|
printf "$(GREEN)Docker Compose containers stopped and removed$(RESET)\n"; \
|
|
else \
|
|
printf "$(YELLOW)No Docker Compose services found running$(RESET)\n"; \
|
|
fi
|
|
|
|
docker-down-volumes: ## Stop, remove containers and delete volumes
|
|
@printf "$(BLUE)Stopping containers and removing volumes...$(RESET)\n"
|
|
@if docker-compose -f docker/docker-compose.yaml ps --services 2>/dev/null | grep -q .; then \
|
|
docker-compose -f docker/docker-compose.yaml down --volumes --remove-orphans; \
|
|
printf "$(GREEN)Docker Compose containers and volumes removed$(RESET)\n"; \
|
|
else \
|
|
printf "$(YELLOW)No Docker Compose services found running$(RESET)\n"; \
|
|
fi
|
|
|
|
docker-stop-all: ## Stop and remove ALL Docker containers (use with caution)
|
|
@printf "$(BLUE)Stopping all Docker containers...$(RESET)\n"
|
|
@docker stop $$(docker ps -aq) 2>/dev/null || true
|
|
@docker rm $$(docker ps -aq) 2>/dev/null || true
|
|
|
|
docker-prune: ## Remove unused Docker images and volumes
|
|
@printf "$(BLUE)Cleaning up Docker images and volumes...$(RESET)\n"
|
|
@docker image prune -f --filter "until=24h" 2>/dev/null || true
|
|
@docker volume prune -f 2>/dev/null || true
|
|
@docker system prune -f 2>/dev/null || true
|
|
|
|
##@ Gitea
|
|
|
|
gitea-setup: ## Setup Gitea integration
|
|
@printf "$(BLUE)Setting up Gitea integration...$(RESET)\n"
|
|
@bun run gitea:setup
|
|
|
|
gitea-build: ## Build multi-platform images for Gitea
|
|
@printf "$(BLUE)Building multi-platform images for Gitea...$(RESET)\n"
|
|
@bun run gitea:build
|
|
|
|
gitea-build-local: ## Build local image for Gitea
|
|
@printf "$(BLUE)Building local image for Gitea...$(RESET)\n"
|
|
@bun run gitea:build-local
|
|
|
|
gitea-build-staging: ## Build staging image for Gitea
|
|
@printf "$(BLUE)Building staging image for Gitea...$(RESET)\n"
|
|
@bun run gitea:build-staging
|
|
|
|
gitea-build-prod: ## Build production image for Gitea
|
|
@printf "$(BLUE)Building production image for Gitea...$(RESET)\n"
|
|
@bun run gitea:build-prod
|
|
|
|
gitea-test: ## Test Gitea integration
|
|
@printf "$(BLUE)Testing Gitea integration...$(RESET)\n"
|
|
@bun run gitea:test
|
|
|
|
gitea-deploy: ## Deploy to Gitea
|
|
@printf "$(BLUE)Deploying to Gitea...$(RESET)\n"
|
|
@bun run gitea:deploy
|
|
|
|
gitea-status: ## Show Gitea deployment status
|
|
@printf "$(BLUE)Showing Gitea status...$(RESET)\n"
|
|
@bun run gitea:status
|
|
|
|
gitea-cleanup: ## Cleanup Gitea resources
|
|
@printf "$(BLUE)Cleaning up Gitea resources...$(RESET)\n"
|
|
@bun run gitea:cleanup
|
|
|
|
##@ Quick Commands
|
|
|
|
start: dev ## Alias for dev (start development server)
|
|
|
|
build-and-test: build test ## Build and run tests
|
|
@printf "$(GREEN)Build and test completed!$(RESET)\n"
|
|
|
|
full-check-backend: lint test-backend ## Run backend code quality check (unit + integration tests only)
|
|
@printf "$(GREEN)Backend check completed!$(RESET)\n"
|
|
|
|
full-check: lint test-all ## Run full code quality check (includes unit + integration + E2E tests)
|
|
@printf "$(GREEN)Full check completed!$(RESET)\n"
|
|
|
|
# Legacy deployment (using shell scripts)
|
|
quick-deploy: build k8s-deploy ## Quick build and deploy to Kubernetes (legacy)
|
|
@printf "$(GREEN)Quick deployment completed!$(RESET)\n"
|
|
|
|
# Kustomize deployment shortcuts
|
|
deploy-dev: kustomize-deploy-dev ## Deploy to development environment with Kustomize
|
|
@printf "$(GREEN)Development deployment completed!$(RESET)\n"
|
|
|
|
deploy-prod: kustomize-deploy-prod ## Deploy to production environment with Kustomize
|
|
@printf "$(GREEN)Production deployment completed!$(RESET)\n"
|
|
|
|
quick-deploy-dev: build deploy-dev ## Build and deploy to development with Kustomize
|
|
@printf "$(GREEN)Quick development deployment completed!$(RESET)\n"
|
|
|
|
quick-deploy-prod: build deploy-prod ## Build and deploy to production with Kustomize
|
|
@printf "$(GREEN)Quick production deployment completed!$(RESET)\n"
|
|
|
|
undeploy-dev: kustomize-undeploy-dev ## Remove development deployment
|
|
@printf "$(GREEN)Development undeploy completed!$(RESET)\n"
|
|
|
|
undeploy-prod: kustomize-undeploy-prod ## Remove production deployment
|
|
@printf "$(GREEN)Production undeploy completed!$(RESET)\n"
|
|
|
|
status-dev: kustomize-status-dev ## Show development deployment status
|
|
@printf "$(GREEN)Development status check completed!$(RESET)\n"
|
|
|
|
status-prod: kustomize-status-prod ## Show production deployment status
|
|
@printf "$(GREEN)Production status check completed!$(RESET)\n"
|
|
|
|
validate-kustomize: kustomize-validate-dev kustomize-validate-prod ## Validate all Kustomize configurations
|
|
@printf "$(GREEN)Kustomize validation completed!$(RESET)\n"
|
|
|
|
##@ Environment-Aware Deployment
|
|
|
|
deploy-with-env-dev: ## Deploy to development using environment variables
|
|
@printf "$(BLUE)Deploying to development with environment variables...$(RESET)\n"
|
|
@./scripts/deploy-with-env.sh dev apply
|
|
|
|
deploy-with-env-prod: ## Deploy to production using environment variables
|
|
@printf "$(BLUE)Deploying to production with environment variables...$(RESET)\n"
|
|
@./scripts/deploy-with-env.sh prod apply
|
|
|
|
deploy-with-env-staging: ## Deploy to staging using environment variables
|
|
@printf "$(BLUE)Deploying to staging with environment variables...$(RESET)\n"
|
|
@./scripts/deploy-with-env.sh staging apply
|
|
|
|
undeploy-with-env-dev: ## Remove development deployment using environment variables
|
|
@printf "$(BLUE)Removing development deployment with environment variables...$(RESET)\n"
|
|
@./scripts/deploy-with-env.sh dev delete
|
|
|
|
undeploy-with-env-prod: ## Remove production deployment using environment variables
|
|
@printf "$(BLUE)Removing production deployment with environment variables...$(RESET)\n"
|
|
@./scripts/deploy-with-env.sh prod delete
|
|
|
|
diff-with-env-dev: ## Show development diff using environment variables
|
|
@printf "$(BLUE)Showing development diff with environment variables...$(RESET)\n"
|
|
@./scripts/deploy-with-env.sh dev diff
|
|
|
|
diff-with-env-prod: ## Show production diff using environment variables
|
|
@printf "$(BLUE)Showing production diff with environment variables...$(RESET)\n"
|
|
@./scripts/deploy-with-env.sh prod diff
|
|
|
|
status-with-env-dev: ## Show development status using environment variables
|
|
@printf "$(BLUE)Showing development status with environment variables...$(RESET)\n"
|
|
@./scripts/deploy-with-env.sh dev status
|
|
|
|
status-with-env-prod: ## Show production status using environment variables
|
|
@printf "$(BLUE)Showing production status with environment variables...$(RESET)\n"
|
|
@./scripts/deploy-with-env.sh prod status
|
|
|
|
reset: clean install ## Reset project (clean and reinstall)
|
|
@printf "$(GREEN)Project reset completed!$(RESET)\n"
|