251 lines
7.2 KiB
Bash
Executable File
251 lines
7.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# SolarBank IoT Dashboard - Production Deployment Script
|
|
# This script handles the complete deployment process
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Function to print colored output
|
|
print_status() {
|
|
echo -e "${GREEN}[INFO]${NC} $1"
|
|
}
|
|
|
|
print_warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
print_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
# Function to check if Docker and Docker Compose are installed
|
|
check_requirements() {
|
|
print_status "Checking requirements..."
|
|
|
|
if ! command -v docker &> /dev/null; then
|
|
print_error "Docker is not installed. Please install Docker first."
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v docker-compose &> /dev/null; then
|
|
print_error "Docker Compose is not installed. Please install Docker Compose first."
|
|
exit 1
|
|
fi
|
|
|
|
print_status "Requirements check passed."
|
|
}
|
|
|
|
# Function to check environment configuration
|
|
check_environment() {
|
|
print_status "Checking environment configuration..."
|
|
|
|
if [ ! -f .env.prod ]; then
|
|
print_error ".env.prod file not found. Please create it from environment.prod.example"
|
|
print_status "Run: cp environment.prod.example .env.prod"
|
|
print_status "Then edit .env.prod with your production values"
|
|
exit 1
|
|
fi
|
|
|
|
# Load environment variables
|
|
export $(cat .env.prod | grep -v '#' | awk '/=/ {print $1}')
|
|
|
|
# Check critical variables
|
|
if [ -z "$DOMAIN_NAME" ] || [ "$DOMAIN_NAME" == "yourdomain.com" ]; then
|
|
print_error "DOMAIN_NAME must be set to your actual domain in .env.prod"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$EMAIL" ] || [ "$EMAIL" == "your-email@domain.com" ]; then
|
|
print_error "EMAIL must be set to your actual email in .env.prod"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$SECRET_KEY" == "REPLACE_WITH_SECURE_RANDOM_STRING_32_CHARS" ]; then
|
|
print_error "SECRET_KEY must be replaced with a secure random string in .env.prod"
|
|
print_status "Generate one with: python -c \"import secrets; print(secrets.token_urlsafe(32))\""
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$JWT_SECRET_KEY" == "REPLACE_WITH_SECURE_RANDOM_STRING_32_CHARS" ]; then
|
|
print_error "JWT_SECRET_KEY must be replaced with a secure random string in .env.prod"
|
|
exit 1
|
|
fi
|
|
|
|
print_status "Environment configuration check passed."
|
|
}
|
|
|
|
# Function to setup SSL certificates
|
|
setup_ssl() {
|
|
print_status "Setting up SSL certificates..."
|
|
|
|
if [ ! -f scripts/init-letsencrypt.sh ]; then
|
|
print_error "SSL setup script not found!"
|
|
exit 1
|
|
fi
|
|
|
|
chmod +x scripts/init-letsencrypt.sh
|
|
./scripts/init-letsencrypt.sh
|
|
|
|
print_status "SSL certificates setup completed."
|
|
}
|
|
|
|
# Function to build and start services
|
|
deploy_services() {
|
|
print_status "Building and deploying services..."
|
|
|
|
# Pull latest images
|
|
docker-compose -f docker-compose.prod.yml pull
|
|
|
|
# Build services
|
|
docker-compose -f docker-compose.prod.yml build --no-cache
|
|
|
|
# Start services
|
|
docker-compose -f docker-compose.prod.yml up -d
|
|
|
|
print_status "Services deployed successfully."
|
|
}
|
|
|
|
# Function to run database migrations
|
|
run_migrations() {
|
|
print_status "Running database migrations..."
|
|
|
|
# Wait for database to be ready
|
|
sleep 10
|
|
|
|
# Run migrations
|
|
docker-compose -f docker-compose.prod.yml exec backend alembic upgrade head
|
|
|
|
print_status "Database migrations completed."
|
|
}
|
|
|
|
# Function to setup monitoring
|
|
setup_monitoring() {
|
|
print_status "Setting up monitoring and health checks..."
|
|
|
|
# Wait for services to be fully ready
|
|
sleep 30
|
|
|
|
# Check service health
|
|
print_status "Checking service health..."
|
|
|
|
# Check backend health
|
|
if curl -f http://localhost/api/health > /dev/null 2>&1; then
|
|
print_status "Backend health check: PASSED"
|
|
else
|
|
print_warning "Backend health check: FAILED (this might be normal if SSL is required)"
|
|
fi
|
|
|
|
# Check frontend health
|
|
if curl -f http://localhost/health > /dev/null 2>&1; then
|
|
print_status "Frontend health check: PASSED"
|
|
else
|
|
print_warning "Frontend health check: FAILED"
|
|
fi
|
|
|
|
print_status "Health checks completed."
|
|
}
|
|
|
|
# Function to setup backup cron job
|
|
setup_backup() {
|
|
print_status "Setting up automated backups..."
|
|
|
|
chmod +x scripts/backup-database.sh
|
|
|
|
# Add cron job for daily backups at 2 AM
|
|
(crontab -l 2>/dev/null; echo "0 2 * * * $(pwd)/scripts/backup-database.sh >> $(pwd)/logs/backup.log 2>&1") | crontab -
|
|
|
|
print_status "Automated backup setup completed."
|
|
}
|
|
|
|
# Function to display final status
|
|
show_status() {
|
|
print_status "==================================="
|
|
print_status "DEPLOYMENT COMPLETED SUCCESSFULLY!"
|
|
print_status "==================================="
|
|
echo
|
|
print_status "Your SolarBank IoT Dashboard is now running at:"
|
|
print_status "🌐 https://$DOMAIN_NAME"
|
|
echo
|
|
print_status "Services status:"
|
|
docker-compose -f docker-compose.prod.yml ps
|
|
echo
|
|
print_status "To monitor logs: docker-compose -f docker-compose.prod.yml logs -f"
|
|
print_status "To stop services: docker-compose -f docker-compose.prod.yml down"
|
|
print_status "To update deployment: ./scripts/deploy.sh --update"
|
|
echo
|
|
print_status "Important next steps:"
|
|
print_status "1. Test your application thoroughly"
|
|
print_status "2. Set up monitoring and alerting"
|
|
print_status "3. Configure firewall rules"
|
|
print_status "4. Set up regular backups verification"
|
|
}
|
|
|
|
# Function to update existing deployment
|
|
update_deployment() {
|
|
print_status "Updating existing deployment..."
|
|
|
|
# Create backup before update
|
|
print_status "Creating backup before update..."
|
|
./scripts/backup-database.sh
|
|
|
|
# Pull latest changes and rebuild
|
|
docker-compose -f docker-compose.prod.yml down
|
|
docker-compose -f docker-compose.prod.yml pull
|
|
docker-compose -f docker-compose.prod.yml build --no-cache
|
|
docker-compose -f docker-compose.prod.yml up -d
|
|
|
|
# Run migrations
|
|
run_migrations
|
|
|
|
print_status "Deployment update completed."
|
|
}
|
|
|
|
# Main deployment function
|
|
main() {
|
|
print_status "Starting SolarBank IoT Dashboard production deployment..."
|
|
|
|
case "$1" in
|
|
--update)
|
|
check_requirements
|
|
check_environment
|
|
update_deployment
|
|
setup_monitoring
|
|
show_status
|
|
;;
|
|
--ssl-only)
|
|
check_requirements
|
|
check_environment
|
|
setup_ssl
|
|
;;
|
|
*)
|
|
check_requirements
|
|
check_environment
|
|
|
|
# Check if this is a fresh installation
|
|
if [ ! -d "./nginx/certbot/conf/live" ]; then
|
|
setup_ssl
|
|
else
|
|
print_status "SSL certificates already exist. Skipping SSL setup."
|
|
print_status "Use --ssl-only flag to regenerate certificates."
|
|
fi
|
|
|
|
deploy_services
|
|
run_migrations
|
|
setup_monitoring
|
|
setup_backup
|
|
show_status
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Create logs directory
|
|
mkdir -p logs
|
|
|
|
# Run main function with all arguments
|
|
main "$@" |