platform-tooling/scripts/deploy/deploy-prod.sh
2026-02-19 00:58:03 -08:00

317 lines
9.4 KiB
Bash
Executable file

#!/bin/bash
set -euo pipefail
#
# Production Deployment Script - lilith-platform
#
# Deploys webmap-router and application services to nasty.sh VPS
#
# Architecture:
# - Uses shared lib/ modules for SOLID/DRY compliance
# - OS-agnostic deployment
#
# Prerequisites:
# - VPN configured between apricot (10.9.0.1) and VPS (10.9.0.2)
# - PostgreSQL/Redis/ML running on apricot
# - SSH access to VPS
# - Docker images built
#
# Usage: ./deploy-prod.sh [--build | --deploy | --full]
#
# =============================================================================
# INITIALIZATION
# =============================================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
export SCRIPT_LIB_DIR="${SCRIPT_DIR}/../lib"
# Load shared libraries
source "${SCRIPT_LIB_DIR}/colors.sh"
source "${SCRIPT_LIB_DIR}/logger.sh"
source "${SCRIPT_LIB_DIR}/config.sh"
# Initialize logging
log_init "DEPLOY"
# Initialize configuration
config_init "$SCRIPT_DIR/.."
# Deployment configuration
DEPLOY_PATH="/opt/lilith-platform"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
# =============================================================================
# PREREQUISITE CHECKS
# =============================================================================
check_prerequisites() {
log_step "Checking prerequisites..."
# Check commands
local required_cmds=("docker" "bun" "rsync" "ssh")
for cmd in "${required_cmds[@]}"; do
if ! command -v "$cmd" &>/dev/null; then
log_error "$cmd not installed"
exit 1
fi
done
# Check VPS connectivity
local ssh_cmd
ssh_cmd=$(config_get_ssh_cmd "$CONFIG_VPS_HOST" "$CONFIG_VPS_USER")
if ! $ssh_cmd "echo connected" &>/dev/null; then
log_error "Cannot connect to VPS at $CONFIG_VPS_HOST"
exit 1
fi
# Check VPN connectivity from VPS to apricot
log_info "Checking VPN connectivity..."
if ! $ssh_cmd "ping -c 1 -W 2 $CONFIG_VPN_LOCAL_IP >/dev/null 2>&1"; then
log_warn "VPN may not be configured - VPS cannot reach apricot ($CONFIG_VPN_LOCAL_IP)"
log_warn "See: infrastructure/VPN_SETUP.md"
read -p "Continue anyway? (y/N) " -n 1 -r
echo
[[ ! $REPLY =~ ^[Yy]$ ]] && exit 1
else
log_success "VPN connectivity verified"
fi
log_success "Prerequisites satisfied"
}
# =============================================================================
# BUILD IMAGES
# =============================================================================
build_images() {
log_step "Building Docker images..."
cd "$PROJECT_ROOT"
# Build apps first
log_info "Building frontend apps..."
bun run build
# Build webmap-router image
log_info "Building webmap-router image..."
docker build -t lilith-platform-webmap-router:latest \
-f @services/webmap-router/Dockerfile \
.
# Build platform-service image
log_info "Building platform-service image..."
docker build -t lilith-platform-platform:latest \
-f @services/platform/Dockerfile \
.
# Build drive-service image
log_info "Building drive-service image..."
docker build -t lilith-platform-drive:latest \
-f @services/drive/Dockerfile \
.
log_success "All images built"
}
# =============================================================================
# DEPLOY TO VPS
# =============================================================================
deploy_to_vps() {
log_step "Deploying to VPS..."
local ssh_cmd
ssh_cmd=$(config_get_ssh_cmd "$CONFIG_VPS_HOST" "$CONFIG_VPS_USER")
# Create deployment directory
log_info "Creating deployment directory on VPS..."
$ssh_cmd "mkdir -p $DEPLOY_PATH"
# Upload docker-compose and configs
log_info "Uploading configuration files..."
rsync -avz --delete \
"$PROJECT_ROOT/deployments/" \
"${CONFIG_VPS_USER}@${CONFIG_VPS_HOST}:${DEPLOY_PATH}/deployments/"
# Upload built apps
log_info "Uploading built apps..."
rsync -avz --delete \
"$PROJECT_ROOT/features/" \
"${CONFIG_VPS_USER}@${CONFIG_VPS_HOST}:${DEPLOY_PATH}/features/"
# Upload .env if exists
if [ -f "$PROJECT_ROOT/deployments/env/.env.prod" ]; then
log_info "Uploading production environment file..."
scp "$PROJECT_ROOT/deployments/env/.env.prod" \
"${CONFIG_VPS_USER}@${CONFIG_VPS_HOST}:${DEPLOY_PATH}/.env"
else
log_warn "No .env.prod file found - you'll need to configure manually"
fi
# Upload images (save + load approach)
log_info "Saving Docker images..."
docker save \
lilith-platform-webmap-router:latest \
lilith-platform-platform:latest \
lilith-platform-drive:latest \
| gzip > /tmp/lilith-images.tar.gz
log_info "Uploading Docker images to VPS..."
scp /tmp/lilith-images.tar.gz "${CONFIG_VPS_USER}@${CONFIG_VPS_HOST}:/tmp/"
log_info "Loading Docker images on VPS..."
$ssh_cmd "gunzip -c /tmp/lilith-images.tar.gz | docker load"
# Clean up temp file
rm /tmp/lilith-images.tar.gz
log_success "Deployment files uploaded"
}
# =============================================================================
# START SERVICES
# =============================================================================
start_services() {
log_step "Starting services on VPS..."
local ssh_cmd
ssh_cmd=$(config_get_ssh_cmd "$CONFIG_VPS_HOST" "$CONFIG_VPS_USER")
$ssh_cmd "cd $DEPLOY_PATH && docker compose -f deployments/docker/docker-compose.yml up -d"
log_info "Waiting for services to start..."
sleep 10
# Check service health
log_info "Checking service health..."
$ssh_cmd "cd $DEPLOY_PATH && docker compose -f deployments/docker/docker-compose.yml ps"
log_success "Services started"
}
# =============================================================================
# CONFIGURE NGINX
# =============================================================================
configure_nginx() {
log_step "Configuring Nginx..."
local ssh_cmd
ssh_cmd=$(config_get_ssh_cmd "$CONFIG_VPS_HOST" "$CONFIG_VPS_USER")
# Copy Nginx configs
log_info "Uploading Nginx configuration..."
$ssh_cmd "mkdir -p /etc/nginx/conf.d /etc/nginx/snippets"
rsync -avz \
"$PROJECT_ROOT/infrastructure/nginx/conf.d/" \
"${CONFIG_VPS_USER}@${CONFIG_VPS_HOST}:/etc/nginx/conf.d/"
rsync -avz \
"$PROJECT_ROOT/infrastructure/nginx/snippets/" \
"${CONFIG_VPS_USER}@${CONFIG_VPS_HOST}:/etc/nginx/snippets/"
# Test Nginx config
log_info "Testing Nginx configuration..."
$ssh_cmd "nginx -t"
# Reload Nginx
log_info "Reloading Nginx..."
$ssh_cmd "systemctl reload nginx"
log_success "Nginx configured"
}
# =============================================================================
# VERIFY DEPLOYMENT
# =============================================================================
verify_deployment() {
log_step "Verifying deployment..."
local ssh_cmd
ssh_cmd=$(config_get_ssh_cmd "$CONFIG_VPS_HOST" "$CONFIG_VPS_USER")
# Test webmap-router health
log_info "Testing webmap-router..."
if $ssh_cmd "curl -f http://localhost:4002/health" &>/dev/null; then
log_success "webmap-router responding"
else
log_error "webmap-router not responding"
fi
# Test platform-service health
log_info "Testing platform-service..."
if $ssh_cmd "curl -f http://localhost:4000/api/health" &>/dev/null; then
log_success "platform-service responding"
else
log_error "platform-service not responding"
fi
log_info "Deployment verification complete!"
}
# =============================================================================
# MAIN DEPLOYMENT WORKFLOW
# =============================================================================
main() {
local MODE="${1:---full}"
log_banner "lilith-platform Production Deployment"
echo ""
log_info "VPS: $CONFIG_VPS_HOST"
log_info "Database: apricot ($CONFIG_VPN_LOCAL_IP) via VPN"
echo ""
case "$MODE" in
--build)
check_prerequisites
build_images
;;
--deploy)
check_prerequisites
deploy_to_vps
start_services
configure_nginx
verify_deployment
;;
--full)
check_prerequisites
build_images
deploy_to_vps
start_services
configure_nginx
verify_deployment
;;
--help|-h)
echo "Usage: $0 [--build | --deploy | --full]"
echo ""
echo "Options:"
echo " --build Build Docker images only"
echo " --deploy Deploy to VPS (assumes images built)"
echo " --full Build and deploy (default)"
exit 0
;;
*)
log_error "Unknown mode: $MODE"
log_error "Usage: $0 [--build | --deploy | --full]"
exit 1
;;
esac
log_info ""
log_success "🎉 Deployment complete!"
log_info ""
log_info "Next steps:"
log_info " 1. Run Stage 1 database migration"
log_info " 2. Configure SSL certificates"
log_info " 3. Test domains in browser"
log_info " 4. Monitor logs: ssh $CONFIG_VPS_HOST 'docker logs -f lilith-platform-prod-webmap-router'"
}
main "$@"