331 lines
9.3 KiB
Bash
Executable File
331 lines
9.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# 🚀 RxMinder Template-based Kubernetes Deployment Script
|
|
# This script processes template files and applies them to Kubernetes
|
|
|
|
set -euo pipefail
|
|
|
|
# Script configuration
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
K8S_DIR="$(dirname "$SCRIPT_DIR")/k8s"
|
|
ENV_FILE="$(dirname "$SCRIPT_DIR")/.env"
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
print_status() {
|
|
echo -e "${BLUE}$1${NC}"
|
|
}
|
|
|
|
print_success() {
|
|
echo -e "${GREEN}✅ $1${NC}"
|
|
}
|
|
|
|
print_warning() {
|
|
echo -e "${YELLOW}⚠️ $1${NC}"
|
|
}
|
|
|
|
print_error() {
|
|
echo -e "${RED}❌ $1${NC}"
|
|
}
|
|
|
|
# Function to load environment variables
|
|
load_env() {
|
|
if [[ -f "$ENV_FILE" ]]; then
|
|
print_status "Loading environment variables from .env..."
|
|
# Export variables from .env file
|
|
set -a
|
|
source "$ENV_FILE"
|
|
set +a
|
|
print_success "Environment variables loaded"
|
|
else
|
|
print_warning ".env file not found at $ENV_FILE"
|
|
print_warning "Using default values. Copy .env.example to .env and customize."
|
|
fi
|
|
}
|
|
|
|
# Function to substitute environment variables in templates
|
|
substitute_template() {
|
|
local template_file="$1"
|
|
local output_file="$2"
|
|
|
|
print_status "Processing template: $template_file"
|
|
|
|
# Use envsubst to substitute environment variables
|
|
if command -v envsubst >/dev/null 2>&1; then
|
|
envsubst < "$template_file" > "$output_file"
|
|
else
|
|
print_error "envsubst not found. Please install gettext package."
|
|
exit 1
|
|
fi
|
|
|
|
print_success "Generated: $output_file"
|
|
}
|
|
|
|
# Function to apply Kubernetes resources
|
|
apply_k8s_resource() {
|
|
local resource_file="$1"
|
|
|
|
if [[ -f "$resource_file" ]]; then
|
|
print_status "Applying Kubernetes resource: $resource_file"
|
|
if kubectl apply -f "$resource_file"; then
|
|
print_success "Applied: $resource_file"
|
|
else
|
|
print_error "Failed to apply: $resource_file"
|
|
return 1
|
|
fi
|
|
else
|
|
print_warning "Resource file not found: $resource_file"
|
|
fi
|
|
}
|
|
|
|
# Function to validate required environment variables
|
|
validate_env() {
|
|
local required_vars=(
|
|
"APP_NAME"
|
|
"DOCKER_IMAGE"
|
|
"COUCHDB_USER"
|
|
"COUCHDB_PASSWORD"
|
|
"INGRESS_HOST"
|
|
"STORAGE_CLASS"
|
|
"STORAGE_SIZE"
|
|
)
|
|
|
|
local missing_vars=()
|
|
|
|
for var in "${required_vars[@]}"; do
|
|
if [[ -z "${!var:-}" ]]; then
|
|
missing_vars+=("$var")
|
|
fi
|
|
done
|
|
|
|
if [[ ${#missing_vars[@]} -gt 0 ]]; then
|
|
print_error "Missing required environment variables:"
|
|
for var in "${missing_vars[@]}"; do
|
|
echo -e " ${RED}- $var${NC}"
|
|
done
|
|
print_warning "Please update your .env file with these variables."
|
|
exit 1
|
|
fi
|
|
|
|
print_success "All required environment variables are set"
|
|
}
|
|
|
|
# Function to process all templates
|
|
process_templates() {
|
|
local temp_dir="/tmp/rxminder-k8s-$$"
|
|
mkdir -p "$temp_dir"
|
|
|
|
print_status "Processing Kubernetes templates..."
|
|
|
|
# Find all template files
|
|
local template_files=(
|
|
"$K8S_DIR/couchdb-secret.yaml.template"
|
|
"$K8S_DIR/ingress.yaml.template"
|
|
)
|
|
|
|
# Add any additional template files
|
|
for template_file in "$K8S_DIR"/*.template; do
|
|
if [[ -f "$template_file" ]]; then
|
|
template_files+=("$template_file")
|
|
fi
|
|
done
|
|
|
|
# Process each template
|
|
for template_file in "${template_files[@]}"; do
|
|
if [[ -f "$template_file" ]]; then
|
|
local base_name
|
|
base_name="$(basename "$template_file" .template)"
|
|
local output_file="$temp_dir/$base_name"
|
|
substitute_template "$template_file" "$output_file"
|
|
fi
|
|
done
|
|
|
|
echo "$temp_dir"
|
|
}
|
|
|
|
# Function to deploy resources in correct order
|
|
deploy_resources() {
|
|
local resource_dir="$1"
|
|
|
|
print_status "Deploying Kubernetes resources..."
|
|
|
|
# Deploy in specific order for dependencies
|
|
local deployment_order=(
|
|
"couchdb-secret.yaml"
|
|
"couchdb-pvc.yaml"
|
|
"couchdb-service.yaml"
|
|
"couchdb-statefulset.yaml"
|
|
"configmap.yaml"
|
|
"frontend-deployment.yaml"
|
|
"frontend-service.yaml"
|
|
"ingress.yaml"
|
|
"$K8S_DIR/network-policy.yaml"
|
|
"$K8S_DIR/hpa.yaml"
|
|
)
|
|
|
|
for resource in "${deployment_order[@]}"; do
|
|
if [[ "$resource" == *.yaml ]]; then
|
|
# Check if it's a template-generated file
|
|
if [[ -f "$resource_dir/$(basename "$resource")" ]]; then
|
|
apply_k8s_resource "$resource_dir/$(basename "$resource")"
|
|
else
|
|
# Apply directly from k8s directory
|
|
apply_k8s_resource "$resource"
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Function to run database seeding job
|
|
run_db_seed() {
|
|
print_status "Running database seed job..."
|
|
|
|
# Apply the db-seed-job (which uses environment variables from secret)
|
|
if kubectl apply -f "$K8S_DIR/db-seed-job.yaml"; then
|
|
print_success "Database seed job submitted"
|
|
|
|
# Wait for job completion
|
|
print_status "Waiting for database seed job to complete..."
|
|
if kubectl wait --for=condition=complete --timeout=300s job/db-seed-job; then
|
|
print_success "Database seeding completed successfully"
|
|
else
|
|
print_warning "Database seed job may have failed. Check logs:"
|
|
echo "kubectl logs job/db-seed-job"
|
|
fi
|
|
else
|
|
print_error "Failed to apply database seed job"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to display deployment status
|
|
show_status() {
|
|
print_status "Deployment Status:"
|
|
echo
|
|
|
|
print_status "Pods:"
|
|
kubectl get pods -l app="${APP_NAME:-rxminder}"
|
|
echo
|
|
|
|
print_status "Services:"
|
|
kubectl get services -l app="${APP_NAME:-rxminder}"
|
|
echo
|
|
|
|
print_status "Ingress:"
|
|
kubectl get ingress
|
|
echo
|
|
|
|
if [[ -n "${INGRESS_HOST:-}" ]]; then
|
|
print_success "Application should be available at: http://${INGRESS_HOST}"
|
|
fi
|
|
}
|
|
|
|
# Function to cleanup temporary files
|
|
cleanup() {
|
|
if [[ -n "${temp_dir:-}" && -d "$temp_dir" ]]; then
|
|
rm -rf "$temp_dir"
|
|
fi
|
|
}
|
|
|
|
# Main deployment function
|
|
main() {
|
|
local command="${1:-deploy}"
|
|
|
|
case "$command" in
|
|
"deploy"|"apply")
|
|
print_status "🚀 Starting RxMinder Kubernetes deployment..."
|
|
echo
|
|
|
|
# Set default values for required variables
|
|
export APP_NAME="${APP_NAME:-rxminder}"
|
|
export DOCKER_IMAGE="${DOCKER_IMAGE:-gitea-http.taildb3494.ts.net/will/meds:latest}"
|
|
export COUCHDB_USER="${COUCHDB_USER:-admin}"
|
|
export COUCHDB_PASSWORD="${COUCHDB_PASSWORD:-change-this-secure-password}"
|
|
export INGRESS_HOST="${INGRESS_HOST:-rxminder.local}"
|
|
export STORAGE_CLASS="${STORAGE_CLASS:-longhorn}"
|
|
export STORAGE_SIZE="${STORAGE_SIZE:-5Gi}"
|
|
|
|
load_env
|
|
validate_env
|
|
|
|
# Process templates
|
|
temp_dir=$(process_templates)
|
|
trap cleanup EXIT
|
|
|
|
# Deploy resources
|
|
deploy_resources "$temp_dir"
|
|
|
|
# Run database seeding
|
|
run_db_seed
|
|
|
|
# Show status
|
|
echo
|
|
show_status
|
|
|
|
print_success "🎉 RxMinder deployment completed!"
|
|
;;
|
|
|
|
"status")
|
|
load_env
|
|
show_status
|
|
;;
|
|
|
|
"delete"|"cleanup")
|
|
print_status "🗑️ Cleaning up RxMinder deployment..."
|
|
kubectl delete all,pvc,secret,configmap,ingress -l app="${APP_NAME:-rxminder}" || true
|
|
kubectl delete job db-seed-job || true
|
|
print_success "Cleanup completed"
|
|
;;
|
|
|
|
"help"|"-h"|"--help")
|
|
echo "RxMinder Kubernetes Deployment Script"
|
|
echo
|
|
echo "Usage: $0 [command]"
|
|
echo
|
|
echo "Commands:"
|
|
echo " deploy Deploy RxMinder to Kubernetes (default)"
|
|
echo " status Show deployment status"
|
|
echo " delete Delete all RxMinder resources"
|
|
echo " help Show this help message"
|
|
echo
|
|
echo "Environment variables (set in .env):"
|
|
echo " APP_NAME Application name (default: rxminder)"
|
|
echo " DOCKER_IMAGE Container image to deploy"
|
|
echo " COUCHDB_USER Database username (default: admin)"
|
|
echo " COUCHDB_PASSWORD Database password (required)"
|
|
echo " INGRESS_HOST Ingress hostname (required)"
|
|
echo " STORAGE_CLASS Storage class for PVCs (default: longhorn)"
|
|
echo " STORAGE_SIZE Storage size for database (default: 5Gi)"
|
|
;;
|
|
|
|
*)
|
|
print_error "Unknown command: $command"
|
|
echo "Use '$0 help' for usage information"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Check if kubectl is available
|
|
if ! command -v kubectl >/dev/null 2>&1; then
|
|
print_error "kubectl not found. Please install kubectl and configure it to connect to your cluster."
|
|
exit 1
|
|
fi
|
|
|
|
# Check if envsubst is available
|
|
if ! command -v envsubst >/dev/null 2>&1; then
|
|
print_error "envsubst not found. Please install the gettext package:"
|
|
echo " Ubuntu/Debian: sudo apt-get install gettext"
|
|
echo " macOS: brew install gettext"
|
|
echo " RHEL/CentOS: sudo yum install gettext"
|
|
exit 1
|
|
fi
|
|
|
|
# Run main function
|
|
main "$@"
|