refactor: consolidate blockchain explorer into single app and update backup ignore patterns
- Remove standalone explorer-web app (README, HTML, package files) - Add /web endpoint to blockchain-explorer for web interface access - Update .gitignore to exclude application backup archives (*.tar.gz, *.zip) - Add backup documentation files to .gitignore (BACKUP_INDEX.md, README.md) - Consolidate explorer functionality into main blockchain-explorer application
This commit is contained in:
302
apps/marketplace/scripts/deploy-frontend.sh
Executable file
302
apps/marketplace/scripts/deploy-frontend.sh
Executable file
@@ -0,0 +1,302 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# AITBC Developer Ecosystem Frontend Deployment Script
|
||||
# Deploys the React frontend application to production
|
||||
#
|
||||
# Usage: ./deploy-frontend.sh [environment] [server]
|
||||
# Environment: development, staging, production
|
||||
# Server: aitbc-cascade (default), custom-server
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# 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}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
ENVIRONMENT="${1:-production}"
|
||||
SERVER="${2:-aitbc-cascade}"
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
APP_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
ROOT_DIR="$(dirname "$APP_DIR)"
|
||||
|
||||
echo "🚀 AITBC Frontend Deployment"
|
||||
echo "============================="
|
||||
echo "Environment: $ENVIRONMENT"
|
||||
echo "Server: $SERVER"
|
||||
echo "App Directory: $APP_DIR"
|
||||
echo ""
|
||||
|
||||
# Check prerequisites
|
||||
check_prerequisites() {
|
||||
print_status "Checking prerequisites..."
|
||||
|
||||
# Check if we're in the correct directory
|
||||
if [[ ! -f "$APP_DIR/package.json" ]]; then
|
||||
print_error "package.json not found in $APP_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if build exists
|
||||
if [[ ! -d "$APP_DIR/dist" ]]; then
|
||||
print_warning "Build directory not found. Building application..."
|
||||
build_application
|
||||
fi
|
||||
|
||||
# Check SSH connection to server
|
||||
if ! ssh -o ConnectTimeout=5 "$SERVER" "echo 'SSH connection successful'" 2>/dev/null; then
|
||||
print_error "Cannot connect to server $SERVER"
|
||||
print_error "Please ensure SSH keys are properly configured"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_success "Prerequisites check completed"
|
||||
}
|
||||
|
||||
# Build application
|
||||
build_application() {
|
||||
print_status "Building frontend application..."
|
||||
|
||||
cd "$APP_DIR"
|
||||
|
||||
# Set environment variables
|
||||
if [[ "$ENVIRONMENT" == "production" ]]; then
|
||||
export NODE_ENV=production
|
||||
elif [[ "$ENVIRONMENT" == "staging" ]]; then
|
||||
export NODE_ENV=staging
|
||||
else
|
||||
export NODE_ENV=development
|
||||
fi
|
||||
|
||||
# Build the application
|
||||
if npm run build; then
|
||||
print_success "Application built successfully"
|
||||
else
|
||||
print_error "Application build failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Deploy to server
|
||||
deploy_to_server() {
|
||||
print_status "Deploying frontend to $SERVER..."
|
||||
|
||||
# Create remote directory if it doesn't exist
|
||||
ssh "$SERVER" "mkdir -p /var/www/aitbc.bubuit.net/marketplace"
|
||||
|
||||
# Copy files to server
|
||||
print_status "Copying files to server..."
|
||||
|
||||
# Copy HTML files
|
||||
scp "$APP_DIR/dist/index.html" "$SERVER:/var/www/aitbc.bubuit.net/marketplace/"
|
||||
|
||||
# Copy JavaScript files
|
||||
scp "$APP_DIR/dist/assets/"*.js "$SERVER:/var/www/aitbc.bubuit.net/marketplace/assets/" 2>/dev/null || true
|
||||
|
||||
# Copy CSS files
|
||||
scp "$APP_DIR/dist/assets/"*.css "$SERVER:/var/www/aitbc.bubuit.net/marketplace/assets/" 2>/dev/null || true
|
||||
|
||||
# Copy other assets
|
||||
scp -r "$APP_DIR/dist/assets/"* "$SERVER:/var/www/aitbc.bubuit.net/marketplace/assets/" 2>/dev/null || true
|
||||
|
||||
print_success "Files copied to server"
|
||||
}
|
||||
|
||||
# Configure nginx
|
||||
configure_nginx() {
|
||||
print_status "Configuring nginx..."
|
||||
|
||||
# Create nginx configuration
|
||||
ssh "$SERVER" "cat > /etc/nginx/sites-available/marketplace.conf << 'EOF'
|
||||
server {
|
||||
listen 80;
|
||||
server_name aitbc.bubuit.net;
|
||||
|
||||
location /marketplace/ {
|
||||
alias /var/www/aitbc.bubuit.net/marketplace/;
|
||||
try_files \$uri \$uri/ /marketplace/index.html;
|
||||
|
||||
# Cache static assets
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control \"public, immutable\";
|
||||
}
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options \"SAMEORIGIN\" always;
|
||||
add_header X-Content-Type-Options \"nosniff\" always;
|
||||
add_header X-XSS-Protection \"1; mode=block\" always;
|
||||
add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;
|
||||
}
|
||||
|
||||
# Redirect root to marketplace
|
||||
location = / {
|
||||
return 301 /marketplace/;
|
||||
}
|
||||
}
|
||||
EOF"
|
||||
|
||||
# Enable site
|
||||
ssh "$SERVER" "ln -sf /etc/nginx/sites-available/marketplace.conf /etc/nginx/sites-enabled/"
|
||||
|
||||
# Test nginx configuration
|
||||
if ssh "$SERVER" "nginx -t"; then
|
||||
print_success "Nginx configuration is valid"
|
||||
else
|
||||
print_error "Nginx configuration is invalid"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Reload nginx
|
||||
ssh "$SERVER" "systemctl reload nginx"
|
||||
|
||||
print_success "Nginx configured and reloaded"
|
||||
}
|
||||
|
||||
# Set permissions
|
||||
set_permissions() {
|
||||
print_status "Setting file permissions..."
|
||||
|
||||
ssh "$SERVER" "chown -R www-data:www-data /var/www/aitbc.bubuit.net/marketplace"
|
||||
ssh "$SERVER" "chmod -R 755 /var/www/aitbc.bubuit.net/marketplace"
|
||||
|
||||
print_success "Permissions set"
|
||||
}
|
||||
|
||||
# Health check
|
||||
health_check() {
|
||||
print_status "Performing health check..."
|
||||
|
||||
# Wait a moment for nginx to reload
|
||||
sleep 5
|
||||
|
||||
# Check if the site is accessible
|
||||
if curl -s -o /dev/null -w "%{http_code}" "http://aitbc.bubuit.net/marketplace/" | grep -q "200"; then
|
||||
print_success "Site is accessible and responding correctly"
|
||||
else
|
||||
print_warning "Site may not be accessible. Please check manually."
|
||||
fi
|
||||
|
||||
# Check nginx status
|
||||
if ssh "$SERVER" "systemctl is-active nginx" | grep -q "active"; then
|
||||
print_success "Nginx is running"
|
||||
else
|
||||
print_error "Nginx is not running"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Generate deployment report
|
||||
generate_deployment_report() {
|
||||
print_status "Generating deployment report..."
|
||||
|
||||
local report_file="$ROOT_DIR/frontend-deployment-report-$(date +%Y%m%d-%H%M%S).json"
|
||||
|
||||
cat > "$report_file" << EOF
|
||||
{
|
||||
"deployment": {
|
||||
"environment": "$ENVIRONMENT",
|
||||
"server": "$SERVER",
|
||||
"timestamp": "$(date -Iseconds)",
|
||||
"app_directory": "$APP_DIR",
|
||||
"build_directory": "$APP_DIR/dist"
|
||||
},
|
||||
"configuration": {
|
||||
"nginx_config": "/etc/nginx/sites-available/marketplace.conf",
|
||||
"web_root": "/var/www/aitbc.bubuit.net/marketplace",
|
||||
"server_name": "aitbc.bubuit.net"
|
||||
},
|
||||
"urls": {
|
||||
"production": "http://aitbc.bubuit.net/marketplace/",
|
||||
"health_check": "http://aitbc.bubuit.net/marketplace/"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
print_success "Deployment report saved to $report_file"
|
||||
}
|
||||
|
||||
# Rollback function
|
||||
rollback() {
|
||||
print_warning "Rolling back deployment..."
|
||||
|
||||
# Restore previous version if exists
|
||||
if ssh "$SERVER" "test -d /var/www/aitbc.bubuit.net/marketplace.backup"; then
|
||||
ssh "$SERVER" "rm -rf /var/www/aitbc.bubuit.net/marketplace"
|
||||
ssh "$SERVER" "mv /var/www/aitbc.bubuit.net/marketplace.backup /var/www/aitbc.bubuit.net/marketplace"
|
||||
ssh "$SERVER" "systemctl reload nginx"
|
||||
print_success "Rollback completed"
|
||||
else
|
||||
print_error "No backup found for rollback"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
print_status "Starting frontend deployment..."
|
||||
|
||||
# Create backup of current deployment
|
||||
if ssh "$SERVER" "test -d /var/www/aitbc.bubuit.net/marketplace"; then
|
||||
print_status "Creating backup of current deployment..."
|
||||
ssh "$SERVER" "cp -r /var/www/aitbc.bubuit.net/marketplace /var/www/aitbc.bubuit.net/marketplace.backup"
|
||||
fi
|
||||
|
||||
# Check prerequisites
|
||||
check_prerequisites
|
||||
|
||||
# Deploy to server
|
||||
deploy_to_server
|
||||
|
||||
# Configure nginx
|
||||
configure_nginx
|
||||
|
||||
# Set permissions
|
||||
set_permissions
|
||||
|
||||
# Health check
|
||||
health_check
|
||||
|
||||
# Generate deployment report
|
||||
generate_deployment_report
|
||||
|
||||
print_success "🎉 Frontend deployment completed successfully!"
|
||||
echo ""
|
||||
echo "🌐 Application URL: http://aitbc.bubuit.net/marketplace/"
|
||||
echo "📊 Deployment report: $report_file"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Test the application in browser"
|
||||
echo "2. Verify all functionality works"
|
||||
echo "3. Monitor application logs"
|
||||
echo "4. Update DNS if needed"
|
||||
}
|
||||
|
||||
# Handle script interruption
|
||||
trap 'print_error "Deployment interrupted"; rollback; exit 1' INT TERM
|
||||
|
||||
# Handle rollback on error
|
||||
trap 'print_error "Deployment failed, initiating rollback..."; rollback; exit 1' ERR
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
248
apps/marketplace/scripts/deploy_edge_node.py
Executable file
248
apps/marketplace/scripts/deploy_edge_node.py
Executable file
@@ -0,0 +1,248 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Edge Node Deployment Script for AITBC Marketplace
|
||||
Deploys edge node configuration and services
|
||||
"""
|
||||
|
||||
import yaml
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
def load_config(config_file):
|
||||
"""Load edge node configuration from YAML file"""
|
||||
with open(config_file, 'r') as f:
|
||||
return yaml.safe_load(f)
|
||||
|
||||
def deploy_redis_cache(config):
|
||||
"""Deploy Redis cache layer"""
|
||||
print(f"🔧 Deploying Redis cache for {config['edge_node_config']['node_id']}")
|
||||
|
||||
# Check if Redis is running
|
||||
try:
|
||||
result = subprocess.run(['redis-cli', 'ping'], capture_output=True, text=True)
|
||||
if result.stdout.strip() == 'PONG':
|
||||
print("✅ Redis is already running")
|
||||
else:
|
||||
print("⚠️ Redis not responding, attempting to start...")
|
||||
# Start Redis if not running
|
||||
subprocess.run(['sudo', 'systemctl', 'start', 'redis-server'], check=True)
|
||||
print("✅ Redis started")
|
||||
except FileNotFoundError:
|
||||
print("❌ Redis not installed, installing...")
|
||||
subprocess.run(['sudo', 'apt-get', 'update'], check=True)
|
||||
subprocess.run(['sudo', 'apt-get', 'install', '-y', 'redis-server'], check=True)
|
||||
subprocess.run(['sudo', 'systemctl', 'start', 'redis-server'], check=True)
|
||||
print("✅ Redis installed and started")
|
||||
|
||||
# Configure Redis
|
||||
redis_config = config['edge_node_config']['caching']
|
||||
|
||||
# Set Redis configuration
|
||||
redis_commands = [
|
||||
f"CONFIG SET maxmemory {redis_config['max_memory_mb']}mb",
|
||||
f"CONFIG SET maxmemory-policy allkeys-lru",
|
||||
f"CONFIG SET timeout {redis_config['cache_ttl_seconds']}"
|
||||
]
|
||||
|
||||
for cmd in redis_commands:
|
||||
try:
|
||||
subprocess.run(['redis-cli', *cmd.split()], check=True, capture_output=True)
|
||||
except subprocess.CalledProcessError:
|
||||
print(f"⚠️ Could not set Redis config: {cmd}")
|
||||
|
||||
def deploy_monitoring(config):
|
||||
"""Deploy monitoring agent"""
|
||||
print(f"📊 Deploying monitoring for {config['edge_node_config']['node_id']}")
|
||||
|
||||
monitoring_config = config['edge_node_config']['monitoring']
|
||||
|
||||
# Create monitoring directory
|
||||
os.makedirs('/tmp/aitbc-monitoring', exist_ok=True)
|
||||
|
||||
# Create monitoring script
|
||||
monitoring_script = f"""#!/bin/bash
|
||||
# Monitoring script for {config['edge_node_config']['node_id']}
|
||||
echo "{{{{'timestamp': '$(date -Iseconds)', 'node_id': '{config['edge_node_config']['node_id']}', 'status': 'monitoring'}}}}" > /tmp/aitbc-monitoring/status.json
|
||||
|
||||
# Check marketplace API health
|
||||
curl -s http://localhost:{config['edge_node_config']['services'][0]['port']}/health/live > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "marketplace_healthy=true" >> /tmp/aitbc-monitoring/status.json
|
||||
else
|
||||
echo "marketplace_healthy=false" >> /tmp/aitbc-monitoring/status.json
|
||||
fi
|
||||
|
||||
# Check Redis health
|
||||
redis-cli ping > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "redis_healthy=true" >> /tmp/aitbc-monitoring/status.json
|
||||
else
|
||||
echo "redis_healthy=false" >> /tmp/aitbc-monitoring/status.json
|
||||
fi
|
||||
"""
|
||||
|
||||
with open('/tmp/aitbc-monitoring/monitor.sh', 'w') as f:
|
||||
f.write(monitoring_script)
|
||||
|
||||
os.chmod('/tmp/aitbc-monitoring/monitor.sh', 0o755)
|
||||
|
||||
# Create systemd service for monitoring
|
||||
monitoring_service = f"""[Unit]
|
||||
Description=AITBC Edge Node Monitoring - {config['edge_node_config']['node_id']}
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
ExecStart=/tmp/aitbc-monitoring/monitor.sh
|
||||
Restart=always
|
||||
RestartSec=30
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
"""
|
||||
|
||||
service_file = f"/etc/systemd/system/aitbc-edge-monitoring-{config['edge_node_config']['node_id']}.service"
|
||||
|
||||
with open(service_file, 'w') as f:
|
||||
f.write(monitoring_service)
|
||||
|
||||
# Enable and start monitoring service
|
||||
subprocess.run(['sudo', 'systemctl', 'daemon-reload'], check=True)
|
||||
subprocess.run(['sudo', 'systemctl', 'enable', f'aitbc-edge-monitoring-{config["edge_node_config"]["node_id"]}.service'], check=True)
|
||||
subprocess.run(['sudo', 'systemctl', 'start', f'aitbc-edge-monitoring-{config["edge_node_config"]["node_id"]}.service'], check=True)
|
||||
|
||||
print("✅ Monitoring agent deployed")
|
||||
|
||||
def optimize_network(config):
|
||||
"""Apply network optimizations"""
|
||||
print(f"🌐 Optimizing network for {config['edge_node_config']['node_id']}")
|
||||
|
||||
network_config = config['edge_node_config']['network']
|
||||
|
||||
# TCP optimizations
|
||||
tcp_params = {
|
||||
'net.core.rmem_max': '16777216',
|
||||
'net.core.wmem_max': '16777216',
|
||||
'net.ipv4.tcp_rmem': '4096 87380 16777216',
|
||||
'net.ipv4.tcp_wmem': '4096 65536 16777216',
|
||||
'net.ipv4.tcp_congestion_control': 'bbr',
|
||||
'net.core.netdev_max_backlog': '5000'
|
||||
}
|
||||
|
||||
for param, value in tcp_params.items():
|
||||
try:
|
||||
subprocess.run(['sudo', 'sysctl', '-w', f'{param}={value}'], check=True, capture_output=True)
|
||||
print(f"✅ Set {param}={value}")
|
||||
except subprocess.CalledProcessError:
|
||||
print(f"⚠️ Could not set {param}")
|
||||
|
||||
def deploy_edge_services(config):
|
||||
"""Deploy edge node services"""
|
||||
print(f"🚀 Deploying edge services for {config['edge_node_config']['node_id']}")
|
||||
|
||||
# Create edge service configuration
|
||||
edge_service_config = {
|
||||
'node_id': config['edge_node_config']['node_id'],
|
||||
'region': config['edge_node_config']['region'],
|
||||
'services': config['edge_node_config']['services'],
|
||||
'performance_targets': config['edge_node_config']['performance_targets'],
|
||||
'deployed_at': datetime.now().isoformat()
|
||||
}
|
||||
|
||||
# Save configuration
|
||||
with open(f'/tmp/aitbc-edge-{config["edge_node_config"]["node_id"]}-config.json', 'w') as f:
|
||||
json.dump(edge_service_config, f, indent=2)
|
||||
|
||||
print(f"✅ Edge services configuration saved")
|
||||
|
||||
def validate_deployment(config):
|
||||
"""Validate edge node deployment"""
|
||||
print(f"✅ Validating deployment for {config['edge_node_config']['node_id']}")
|
||||
|
||||
validation_results = {}
|
||||
|
||||
# Check marketplace API
|
||||
try:
|
||||
response = subprocess.run(['curl', '-s', f'http://localhost:{config["edge_node_config"]["services"][0]["port"]}/health/live'],
|
||||
capture_output=True, text=True, timeout=10)
|
||||
if response.status_code == 0:
|
||||
validation_results['marketplace_api'] = 'healthy'
|
||||
else:
|
||||
validation_results['marketplace_api'] = 'unhealthy'
|
||||
except Exception as e:
|
||||
validation_results['marketplace_api'] = f'error: {str(e)}'
|
||||
|
||||
# Check Redis
|
||||
try:
|
||||
result = subprocess.run(['redis-cli', 'ping'], capture_output=True, text=True, timeout=5)
|
||||
if result.stdout.strip() == 'PONG':
|
||||
validation_results['redis'] = 'healthy'
|
||||
else:
|
||||
validation_results['redis'] = 'unhealthy'
|
||||
except Exception as e:
|
||||
validation_results['redis'] = f'error: {str(e)}'
|
||||
|
||||
# Check monitoring
|
||||
try:
|
||||
result = subprocess.run(['systemctl', 'is-active', f'aitbc-edge-monitoring-{config["edge_node_config"]["node_id"]}.service'],
|
||||
capture_output=True, text=True, timeout=5)
|
||||
validation_results['monitoring'] = result.stdout.strip()
|
||||
except Exception as e:
|
||||
validation_results['monitoring'] = f'error: {str(e)}'
|
||||
|
||||
print(f"📊 Validation Results:")
|
||||
for service, status in validation_results.items():
|
||||
print(f" {service}: {status}")
|
||||
|
||||
return validation_results
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 2:
|
||||
print("Usage: python deploy_edge_node.py <config_file>")
|
||||
sys.exit(1)
|
||||
|
||||
config_file = sys.argv[1]
|
||||
|
||||
if not os.path.exists(config_file):
|
||||
print(f"❌ Configuration file {config_file} not found")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
config = load_config(config_file)
|
||||
|
||||
print(f"🚀 Deploying edge node: {config['edge_node_config']['node_id']}")
|
||||
print(f"📍 Region: {config['edge_node_config']['region']}")
|
||||
print(f"🌍 Location: {config['edge_node_config']['location']}")
|
||||
|
||||
# Deploy components
|
||||
deploy_redis_cache(config)
|
||||
deploy_monitoring(config)
|
||||
optimize_network(config)
|
||||
deploy_edge_services(config)
|
||||
|
||||
# Validate deployment
|
||||
validation_results = validate_deployment(config)
|
||||
|
||||
# Save deployment status
|
||||
deployment_status = {
|
||||
'node_id': config['edge_node_config']['node_id'],
|
||||
'deployment_time': datetime.now().isoformat(),
|
||||
'validation_results': validation_results,
|
||||
'status': 'completed'
|
||||
}
|
||||
|
||||
with open(f'/tmp/aitbc-edge-{config["edge_node_config"]["node_id"]}-deployment.json', 'w') as f:
|
||||
json.dump(deployment_status, f, indent=2)
|
||||
|
||||
print(f"✅ Edge node deployment completed for {config['edge_node_config']['node_id']}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Deployment failed: {str(e)}")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user