# Environment Variables Guide This guide explains how to use environment variables with the rxminder Kustomize deployment system. ## Overview The rxminder application supports multiple ways to configure deployments using environment variables: 1. **Static Configuration**: Pre-generated config files 2. **Dynamic Configuration**: Runtime environment variable injection 3. **Hybrid Approach**: Combination of both methods ## Environment Variable Sources Variables are loaded in the following priority order (last wins): 1. `~/.env` - Global user environment 2. `./.env` - Project-wide environment 3. `./.env.{environment}` - Environment-specific (e.g., `.env.dev`, `.env.prod`) 4. `./.env.local` - Local overrides (git-ignored) 5. System environment variables ## Quick Start ### Method 1: Generate Static Configuration ```bash # Generate configuration from your environment variables make generate-config-dev make generate-config-prod # Deploy using generated config make deploy-dev ``` ### Method 2: Dynamic Environment Injection ```bash # Deploy with runtime environment variable substitution make deploy-with-env-dev make deploy-with-env-prod ``` ## Environment Files Setup ### 1. Global User Environment (`~/.env`) Store your personal/machine-specific settings: ```bash # ~/.env REGISTRY_USERNAME=your_username REGISTRY_EMAIL=your_email@example.com KUBECONFIG=/path/to/your/kubeconfig ``` ### 2. Project Environment (`./.env`) Store project-wide defaults: ```bash # ./.env APP_NAME=rxminder REGISTRY_URL=gitea-http.taildb3494.ts.net IMAGE_REPOSITORY=will/rxminder COUCHDB_DATABASE_NAME=meds_app ``` ### 3. Environment-Specific Files #### Development (`./.env.dev`) ```bash NODE_ENV=development LOG_LEVEL=debug DEBUG=true IMAGE_TAG=dev INGRESS_HOST=rxminder-dev.local DEV_MODE=true ENABLE_MONITORING=false # Development database COUCHDB_USERNAME=admin COUCHDB_PASSWORD=devpass123 # Development resource limits FRONTEND_MEMORY_REQUEST=16Mi FRONTEND_MEMORY_LIMIT=32Mi COUCHDB_MEMORY_REQUEST=64Mi COUCHDB_MEMORY_LIMIT=128Mi STORAGE_SIZE=1Gi ``` #### Production (`./.env.prod`) ```bash NODE_ENV=production LOG_LEVEL=warn DEBUG=false IMAGE_TAG=v1.0.0 INGRESS_HOST=rxminder.yourdomain.com ENABLE_MONITORING=true ENABLE_METRICS=true ENABLE_TRACING=true # Production performance CACHE_TTL=3600 REQUEST_TIMEOUT=30000 MAX_CONNECTIONS=200 # Production resources FRONTEND_REPLICAS=3 FRONTEND_MEMORY_REQUEST=256Mi FRONTEND_MEMORY_LIMIT=512Mi COUCHDB_MEMORY_REQUEST=512Mi COUCHDB_MEMORY_LIMIT=1Gi STORAGE_SIZE=10Gi STORAGE_CLASS=ssd # Security ENABLE_SECURITY_HEADERS=true ENABLE_RATE_LIMITING=true CORS_ORIGIN=https://rxminder.yourdomain.com # TLS/SSL ENABLE_TLS=true CERT_MANAGER_ISSUER=letsencrypt-prod ``` #### Staging (`./.env.staging`) ```bash NODE_ENV=staging LOG_LEVEL=info DEBUG=false IMAGE_TAG=staging INGRESS_HOST=staging.rxminder.yourdomain.com ENABLE_MONITORING=true # Staging resources (between dev and prod) FRONTEND_REPLICAS=2 FRONTEND_MEMORY_REQUEST=128Mi FRONTEND_MEMORY_LIMIT=256Mi STORAGE_SIZE=5Gi ``` ### 4. Local Overrides (`./.env.local`) **Note**: This file should be in `.gitignore` and used for sensitive local settings: ```bash # ./.env.local (DO NOT COMMIT) COUCHDB_PASSWORD=your_secure_password REGISTRY_PASSWORD=your_registry_token API_SECRET_KEY=your_secret_key JWT_SECRET=your_jwt_secret # Local development overrides INGRESS_HOST=localhost:8080 DEV_API_URL=http://localhost:5984 ``` ## Available Environment Variables ### Core Application Variables | Variable | Default | Description | | ------------- | ------------ | ------------------------------------------------------------ | | `APP_NAME` | `rxminder` | Application name used in labels and resources | | `NODE_ENV` | `production` | Runtime environment (`development`, `staging`, `production`) | | `LOG_LEVEL` | `info` | Logging level (`debug`, `info`, `warn`, `error`) | | `DEBUG` | `false` | Enable debug mode | | `APP_VERSION` | `1.0.0` | Application version | ### Container Registry Variables | Variable | Default | Description | | ------------------- | ------------------------------ | -------------------------------- | | `REGISTRY_URL` | `gitea-http.taildb3494.ts.net` | Container registry URL | | `IMAGE_REPOSITORY` | `will/rxminder` | Image repository path | | `IMAGE_TAG` | `latest` | Image tag to deploy | | `REGISTRY_USERNAME` | - | Registry authentication username | | `REGISTRY_PASSWORD` | - | Registry authentication password | | `REGISTRY_EMAIL` | - | Registry authentication email | ### Database Variables | Variable | Default | Description | | ----------------------- | -------------------------- | ---------------------------- | | `DB_HOST` | `rxminder-couchdb-service` | Database host | | `DB_PORT` | `5984` | Database port | | `COUCHDB_DATABASE_NAME` | `meds_app` | CouchDB database name | | `COUCHDB_USERNAME` | `admin` | Database username | | `COUCHDB_PASSWORD` | - | Database password (required) | ### Network & Ingress Variables | Variable | Default | Description | | --------------------- | -------------------- | -------------------- | | `INGRESS_HOST` | Environment-specific | Ingress hostname | | `INGRESS_CLASS` | `nginx` | Ingress class to use | | `ENABLE_TLS` | `false` | Enable TLS/HTTPS | | `CERT_MANAGER_ISSUER` | `letsencrypt-prod` | Certificate issuer | | `CORS_ORIGIN` | `*` | CORS allowed origins | ### Performance Variables | Variable | Default | Description | | ------------------- | ------- | ------------------------------- | | `FRONTEND_REPLICAS` | `1` | Number of frontend replicas | | `CACHE_TTL` | `1800` | Cache time-to-live in seconds | | `REQUEST_TIMEOUT` | `30000` | Request timeout in milliseconds | | `MAX_CONNECTIONS` | `100` | Maximum concurrent connections | ### Resource Limits | Variable | Default | Description | | ------------------------- | ---------- | ----------------------- | | `FRONTEND_MEMORY_REQUEST` | `32Mi` | Frontend memory request | | `FRONTEND_MEMORY_LIMIT` | `64Mi` | Frontend memory limit | | `FRONTEND_CPU_REQUEST` | `20m` | Frontend CPU request | | `FRONTEND_CPU_LIMIT` | `40m` | Frontend CPU limit | | `COUCHDB_MEMORY_REQUEST` | `64Mi` | CouchDB memory request | | `COUCHDB_MEMORY_LIMIT` | `128Mi` | CouchDB memory limit | | `STORAGE_SIZE` | `1Gi` | Storage volume size | | `STORAGE_CLASS` | `standard` | Storage class | ### Monitoring & Observability | Variable | Default | Description | | ------------------- | ------- | -------------------------- | | `ENABLE_MONITORING` | `false` | Enable monitoring features | | `ENABLE_METRICS` | `false` | Enable metrics collection | | `ENABLE_TRACING` | `false` | Enable distributed tracing | | `METRICS_PORT` | `9090` | Metrics server port | ### Security Variables | Variable | Default | Description | | ------------------------- | ------- | ----------------------- | | `ENABLE_SECURITY_HEADERS` | `false` | Enable security headers | | `ENABLE_RATE_LIMITING` | `false` | Enable rate limiting | | `API_SECRET_KEY` | - | API secret key | | `JWT_SECRET` | - | JWT signing secret | ## Usage Examples ### Basic Development Setup 1. Create your development environment file: ```bash cat > .env.dev << EOF NODE_ENV=development LOG_LEVEL=debug DEBUG=true IMAGE_TAG=dev INGRESS_HOST=rxminder-dev.local COUCHDB_PASSWORD=devpass123 EOF ``` 2. Generate configuration and deploy: ```bash make generate-config-dev make deploy-dev ``` ### Production Deployment with Secrets 1. Set up your production environment: ```bash # .env.prod (commit this) NODE_ENV=production LOG_LEVEL=warn IMAGE_TAG=v1.0.0 INGRESS_HOST=rxminder.yourdomain.com ENABLE_TLS=true # .env.local (DO NOT commit) COUCHDB_PASSWORD=your_secure_production_password REGISTRY_PASSWORD=your_registry_token ``` 2. Deploy with environment variables: ```bash make deploy-with-env-prod ``` ### Dynamic Configuration Updates Update configuration without rebuilding: ```bash # Update environment variable export LOG_LEVEL=debug # Deploy with updated configuration ./scripts/deploy-with-env.sh prod apply ``` ### Testing Different Configurations ```bash # Test with different image tag export IMAGE_TAG=feature-branch make diff-with-env-dev # Test with different resources export FRONTEND_REPLICAS=5 ./scripts/deploy-with-env.sh prod dry-run ``` ## Available Commands ### Configuration Generation ```bash make generate-config-dev # Generate dev config from env vars make generate-config-prod # Generate prod config from env vars make generate-config-staging # Generate staging config from env vars make generate-config-all # Generate all environment configs make validate-config # Validate generated configuration make generate-secrets-template # Generate secrets template files ``` ### Environment-Aware Deployment ```bash make deploy-with-env-dev # Deploy dev with env vars make deploy-with-env-prod # Deploy prod with env vars make deploy-with-env-staging # Deploy staging with env vars make undeploy-with-env-dev # Remove dev deployment make diff-with-env-dev # Show dev diff with env vars make status-with-env-dev # Show dev status with env vars ``` ### Direct Script Usage ```bash # Generate configuration ./scripts/generate-config.sh dev ./scripts/generate-config.sh prod --secrets # Deploy with environment variables ./scripts/deploy-with-env.sh dev apply ./scripts/deploy-with-env.sh prod diff ./scripts/deploy-with-env.sh staging delete ``` ## Best Practices ### Security 1. **Never commit sensitive data**: - Add `.env.local` to `.gitignore` - Use external secret management for production - Rotate passwords regularly 2. **Use environment-specific files**: - `.env.dev` for development settings - `.env.prod` for production configuration - `.env.local` for sensitive overrides ### Organization 1. **Group related variables**: - Database settings together - Resource limits together - Feature flags together 2. **Use descriptive names**: - `FRONTEND_MEMORY_LIMIT` vs `MEM_LIMIT` - `ENABLE_DEBUG_MODE` vs `DEBUG` 3. **Document your variables**: - Add comments explaining purpose - Include example values - Note required vs optional ### Development Workflow 1. **Start with examples**: ```bash cp .env.example .env.dev # Edit .env.dev with your settings ``` 2. **Test configurations**: ```bash make generate-config-dev make kustomize-dry-run-dev ``` 3. **Validate before deploying**: ```bash make validate-config make diff-with-env-dev ``` ## Troubleshooting ### Common Issues 1. **Variables not being loaded**: - Check file permissions (`chmod 644 .env.*`) - Verify file format (no spaces around `=`) - Check file encoding (UTF-8) 2. **Configuration not updating**: - Regenerate config: `make generate-config-dev` - Clear cached resources: `kubectl delete configmap -l app=rxminder` 3. **Deployment failures**: - Validate syntax: `make validate-config` - Check logs: `kubectl logs -l app=rxminder` - Verify resources: `kubectl describe deployment rxminder-frontend` ### Debug Commands ```bash # Check loaded environment variables ./scripts/generate-config.sh dev --dry-run # Validate generated configuration make validate-config # Show what would be deployed ./scripts/deploy-with-env.sh dev dry-run # Check current deployment status make status-with-env-dev ``` ## Migration from Legacy System ### Step 1: Extract Current Configuration ```bash # Export current settings to environment file echo "APP_NAME=rxminder" > .env.dev echo "IMAGE_TAG=dev" >> .env.dev # ... add other variables ``` ### Step 2: Test New System ```bash # Generate and validate configuration make generate-config-dev make validate-config # Test deployment make kustomize-dry-run-dev ``` ### Step 3: Deploy ```bash # Deploy using new system make deploy-with-env-dev # Verify deployment make status-with-env-dev ``` ## External Secret Management For production environments, integrate with external secret management: ### HashiCorp Vault Integration ```bash # .env.prod VAULT_ADDR=https://vault.yourdomain.com VAULT_ROLE=rxminder-prod VAULT_SECRET_PATH=secret/rxminder/prod # Use Vault Agent or CSI driver to inject secrets ``` ### Kubernetes External Secrets ```yaml # external-secret.yaml apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: rxminder-secrets spec: secretStoreRef: name: vault-backend kind: SecretStore target: name: couchdb-secret data: - secretKey: password remoteRef: key: rxminder/prod property: couchdb_password ``` ### AWS Secrets Manager ```bash # .env.prod AWS_REGION=us-west-2 AWS_SECRET_NAME=rxminder/prod/couchdb # Use AWS Load Balancer Controller or external-secrets-operator ``` ## Summary The environment variable system provides: - **Flexibility**: Configure deployments without changing code - **Security**: Keep sensitive data out of version control - **Consistency**: Standardized configuration across environments - **Maintainability**: Clear separation of configuration and code Choose the approach that best fits your workflow: - **Static generation** for stable, version-controlled configurations - **Dynamic injection** for flexible, runtime configurations - **Hybrid approach** for the best of both worlds For more information, see: - [Configuration Guide](COMPLETE_TEMPLATE_CONFIGURATION.md) - [App Name Configuration](APP_NAME_CONFIGURATION.md) - [Project Structure](../architecture/PROJECT_STRUCTURE.md)