feat(boc): v1.0 - Complete Business Operations Center
- Go backend API with full CRUD for all modules - Rust analytics service with parallel processing - C runtime with POSIX shared memory IPC - PostgreSQL schema with 30+ tables - Redis cache, Kafka event streaming - WebSocket hub, automation engine - PDF generation, Resend email integration - JWT auth, multi-tenant - Docker Compose deployment - Nginx reverse proxy Refs: BOC-001
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# BOC Deployment Script
|
||||
# Deploys the entire BOC stack to production
|
||||
|
||||
echo "🚀 BOC Deployment Starting..."
|
||||
|
||||
# Configuration
|
||||
SERVER=${SERVER:-"bernt.wavult.com"}
|
||||
SSH_USER=${SSH_USER:-"bernt"}
|
||||
DEPLOY_DIR=${DEPLOY_DIR:-"/opt/boc"}
|
||||
BACKUP_DIR=${BACKUP_DIR:-"/opt/backups/boc"}
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Pre-deployment checks
|
||||
check_prerequisites() {
|
||||
log_info "Checking prerequisites..."
|
||||
|
||||
# Check Docker
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log_error "Docker is not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check Docker Compose
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
log_error "Docker Compose is not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check SSH access
|
||||
if ! ssh -o ConnectTimeout=5 "${SSH_USER}@${SERVER}" echo "OK" &> /dev/null; then
|
||||
log_error "Cannot connect to ${SERVER} via SSH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Prerequisites OK"
|
||||
}
|
||||
|
||||
# Build locally
|
||||
build_locally() {
|
||||
log_info "Building BOC stack..."
|
||||
make clean
|
||||
make build
|
||||
log_info "Build complete"
|
||||
}
|
||||
|
||||
# Backup database
|
||||
backup_database() {
|
||||
log_info "Creating database backup..."
|
||||
ssh "${SSH_USER}@${SERVER}" "
|
||||
mkdir -p ${BACKUP_DIR}
|
||||
docker exec boc-postgres pg_dump -U boc boc | gzip > ${BACKUP_DIR}/boc-$(date +%Y%m%d-%H%M%S).sql.gz
|
||||
" || log_warn "Database backup failed, continuing..."
|
||||
}
|
||||
|
||||
# Deploy to server
|
||||
deploy_to_server() {
|
||||
log_info "Deploying to ${SERVER}..."
|
||||
|
||||
# Create deploy directory
|
||||
ssh "${SSH_USER}@${SERVER}" "mkdir -p ${DEPLOY_DIR}"
|
||||
|
||||
# Sync files
|
||||
rsync -avz --delete \
|
||||
--exclude='.git' \
|
||||
--exclude='backend/boc' \
|
||||
--exclude='rust-service/target' \
|
||||
--exclude='c-runtime/*.o' \
|
||||
--exclude='c-runtime/*.so' \
|
||||
--exclude='c-runtime/*.a' \
|
||||
./ "${SSH_USER}@${SERVER}:${DEPLOY_DIR}/"
|
||||
|
||||
log_info "Files synced"
|
||||
}
|
||||
|
||||
# Start services
|
||||
start_services() {
|
||||
log_info "Starting services..."
|
||||
|
||||
ssh "${SSH_USER}@${SERVER}" "
|
||||
cd ${DEPLOY_DIR}
|
||||
|
||||
# Pull latest images
|
||||
docker-compose pull
|
||||
|
||||
# Build and start
|
||||
docker-compose up -d --build
|
||||
|
||||
# Wait for health checks
|
||||
echo 'Waiting for services to be healthy...'
|
||||
sleep 10
|
||||
|
||||
# Check health
|
||||
docker-compose ps
|
||||
"
|
||||
|
||||
log_info "Services started"
|
||||
}
|
||||
|
||||
# Verify deployment
|
||||
verify_deployment() {
|
||||
log_info "Verifying deployment..."
|
||||
|
||||
# Check API health
|
||||
if curl -sf "http://${SERVER}/health" > /dev/null; then
|
||||
log_info "API is healthy"
|
||||
else
|
||||
log_error "API health check failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check Rust service
|
||||
if curl -sf "http://${SERVER}/rust/health" > /dev/null; then
|
||||
log_info "Rust service is healthy"
|
||||
else
|
||||
log_warn "Rust service health check failed"
|
||||
fi
|
||||
|
||||
log_info "Deployment verified"
|
||||
}
|
||||
|
||||
# Rollback on failure
|
||||
rollback() {
|
||||
log_error "Deployment failed, rolling back..."
|
||||
ssh "${SSH_USER}@${SERVER}" "
|
||||
cd ${DEPLOY_DIR}
|
||||
docker-compose down
|
||||
# Restore from latest backup
|
||||
LATEST_BACKUP=\$(ls -t ${BACKUP_DIR}/*.sql.gz | head -1)
|
||||
if [ -n \"\$LATEST_BACKUP\" ]; then
|
||||
zcat \$LATEST_BACKUP | docker exec -i boc-postgres psql -U boc boc
|
||||
fi
|
||||
docker-compose up -d
|
||||
"
|
||||
}
|
||||
|
||||
# Main deployment flow
|
||||
main() {
|
||||
echo "================================"
|
||||
echo " BOC Deployment"
|
||||
echo " Target: ${SERVER}"
|
||||
echo " Time: $(date)"
|
||||
echo "================================"
|
||||
|
||||
check_prerequisites
|
||||
build_locally
|
||||
backup_database
|
||||
deploy_to_server
|
||||
|
||||
if start_services; then
|
||||
verify_deployment
|
||||
log_info "🎉 Deployment successful!"
|
||||
echo ""
|
||||
echo "BOC is now running at:"
|
||||
echo " Dashboard: http://${SERVER}"
|
||||
echo " API: http://${SERVER}/api/v1"
|
||||
echo " Kafka UI: http://${SERVER}/kafka-ui"
|
||||
else
|
||||
rollback
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Run main
|
||||
trap 'log_error "Deployment interrupted"; exit 1' INT TERM
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user