- Organized 252 files across project - Root directory: 187 → 2 files (98.9% reduction) - Moved configuration guides to docs/04-configuration/ - Moved troubleshooting guides to docs/09-troubleshooting/ - Moved quick start guides to docs/01-getting-started/ - Moved reports to reports/ directory - Archived temporary files - Generated comprehensive reports and documentation - Created maintenance scripts and guides All files organized according to established standards.
336 lines
10 KiB
Bash
Executable File
336 lines
10 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Deploy Miracles In Motion Web Platform to pve2
|
|
# React + Vite web application for nonprofit organization
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
|
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
|
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
|
|
# Configuration
|
|
PROXMOX_NODE="pve2"
|
|
PROXMOX_HOST="192.168.11.12"
|
|
PROXMOX_STORAGE="${PROXMOX_STORAGE:-thin4}"
|
|
CONTAINER_OS_TEMPLATE="local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst"
|
|
|
|
# Miracles In Motion Configuration
|
|
# Using Sankofa service layer VLAN 160 (10.160.0.0/22)
|
|
MIM_VLAN="160"
|
|
MIM_SUBNET="10.160.0.0/22"
|
|
MIM_GATEWAY="10.160.0.1"
|
|
|
|
# VMID Allocation (within Sankofa range: 7800-8999)
|
|
VMID_MIM_WEB=7810
|
|
VMID_MIM_API=7811
|
|
|
|
# Service IPs (VLAN 160)
|
|
MIM_WEB_IP="10.160.0.20"
|
|
MIM_API_IP="10.160.0.21"
|
|
|
|
# Resource allocation
|
|
MIM_WEB_MEMORY="4096" # 4GB
|
|
MIM_WEB_CORES="4"
|
|
MIM_WEB_DISK="50" # 50GB
|
|
|
|
MIM_API_MEMORY="2048" # 2GB
|
|
MIM_API_CORES="2"
|
|
MIM_API_DISK="30" # 30GB
|
|
|
|
# Project paths
|
|
MIM_PROJECT_PATH="/home/intlc/projects/proxmox/miracles_in_motion"
|
|
MIM_DEPLOY_PATH="/opt/miracles-in-motion"
|
|
|
|
# SSH function
|
|
ssh_pve2() {
|
|
ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 root@"$PROXMOX_HOST" "$@"
|
|
}
|
|
|
|
# Check if container exists
|
|
container_exists() {
|
|
local vmid=$1
|
|
ssh_pve2 "pct list 2>/dev/null | grep -q '^\s*$vmid\s'" 2>/dev/null
|
|
}
|
|
|
|
# Create Miracles In Motion container
|
|
create_mim_container() {
|
|
local vmid=$1
|
|
local hostname=$2
|
|
local ip_address=$3
|
|
local memory=$4
|
|
local cores=$5
|
|
local disk=$6
|
|
local service_type=$7
|
|
|
|
log_info "Creating Miracles In Motion $service_type: $hostname (VMID: $vmid, IP: $ip_address)"
|
|
|
|
if container_exists "$vmid"; then
|
|
log_warn "Container $vmid ($hostname) already exists, skipping creation"
|
|
return 0
|
|
fi
|
|
|
|
# Network configuration - using DHCP (VLAN tagging configured at bridge level)
|
|
local network_config="bridge=vmbr0,name=eth0,ip=dhcp,type=veth"
|
|
|
|
log_info "Creating container $vmid on $PROXMOX_NODE..."
|
|
ssh_pve2 "pct create $vmid \
|
|
$CONTAINER_OS_TEMPLATE \
|
|
--storage $PROXMOX_STORAGE \
|
|
--hostname $hostname \
|
|
--memory $memory \
|
|
--cores $cores \
|
|
--rootfs $PROXMOX_STORAGE:$disk \
|
|
--net0 '$network_config' \
|
|
--unprivileged 1 \
|
|
--swap 512 \
|
|
--onboot 1 \
|
|
--timezone America/Los_Angeles \
|
|
--features nesting=1,keyctl=1" 2>&1
|
|
|
|
if container_exists "$vmid"; then
|
|
log_success "Container $vmid created successfully"
|
|
|
|
# Start container
|
|
log_info "Starting container $vmid..."
|
|
ssh_pve2 "pct start $vmid" 2>&1 || true
|
|
|
|
# Wait for container to be ready
|
|
log_info "Waiting for container to be ready..."
|
|
sleep 5
|
|
|
|
# Basic setup
|
|
log_info "Configuring container $vmid..."
|
|
ssh_pve2 "pct exec $vmid -- bash -c 'export DEBIAN_FRONTEND=noninteractive; apt-get update -qq && apt-get install -y -qq curl wget git build-essential'" 2>&1 | grep -vE "(perl: warning|locale:)" || true
|
|
|
|
log_success "Miracles In Motion $service_type container $vmid ($hostname) deployed successfully"
|
|
return 0
|
|
else
|
|
log_error "Failed to create container $vmid"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Setup web service in container
|
|
setup_web_service() {
|
|
local vmid=$1
|
|
local hostname=$2
|
|
|
|
log_info "Setting up web service in container $vmid..."
|
|
|
|
# Install Node.js 18+
|
|
log_info "Installing Node.js..."
|
|
ssh_pve2 "pct exec $vmid -- bash -c 'curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && apt-get install -y nodejs'" 2>&1 | grep -vE "(perl: warning|locale:)" || true
|
|
|
|
# Install nginx for serving static files
|
|
log_info "Installing nginx..."
|
|
ssh_pve2 "pct exec $vmid -- bash -c 'apt-get install -y nginx'" 2>&1 | grep -vE "(perl: warning|locale:)" || true
|
|
|
|
# Create deployment directory
|
|
ssh_pve2 "pct exec $vmid -- bash -c 'mkdir -p $MIM_DEPLOY_PATH'" 2>&1
|
|
|
|
log_success "Web service setup complete for container $vmid"
|
|
}
|
|
|
|
# Copy project to container
|
|
copy_project_to_container() {
|
|
local vmid=$1
|
|
|
|
log_info "Copying project files to container $vmid..."
|
|
|
|
# Create a tarball of the project (excluding node_modules and dist)
|
|
log_info "Creating project archive..."
|
|
cd "$PROJECT_ROOT"
|
|
tar --exclude='node_modules' \
|
|
--exclude='dist' \
|
|
--exclude='.git' \
|
|
--exclude='*.log' \
|
|
-czf /tmp/miracles-in-motion.tar.gz -C miracles_in_motion .
|
|
|
|
# Copy to container
|
|
log_info "Transferring project to container..."
|
|
scp -o StrictHostKeyChecking=no /tmp/miracles-in-motion.tar.gz root@"$PROXMOX_HOST":/tmp/
|
|
ssh_pve2 "pct push $vmid /tmp/miracles-in-motion.tar.gz /tmp/miracles-in-motion.tar.gz"
|
|
|
|
# Extract in container
|
|
log_info "Extracting project in container..."
|
|
ssh_pve2 "pct exec $vmid -- bash -c 'cd $MIM_DEPLOY_PATH && tar -xzf /tmp/miracles-in-motion.tar.gz && rm /tmp/miracles-in-motion.tar.gz'"
|
|
|
|
# Cleanup local tarball
|
|
rm -f /tmp/miracles-in-motion.tar.gz
|
|
|
|
log_success "Project copied to container $vmid"
|
|
}
|
|
|
|
# Build and configure web application
|
|
build_web_application() {
|
|
local vmid=$1
|
|
|
|
log_info "Building web application in container $vmid..."
|
|
|
|
# Install dependencies
|
|
log_info "Installing npm dependencies..."
|
|
ssh_pve2 "pct exec $vmid -- bash -c 'cd $MIM_DEPLOY_PATH && npm install --legacy-peer-deps'" 2>&1 | tail -20
|
|
|
|
# Build the application
|
|
log_info "Building application..."
|
|
ssh_pve2 "pct exec $vmid -- bash -c 'cd $MIM_DEPLOY_PATH && npm run build'" 2>&1 | tail -20
|
|
|
|
# Configure nginx to serve the built files
|
|
log_info "Configuring nginx..."
|
|
ssh_pve2 "pct exec $vmid -- bash -c 'cat > /etc/nginx/sites-available/miracles-in-motion <<EOF
|
|
server {
|
|
listen 80;
|
|
server_name _;
|
|
root $MIM_DEPLOY_PATH/dist;
|
|
index index.html;
|
|
|
|
location / {
|
|
try_files \$uri \$uri/ /index.html;
|
|
}
|
|
|
|
location /api {
|
|
proxy_pass http://localhost:3001;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade \$http_upgrade;
|
|
proxy_set_header Connection \"upgrade\";
|
|
proxy_set_header Host \$host;
|
|
proxy_set_header X-Real-IP \$remote_addr;
|
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
}
|
|
}
|
|
EOF
|
|
ln -sf /etc/nginx/sites-available/miracles-in-motion /etc/nginx/sites-enabled/
|
|
rm -f /etc/nginx/sites-enabled/default
|
|
nginx -t && systemctl restart nginx'" 2>&1
|
|
|
|
log_success "Web application built and configured"
|
|
}
|
|
|
|
# Main deployment
|
|
main() {
|
|
echo ""
|
|
log_info "========================================="
|
|
log_info "Miracles In Motion Deployment to pve2"
|
|
log_info "========================================="
|
|
echo ""
|
|
log_info "Target Node: $PROXMOX_NODE ($PROXMOX_HOST)"
|
|
log_info "VLAN: $MIM_VLAN ($MIM_SUBNET)"
|
|
log_info "VMID Range: 7810-7811 (within Sankofa range 7800-8999)"
|
|
log_info "Project Path: $MIM_PROJECT_PATH"
|
|
echo ""
|
|
|
|
# Check if project exists
|
|
if [[ ! -d "$MIM_PROJECT_PATH" ]]; then
|
|
log_error "Project not found at $MIM_PROJECT_PATH"
|
|
exit 1
|
|
fi
|
|
log_success "Project found at $MIM_PROJECT_PATH"
|
|
echo ""
|
|
|
|
# Check connectivity to pve2
|
|
log_info "Checking connectivity to $PROXMOX_NODE..."
|
|
if ! ssh_pve2 "pvecm status >/dev/null 2>&1"; then
|
|
log_error "Cannot connect to $PROXMOX_NODE. Please check SSH access."
|
|
exit 1
|
|
fi
|
|
log_success "Connected to $PROXMOX_NODE"
|
|
echo ""
|
|
|
|
# Check if containers already exist
|
|
log_info "Checking existing Miracles In Motion containers..."
|
|
existing_containers=()
|
|
if container_exists "$VMID_MIM_WEB"; then
|
|
existing_containers+=("$VMID_MIM_WEB:mim-web-1")
|
|
log_warn "Container $VMID_MIM_WEB (mim-web-1) already exists"
|
|
fi
|
|
if container_exists "$VMID_MIM_API"; then
|
|
existing_containers+=("$VMID_MIM_API:mim-api-1")
|
|
log_warn "Container $VMID_MIM_API (mim-api-1) already exists"
|
|
fi
|
|
|
|
if [[ ${#existing_containers[@]} -gt 0 ]]; then
|
|
log_warn "Some Miracles In Motion containers already exist:"
|
|
for container in "${existing_containers[@]}"; do
|
|
echo " - $container"
|
|
done
|
|
echo ""
|
|
read -p "Continue with deployment? (y/N): " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
log_info "Deployment cancelled"
|
|
exit 0
|
|
fi
|
|
fi
|
|
echo ""
|
|
|
|
# Deploy Miracles In Motion Web
|
|
log_info "Deploying Miracles In Motion Web service..."
|
|
create_mim_container \
|
|
"$VMID_MIM_WEB" \
|
|
"mim-web-1" \
|
|
"$MIM_WEB_IP" \
|
|
"$MIM_WEB_MEMORY" \
|
|
"$MIM_WEB_CORES" \
|
|
"$MIM_WEB_DISK" \
|
|
"Web"
|
|
echo ""
|
|
|
|
# Setup web service
|
|
setup_web_service "$VMID_MIM_WEB" "mim-web-1"
|
|
echo ""
|
|
|
|
# Copy project to container
|
|
copy_project_to_container "$VMID_MIM_WEB"
|
|
echo ""
|
|
|
|
# Build and configure
|
|
build_web_application "$VMID_MIM_WEB"
|
|
echo ""
|
|
|
|
# Deploy API service (optional, for future use)
|
|
log_info "Deploying Miracles In Motion API service (optional)..."
|
|
create_mim_container \
|
|
"$VMID_MIM_API" \
|
|
"mim-api-1" \
|
|
"$MIM_API_IP" \
|
|
"$MIM_API_MEMORY" \
|
|
"$MIM_API_CORES" \
|
|
"$MIM_API_DISK" \
|
|
"API"
|
|
echo ""
|
|
|
|
# Summary
|
|
log_success "========================================="
|
|
log_success "Miracles In Motion Deployment Complete"
|
|
log_success "========================================="
|
|
echo ""
|
|
log_info "Deployed containers on $PROXMOX_NODE:"
|
|
echo " - VMID $VMID_MIM_WEB: mim-web-1 ($MIM_WEB_IP) - Web Frontend"
|
|
echo " - VMID $VMID_MIM_API: mim-api-1 ($MIM_API_IP) - API Service (ready for setup)"
|
|
echo ""
|
|
log_info "Next steps:"
|
|
echo " 1. Configure environment variables in containers"
|
|
echo " 2. Set up API service if needed"
|
|
echo " 3. Configure Cloudflare tunnels for external access"
|
|
echo " 4. Set up SSL certificates"
|
|
echo " 5. Configure monitoring and logging"
|
|
echo ""
|
|
log_info "Web service should be accessible at: http://<container-ip>"
|
|
echo ""
|
|
}
|
|
|
|
# Run main function
|
|
main "$@"
|
|
|