From 0c00382a989a33d3ce76aae5526a8245b1416f5c Mon Sep 17 00:00:00 2001 From: hailin Date: Sun, 7 Dec 2025 07:00:58 -0800 Subject: [PATCH] fix: convert deploy.sh CRLF to LF and add executable permission MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Convert Windows CRLF line endings to Unix LF for all deploy.sh files - Add executable permission to all deploy.sh scripts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- backend/api-gateway/deploy.sh | 756 +++---- backend/mpc-system/scripts/deploy.sh | 1748 ++++++++--------- backend/services/admin-service/deploy.sh | 732 +++---- .../services/authorization-service/deploy.sh | 188 +- .../identity-service/package-lock.json | 40 +- .../services/leaderboard-service/deploy.sh | 188 +- backend/services/planting-service/deploy.sh | 188 +- backend/services/presence-service/deploy.sh | 506 ++--- backend/services/referral-service/deploy.sh | 188 +- backend/services/reporting-service/deploy.sh | 188 +- backend/services/reward-service/deploy.sh | 188 +- backend/services/wallet-service/deploy.sh | 188 +- frontend/admin-web/deploy.sh | 432 ++-- frontend/mobile-upgrade/deploy.sh | 432 ++-- 14 files changed, 2972 insertions(+), 2990 deletions(-) diff --git a/backend/api-gateway/deploy.sh b/backend/api-gateway/deploy.sh index 784e9528..fe2bc9f5 100755 --- a/backend/api-gateway/deploy.sh +++ b/backend/api-gateway/deploy.sh @@ -1,378 +1,378 @@ -#!/bin/bash - -# ============================================================================= -# RWADurian API Gateway (Kong) - 部署脚本 -# ============================================================================= -# Usage: -# ./deploy.sh up # 启动网关 -# ./deploy.sh down # 停止网关 -# ./deploy.sh restart # 重启网关 -# ./deploy.sh logs # 查看日志 -# ./deploy.sh status # 查看状态 -# ./deploy.sh health # 健康检查 -# ./deploy.sh reload # 重载 Kong 配置 -# ./deploy.sh routes # 查看所有路由 -# ./deploy.sh monitoring # 启动监控栈 (Prometheus + Grafana) -# ./deploy.sh metrics # 查看 Prometheus 指标 -# ============================================================================= - -set -e - -# 颜色定义 -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}[SUCCESS]${NC} $1"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } -log_error() { echo -e "${RED}[ERROR]${NC} $1"; } - -# 项目信息 -PROJECT_NAME="rwa-api-gateway" -KONG_ADMIN_URL="http://localhost:8001" -KONG_PROXY_URL="http://localhost:8000" - -# 脚本目录 -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -# 切换到脚本所在目录 -cd "$SCRIPT_DIR" - -# 加载环境变量 -if [ -f ".env" ]; then - log_info "Loading environment from .env file" - set -a - source .env - set +a -elif [ -f ".env.example" ]; then - log_warn ".env file not found!" - log_warn "Creating .env from .env.example..." - cp .env.example .env - log_error "Please edit .env file to configure your environment, then run again" - exit 1 -else - log_error "Neither .env nor .env.example found!" - exit 1 -fi - -# 检查 Docker -check_docker() { - if ! command -v docker &> /dev/null; then - log_error "Docker 未安装" - exit 1 - fi - if ! docker info &> /dev/null; then - log_error "Docker 服务未运行" - exit 1 - fi -} - -# 检查 Docker Compose -check_docker_compose() { - if docker compose version &> /dev/null; then - COMPOSE_CMD="docker compose" - elif command -v docker-compose &> /dev/null; then - COMPOSE_CMD="docker-compose" - else - log_error "Docker Compose 未安装" - exit 1 - fi -} - -# 检查后端服务连通性(可选) -check_backend() { - local BACKEND_IP="${BACKEND_SERVER_IP:-192.168.1.111}" - log_info "检查后端服务器 $BACKEND_IP 连通性..." - if ping -c 1 -W 2 $BACKEND_IP &> /dev/null; then - log_success "后端服务器可达" - else - log_warn "无法 ping 通后端服务器 $BACKEND_IP" - log_warn "请确保后端服务已启动且网络可达" - fi -} - -# 启动服务 -cmd_up() { - log_info "启动 Kong API Gateway..." - check_backend - $COMPOSE_CMD up -d - - log_info "等待 Kong 启动..." - sleep 10 - - # 检查状态 - if docker ps | grep -q rwa-kong; then - log_success "Kong API Gateway 启动成功!" - echo "" - echo "服务地址:" - echo " Proxy: http://localhost:8000" - echo " Admin API: http://localhost:8001" - echo " Admin GUI: http://localhost:8002" - echo "" - echo "查看路由: ./deploy.sh routes" - else - log_error "Kong 启动失败,查看日志: ./deploy.sh logs" - exit 1 - fi -} - -# 停止服务 -cmd_down() { - log_info "停止 Kong API Gateway..." - $COMPOSE_CMD down - log_success "Kong 已停止" -} - -# 重启服务 -cmd_restart() { - log_info "重启 Kong API Gateway..." - $COMPOSE_CMD restart - log_success "Kong 已重启" -} - -# 查看日志 -cmd_logs() { - $COMPOSE_CMD logs -f -} - -# 查看状态 -cmd_status() { - log_info "Kong API Gateway 状态:" - $COMPOSE_CMD ps -} - -# 健康检查 -cmd_health() { - log_info "Kong 健康检查..." - - # 检查 Kong 状态 - response=$(curl -s $KONG_ADMIN_URL/status 2>/dev/null) - if [ $? -eq 0 ]; then - log_success "Kong Admin API 正常" - echo "$response" | python3 -m json.tool 2>/dev/null || echo "$response" - else - log_error "Kong Admin API 不可用" - exit 1 - fi -} - -# 重载配置 (触发 deck sync) -cmd_reload() { - log_info "重载 Kong 配置..." - $COMPOSE_CMD run --rm kong-config - log_success "配置已重载" -} - -# 同步配置到数据库 -cmd_sync() { - log_info "同步 kong.yml 配置到数据库..." - $COMPOSE_CMD run --rm kong-config - log_success "配置同步完成" - echo "" - echo "查看路由: ./deploy.sh routes" -} - -# 查看所有路由 -cmd_routes() { - log_info "Kong 路由列表:" - curl -s $KONG_ADMIN_URL/routes | python3 -m json.tool 2>/dev/null || curl -s $KONG_ADMIN_URL/routes -} - -# 查看所有服务 -cmd_services() { - log_info "Kong 服务列表:" - curl -s $KONG_ADMIN_URL/services | python3 -m json.tool 2>/dev/null || curl -s $KONG_ADMIN_URL/services -} - -# 测试 API -cmd_test() { - log_info "测试 API 路由..." - - echo "" - echo "测试 /api/v1/versions (admin-service):" - curl -s -o /dev/null -w " HTTP Status: %{http_code}\n" $KONG_PROXY_URL/api/v1/versions - - echo "" - echo "测试 /api/v1/auth (identity-service):" - curl -s -o /dev/null -w " HTTP Status: %{http_code}\n" $KONG_PROXY_URL/api/v1/auth -} - -# 清理 -cmd_clean() { - log_info "清理 Kong 容器和数据..." - $COMPOSE_CMD down -v --remove-orphans - docker image prune -f - log_success "清理完成" -} - -# 启动监控栈 -cmd_monitoring_up() { - log_info "启动监控栈 (Prometheus + Grafana)..." - $COMPOSE_CMD -f docker-compose.yml -f docker-compose.monitoring.yml up -d prometheus grafana - - log_info "等待服务启动..." - sleep 5 - - log_success "监控栈启动成功!" - echo "" - echo "监控服务地址:" - echo " Grafana: http://localhost:3030 (admin/admin123)" - echo " Prometheus: http://localhost:9099" - echo " Kong 指标: http://localhost:8001/metrics" - echo "" -} - -# 安装监控栈 (包括 Nginx + SSL) -cmd_monitoring_install() { - local domain="${1:-monitor.szaiai.com}" - log_info "安装监控栈..." - - if [ ! -f "$SCRIPT_DIR/scripts/install-monitor.sh" ]; then - log_error "安装脚本不存在: scripts/install-monitor.sh" - exit 1 - fi - - sudo bash "$SCRIPT_DIR/scripts/install-monitor.sh" "$domain" -} - -# 停止监控栈 -cmd_monitoring_down() { - log_info "停止监控栈..." - docker stop rwa-prometheus rwa-grafana 2>/dev/null || true - docker rm rwa-prometheus rwa-grafana 2>/dev/null || true - log_success "监控栈已停止" -} - -# 查看 Prometheus 指标 -cmd_metrics() { - log_info "Kong Prometheus 指标概览:" - echo "" - - # 获取关键指标 - metrics=$(curl -s $KONG_ADMIN_URL/metrics 2>/dev/null) - - if [ $? -eq 0 ]; then - echo "=== 请求统计 ===" - echo "$metrics" | grep -E "^kong_http_requests_total" | head -20 - echo "" - echo "=== 延迟统计 ===" - echo "$metrics" | grep -E "^kong_latency_" | head -10 - echo "" - echo "完整指标: curl $KONG_ADMIN_URL/metrics" - else - log_error "无法获取指标,请确保 Kong 正在运行且 prometheus 插件已启用" - fi -} - -# 显示帮助 -show_help() { - echo "" - echo "RWADurian API Gateway (Kong) 部署脚本" - echo "" - echo "用法: ./deploy.sh [命令]" - echo "" - echo "命令:" - echo " up 启动 Kong 网关" - echo " down 停止 Kong 网关" - echo " restart 重启 Kong 网关" - echo " logs 查看日志" - echo " status 查看状态" - echo " health 健康检查" - echo " sync 同步 kong.yml 配置到数据库" - echo " reload 重载 Kong 配置 (同 sync)" - echo " routes 查看所有路由" - echo " services 查看所有服务" - echo " test 测试 API 路由" - echo " clean 清理容器和数据" - echo "" - echo "监控命令:" - echo " monitoring install [domain] 一键安装监控 (Nginx+SSL+服务)" - echo " monitoring up 启动监控栈" - echo " monitoring down 停止监控栈" - echo " metrics 查看 Prometheus 指标" - echo "" - echo " help 显示帮助" - echo "" - echo "注意: 需要先启动 backend/services 才能启动 Kong" - echo "" -} - -# 主函数 -main() { - check_docker - check_docker_compose - - case "${1:-help}" in - up) - cmd_up - ;; - down) - cmd_down - ;; - restart) - cmd_restart - ;; - logs) - cmd_logs - ;; - status) - cmd_status - ;; - health) - cmd_health - ;; - sync) - cmd_sync - ;; - reload) - cmd_reload - ;; - routes) - cmd_routes - ;; - services) - cmd_services - ;; - test) - cmd_test - ;; - clean) - cmd_clean - ;; - monitoring) - case "${2:-up}" in - install) - cmd_monitoring_install "$3" - ;; - up) - cmd_monitoring_up - ;; - down) - cmd_monitoring_down - ;; - *) - log_error "未知监控命令: $2" - echo "用法: ./deploy.sh monitoring [install|up|down]" - exit 1 - ;; - esac - ;; - metrics) - cmd_metrics - ;; - help|--help|-h) - show_help - ;; - *) - log_error "未知命令: $1" - show_help - exit 1 - ;; - esac -} - -main "$@" +#!/bin/bash + +# ============================================================================= +# RWADurian API Gateway (Kong) - 部署脚本 +# ============================================================================= +# Usage: +# ./deploy.sh up # 启动网关 +# ./deploy.sh down # 停止网关 +# ./deploy.sh restart # 重启网关 +# ./deploy.sh logs # 查看日志 +# ./deploy.sh status # 查看状态 +# ./deploy.sh health # 健康检查 +# ./deploy.sh reload # 重载 Kong 配置 +# ./deploy.sh routes # 查看所有路由 +# ./deploy.sh monitoring # 启动监控栈 (Prometheus + Grafana) +# ./deploy.sh metrics # 查看 Prometheus 指标 +# ============================================================================= + +set -e + +# 颜色定义 +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}[SUCCESS]${NC} $1"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +# 项目信息 +PROJECT_NAME="rwa-api-gateway" +KONG_ADMIN_URL="http://localhost:8001" +KONG_PROXY_URL="http://localhost:8000" + +# 脚本目录 +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# 切换到脚本所在目录 +cd "$SCRIPT_DIR" + +# 加载环境变量 +if [ -f ".env" ]; then + log_info "Loading environment from .env file" + set -a + source .env + set +a +elif [ -f ".env.example" ]; then + log_warn ".env file not found!" + log_warn "Creating .env from .env.example..." + cp .env.example .env + log_error "Please edit .env file to configure your environment, then run again" + exit 1 +else + log_error "Neither .env nor .env.example found!" + exit 1 +fi + +# 检查 Docker +check_docker() { + if ! command -v docker &> /dev/null; then + log_error "Docker 未安装" + exit 1 + fi + if ! docker info &> /dev/null; then + log_error "Docker 服务未运行" + exit 1 + fi +} + +# 检查 Docker Compose +check_docker_compose() { + if docker compose version &> /dev/null; then + COMPOSE_CMD="docker compose" + elif command -v docker-compose &> /dev/null; then + COMPOSE_CMD="docker-compose" + else + log_error "Docker Compose 未安装" + exit 1 + fi +} + +# 检查后端服务连通性(可选) +check_backend() { + local BACKEND_IP="${BACKEND_SERVER_IP:-192.168.1.111}" + log_info "检查后端服务器 $BACKEND_IP 连通性..." + if ping -c 1 -W 2 $BACKEND_IP &> /dev/null; then + log_success "后端服务器可达" + else + log_warn "无法 ping 通后端服务器 $BACKEND_IP" + log_warn "请确保后端服务已启动且网络可达" + fi +} + +# 启动服务 +cmd_up() { + log_info "启动 Kong API Gateway..." + check_backend + $COMPOSE_CMD up -d + + log_info "等待 Kong 启动..." + sleep 10 + + # 检查状态 + if docker ps | grep -q rwa-kong; then + log_success "Kong API Gateway 启动成功!" + echo "" + echo "服务地址:" + echo " Proxy: http://localhost:8000" + echo " Admin API: http://localhost:8001" + echo " Admin GUI: http://localhost:8002" + echo "" + echo "查看路由: ./deploy.sh routes" + else + log_error "Kong 启动失败,查看日志: ./deploy.sh logs" + exit 1 + fi +} + +# 停止服务 +cmd_down() { + log_info "停止 Kong API Gateway..." + $COMPOSE_CMD down + log_success "Kong 已停止" +} + +# 重启服务 +cmd_restart() { + log_info "重启 Kong API Gateway..." + $COMPOSE_CMD restart + log_success "Kong 已重启" +} + +# 查看日志 +cmd_logs() { + $COMPOSE_CMD logs -f +} + +# 查看状态 +cmd_status() { + log_info "Kong API Gateway 状态:" + $COMPOSE_CMD ps +} + +# 健康检查 +cmd_health() { + log_info "Kong 健康检查..." + + # 检查 Kong 状态 + response=$(curl -s $KONG_ADMIN_URL/status 2>/dev/null) + if [ $? -eq 0 ]; then + log_success "Kong Admin API 正常" + echo "$response" | python3 -m json.tool 2>/dev/null || echo "$response" + else + log_error "Kong Admin API 不可用" + exit 1 + fi +} + +# 重载配置 (触发 deck sync) +cmd_reload() { + log_info "重载 Kong 配置..." + $COMPOSE_CMD run --rm kong-config + log_success "配置已重载" +} + +# 同步配置到数据库 +cmd_sync() { + log_info "同步 kong.yml 配置到数据库..." + $COMPOSE_CMD run --rm kong-config + log_success "配置同步完成" + echo "" + echo "查看路由: ./deploy.sh routes" +} + +# 查看所有路由 +cmd_routes() { + log_info "Kong 路由列表:" + curl -s $KONG_ADMIN_URL/routes | python3 -m json.tool 2>/dev/null || curl -s $KONG_ADMIN_URL/routes +} + +# 查看所有服务 +cmd_services() { + log_info "Kong 服务列表:" + curl -s $KONG_ADMIN_URL/services | python3 -m json.tool 2>/dev/null || curl -s $KONG_ADMIN_URL/services +} + +# 测试 API +cmd_test() { + log_info "测试 API 路由..." + + echo "" + echo "测试 /api/v1/versions (admin-service):" + curl -s -o /dev/null -w " HTTP Status: %{http_code}\n" $KONG_PROXY_URL/api/v1/versions + + echo "" + echo "测试 /api/v1/auth (identity-service):" + curl -s -o /dev/null -w " HTTP Status: %{http_code}\n" $KONG_PROXY_URL/api/v1/auth +} + +# 清理 +cmd_clean() { + log_info "清理 Kong 容器和数据..." + $COMPOSE_CMD down -v --remove-orphans + docker image prune -f + log_success "清理完成" +} + +# 启动监控栈 +cmd_monitoring_up() { + log_info "启动监控栈 (Prometheus + Grafana)..." + $COMPOSE_CMD -f docker-compose.yml -f docker-compose.monitoring.yml up -d prometheus grafana + + log_info "等待服务启动..." + sleep 5 + + log_success "监控栈启动成功!" + echo "" + echo "监控服务地址:" + echo " Grafana: http://localhost:3030 (admin/admin123)" + echo " Prometheus: http://localhost:9099" + echo " Kong 指标: http://localhost:8001/metrics" + echo "" +} + +# 安装监控栈 (包括 Nginx + SSL) +cmd_monitoring_install() { + local domain="${1:-monitor.szaiai.com}" + log_info "安装监控栈..." + + if [ ! -f "$SCRIPT_DIR/scripts/install-monitor.sh" ]; then + log_error "安装脚本不存在: scripts/install-monitor.sh" + exit 1 + fi + + sudo bash "$SCRIPT_DIR/scripts/install-monitor.sh" "$domain" +} + +# 停止监控栈 +cmd_monitoring_down() { + log_info "停止监控栈..." + docker stop rwa-prometheus rwa-grafana 2>/dev/null || true + docker rm rwa-prometheus rwa-grafana 2>/dev/null || true + log_success "监控栈已停止" +} + +# 查看 Prometheus 指标 +cmd_metrics() { + log_info "Kong Prometheus 指标概览:" + echo "" + + # 获取关键指标 + metrics=$(curl -s $KONG_ADMIN_URL/metrics 2>/dev/null) + + if [ $? -eq 0 ]; then + echo "=== 请求统计 ===" + echo "$metrics" | grep -E "^kong_http_requests_total" | head -20 + echo "" + echo "=== 延迟统计 ===" + echo "$metrics" | grep -E "^kong_latency_" | head -10 + echo "" + echo "完整指标: curl $KONG_ADMIN_URL/metrics" + else + log_error "无法获取指标,请确保 Kong 正在运行且 prometheus 插件已启用" + fi +} + +# 显示帮助 +show_help() { + echo "" + echo "RWADurian API Gateway (Kong) 部署脚本" + echo "" + echo "用法: ./deploy.sh [命令]" + echo "" + echo "命令:" + echo " up 启动 Kong 网关" + echo " down 停止 Kong 网关" + echo " restart 重启 Kong 网关" + echo " logs 查看日志" + echo " status 查看状态" + echo " health 健康检查" + echo " sync 同步 kong.yml 配置到数据库" + echo " reload 重载 Kong 配置 (同 sync)" + echo " routes 查看所有路由" + echo " services 查看所有服务" + echo " test 测试 API 路由" + echo " clean 清理容器和数据" + echo "" + echo "监控命令:" + echo " monitoring install [domain] 一键安装监控 (Nginx+SSL+服务)" + echo " monitoring up 启动监控栈" + echo " monitoring down 停止监控栈" + echo " metrics 查看 Prometheus 指标" + echo "" + echo " help 显示帮助" + echo "" + echo "注意: 需要先启动 backend/services 才能启动 Kong" + echo "" +} + +# 主函数 +main() { + check_docker + check_docker_compose + + case "${1:-help}" in + up) + cmd_up + ;; + down) + cmd_down + ;; + restart) + cmd_restart + ;; + logs) + cmd_logs + ;; + status) + cmd_status + ;; + health) + cmd_health + ;; + sync) + cmd_sync + ;; + reload) + cmd_reload + ;; + routes) + cmd_routes + ;; + services) + cmd_services + ;; + test) + cmd_test + ;; + clean) + cmd_clean + ;; + monitoring) + case "${2:-up}" in + install) + cmd_monitoring_install "$3" + ;; + up) + cmd_monitoring_up + ;; + down) + cmd_monitoring_down + ;; + *) + log_error "未知监控命令: $2" + echo "用法: ./deploy.sh monitoring [install|up|down]" + exit 1 + ;; + esac + ;; + metrics) + cmd_metrics + ;; + help|--help|-h) + show_help + ;; + *) + log_error "未知命令: $1" + show_help + exit 1 + ;; + esac +} + +main "$@" diff --git a/backend/mpc-system/scripts/deploy.sh b/backend/mpc-system/scripts/deploy.sh index e5127caf..3242828a 100755 --- a/backend/mpc-system/scripts/deploy.sh +++ b/backend/mpc-system/scripts/deploy.sh @@ -1,874 +1,874 @@ -#!/bin/bash -# -# MPC-System Native Deployment Script (No Docker) -# For environments where Docker is not available (e.g., China) -# -# Usage: -# ./scripts/deploy.sh install # Install dependencies and build services -# ./scripts/deploy.sh start # Start all services -# ./scripts/deploy.sh stop # Stop all services -# ./scripts/deploy.sh restart # Restart all services -# ./scripts/deploy.sh status # Check service status -# ./scripts/deploy.sh logs # View logs -# ./scripts/deploy.sh uninstall # Remove all services -# - -set -e - -# ============================================ -# Configuration -# ============================================ -MPC_HOME="${MPC_HOME:-/opt/mpc-system}" -MPC_USER="${MPC_USER:-mpc}" -MPC_GROUP="${MPC_GROUP:-mpc}" -LOG_DIR="${MPC_HOME}/logs" -PID_DIR="${MPC_HOME}/pids" -BIN_DIR="${MPC_HOME}/bin" -CONFIG_DIR="${MPC_HOME}/config" -DATA_DIR="${MPC_HOME}/data" - -# Service names -SERVICES=("account-service" "session-coordinator" "message-router" "server-party-1" "server-party-2" "server-party-3") - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -# ============================================ -# Helper Functions -# ============================================ -log_info() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -check_root() { - if [ "$EUID" -ne 0 ]; then - log_error "This script must be run as root" - exit 1 - fi -} - -# ============================================ -# Install Dependencies -# ============================================ -install_dependencies() { - log_info "Installing system dependencies..." - - # Update package list - apt-get update - - # Install basic tools - apt-get install -y curl wget git build-essential - - # Install Go 1.21 - log_info "Installing Go 1.21..." - if ! command -v go &> /dev/null || [[ $(go version) != *"go1.21"* ]]; then - wget -q https://go.dev/dl/go1.21.13.linux-amd64.tar.gz -O /tmp/go.tar.gz - rm -rf /usr/local/go - tar -C /usr/local -xzf /tmp/go.tar.gz - rm /tmp/go.tar.gz - - # Add Go to PATH for all users - echo 'export PATH=$PATH:/usr/local/go/bin' > /etc/profile.d/go.sh - source /etc/profile.d/go.sh - fi - log_info "Go version: $(go version)" - - # Install PostgreSQL 15 - log_info "Installing PostgreSQL 15..." - if ! command -v psql &> /dev/null; then - apt-get install -y postgresql postgresql-contrib - systemctl enable postgresql - systemctl start postgresql - fi - - # Install Redis - log_info "Installing Redis..." - if ! command -v redis-server &> /dev/null; then - apt-get install -y redis-server - systemctl enable redis-server - systemctl start redis-server - fi - - # Install RabbitMQ - log_info "Installing RabbitMQ..." - if ! command -v rabbitmqctl &> /dev/null; then - # Install Erlang first - apt-get install -y erlang-base erlang-nox erlang-dev erlang-src - - # Install RabbitMQ - apt-get install -y rabbitmq-server - systemctl enable rabbitmq-server - systemctl start rabbitmq-server - - # Enable management plugin - rabbitmq-plugins enable rabbitmq_management - fi - - log_info "All dependencies installed successfully" -} - -# ============================================ -# Create User and Directories -# ============================================ -setup_directories() { - log_info "Setting up directories..." - - # Create mpc user if not exists - if ! id "$MPC_USER" &>/dev/null; then - useradd -r -s /bin/false -d "$MPC_HOME" "$MPC_USER" - fi - - # Create directories - mkdir -p "$MPC_HOME" "$LOG_DIR" "$PID_DIR" "$BIN_DIR" "$CONFIG_DIR" "$DATA_DIR" - - # Set permissions - chown -R "$MPC_USER:$MPC_GROUP" "$MPC_HOME" - chmod 755 "$MPC_HOME" - - log_info "Directories created at $MPC_HOME" -} - -# ============================================ -# Configure Infrastructure -# ============================================ -configure_postgres() { - log_info "Configuring PostgreSQL..." - - # Load environment variables - use MPC_ prefix variables (same as Go code uses) - source "$CONFIG_DIR/mpc.env" 2>/dev/null || true - - local DB_USER="${MPC_DATABASE_USER:-mpc_user}" - local DB_PASS="${MPC_DATABASE_PASSWORD:-your_secure_postgres_password_here}" - local DB_NAME="${MPC_DATABASE_DBNAME:-mpc_system}" - - # Configure pg_hba.conf to allow password authentication for local connections - local PG_HBA="/etc/postgresql/*/main/pg_hba.conf" - for hba_file in $PG_HBA; do - if [ -f "$hba_file" ]; then - # Backup original - cp "$hba_file" "${hba_file}.bak" 2>/dev/null || true - # Change 'peer' to 'md5' for local connections to allow password auth - sed -i 's/local all all peer/local all all md5/' "$hba_file" - sed -i 's/host all all 127.0.0.1\/32 scram-sha-256/host all all 127.0.0.1\/32 md5/' "$hba_file" - sed -i 's/host all all ::1\/128 scram-sha-256/host all all ::1\/128 md5/' "$hba_file" - log_info "Updated pg_hba.conf at $hba_file" - fi - done - - # Reload PostgreSQL to apply pg_hba.conf changes - systemctl reload postgresql 2>/dev/null || systemctl restart postgresql - - # Create database and user - sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';" 2>/dev/null || \ - sudo -u postgres psql -c "ALTER USER $DB_USER WITH PASSWORD '$DB_PASS';" - sudo -u postgres psql -c "CREATE DATABASE $DB_NAME OWNER $DB_USER;" 2>/dev/null || true - sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;" 2>/dev/null || true - sudo -u postgres psql -d "$DB_NAME" -c "GRANT ALL ON SCHEMA public TO $DB_USER;" 2>/dev/null || true - - # Run migrations - log_info "Running database migrations..." - PGPASSWORD="$DB_PASS" psql -h 127.0.0.1 -U "$DB_USER" -d "$DB_NAME" -f "$MPC_HOME/migrations/001_init_schema.up.sql" 2>/dev/null || log_warn "Migration may have already been applied" - - log_info "PostgreSQL configured with user '$DB_USER' and database '$DB_NAME'" -} - -configure_redis() { - log_info "Configuring Redis..." - - source "$CONFIG_DIR/mpc.env" 2>/dev/null || true - - local REDIS_PASS="${REDIS_PASSWORD:-}" - - if [ -n "$REDIS_PASS" ]; then - # Set Redis password - sed -i "s/^# requirepass.*/requirepass $REDIS_PASS/" /etc/redis/redis.conf - systemctl restart redis-server - fi - - log_info "Redis configured" -} - -configure_rabbitmq() { - log_info "Configuring RabbitMQ..." - - source "$CONFIG_DIR/mpc.env" 2>/dev/null || true - - local RABBIT_USER="${RABBITMQ_USER:-mpc_user}" - local RABBIT_PASS="${RABBITMQ_PASSWORD:-mpc_rabbit_password}" - - # Create user - rabbitmqctl add_user "$RABBIT_USER" "$RABBIT_PASS" 2>/dev/null || rabbitmqctl change_password "$RABBIT_USER" "$RABBIT_PASS" - rabbitmqctl set_permissions -p / "$RABBIT_USER" ".*" ".*" ".*" - rabbitmqctl set_user_tags "$RABBIT_USER" administrator - - log_info "RabbitMQ configured" -} - -# ============================================ -# Build Services -# ============================================ -build_services() { - log_info "Building MPC services..." - - # Get the script's directory (where the source code is) - local SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" - - export PATH=$PATH:/usr/local/go/bin - export GOPATH="$MPC_HOME/go" - export GOPROXY="https://goproxy.cn,direct" # Use Chinese proxy - - cd "$SOURCE_DIR" - - # Download dependencies - log_info "Downloading Go dependencies..." - go mod download - - # Build account service - log_info "Building account-service..." - go build -o "$BIN_DIR/account-service" ./services/account/cmd/server/ - - # Build session coordinator - log_info "Building session-coordinator..." - go build -o "$BIN_DIR/session-coordinator" ./services/session-coordinator/cmd/server/ - - # Build message router - log_info "Building message-router..." - go build -o "$BIN_DIR/message-router" ./services/message-router/cmd/server/ - - # Build server party (single binary, different config for each party) - log_info "Building server-party..." - go build -o "$BIN_DIR/server-party" ./services/server-party/cmd/server/ - - # Copy migrations - cp -r "$SOURCE_DIR/migrations" "$MPC_HOME/" - - # Set permissions - chmod +x "$BIN_DIR"/* - chown -R "$MPC_USER:$MPC_GROUP" "$BIN_DIR" - - log_info "All services built successfully" -} - -# ============================================ -# Create Systemd Service Files -# ============================================ -create_systemd_services() { - log_info "Creating systemd service files..." - - # Common service template - # Args: SERVICE_NAME, DESCRIPTION, EXEC_START, EXTRA_ENV (optional) - create_service_file() { - local SERVICE_NAME=$1 - local DESCRIPTION=$2 - local EXEC_START=$3 - local EXTRA_ENV=$4 - - cat > "/etc/systemd/system/$SERVICE_NAME.service" << EOF -[Unit] -Description=MPC System - $DESCRIPTION -After=network.target postgresql.service redis-server.service rabbitmq-server.service -Wants=postgresql.service redis-server.service rabbitmq-server.service - -[Service] -Type=simple -User=$MPC_USER -Group=$MPC_GROUP -WorkingDirectory=$MPC_HOME -EnvironmentFile=$CONFIG_DIR/mpc.env -${EXTRA_ENV:+$EXTRA_ENV} -ExecStart=$EXEC_START -Restart=always -RestartSec=5 -StandardOutput=append:$LOG_DIR/$SERVICE_NAME.log -StandardError=append:$LOG_DIR/$SERVICE_NAME.error.log - -# Security settings -NoNewPrivileges=yes -ProtectSystem=strict -ProtectHome=yes -ReadWritePaths=$MPC_HOME - -[Install] -WantedBy=multi-user.target -EOF - } - - # Create service files with different gRPC ports to avoid conflicts - # session-coordinator: gRPC 50051, HTTP 8081 - # message-router: gRPC 50052, HTTP 8082 - # server-party-1/2/3: HTTP 8083/8084/8085 - # account-service: HTTP 8080 - - create_service_file "mpc-account" "Account Service" "$BIN_DIR/account-service" \ - "Environment=MPC_SERVER_HTTP_PORT=8080" - - create_service_file "mpc-session-coordinator" "Session Coordinator" "$BIN_DIR/session-coordinator" \ - "Environment=MPC_SERVER_GRPC_PORT=50051 -Environment=MPC_SERVER_HTTP_PORT=8081" - - create_service_file "mpc-message-router" "Message Router" "$BIN_DIR/message-router" \ - "Environment=MPC_SERVER_GRPC_PORT=50052 -Environment=MPC_SERVER_HTTP_PORT=8082" - - create_service_file "mpc-server-party-1" "Server Party 1" "$BIN_DIR/server-party" \ - "Environment=PARTY_ID=server-party-1 -Environment=MPC_SERVER_HTTP_PORT=8083" - - create_service_file "mpc-server-party-2" "Server Party 2" "$BIN_DIR/server-party" \ - "Environment=PARTY_ID=server-party-2 -Environment=MPC_SERVER_HTTP_PORT=8084" - - create_service_file "mpc-server-party-3" "Server Party 3" "$BIN_DIR/server-party" \ - "Environment=PARTY_ID=server-party-3 -Environment=MPC_SERVER_HTTP_PORT=8085" - - # Reload systemd - systemctl daemon-reload - - log_info "Systemd services created" -} - -# ============================================ -# Generate Secure Random Keys -# ============================================ -generate_random_password() { - # Generate a random 32-character alphanumeric password - openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 32 -} - -generate_random_hex_key() { - # Generate a random 64-character hex key (256-bit) - openssl rand -hex 32 -} - -# ============================================ -# Create Environment Configuration -# ============================================ -create_env_config() { - log_info "Creating environment configuration..." - - if [ ! -f "$CONFIG_DIR/mpc.env" ]; then - # Generate secure random keys - local POSTGRES_PASS=$(generate_random_password) - local RABBITMQ_PASS=$(generate_random_password) - local JWT_SECRET=$(generate_random_password) - local API_KEY=$(generate_random_password) - local MASTER_KEY=$(generate_random_hex_key) - - log_info "Generating secure random keys..." - - cat > "$CONFIG_DIR/mpc.env" << EOF -# MPC-System Environment Configuration -# Auto-generated secure keys - modify if needed - -# Environment -ENVIRONMENT=production - -# PostgreSQL Database -POSTGRES_USER=mpc_user -POSTGRES_PASSWORD=${POSTGRES_PASS} -MPC_DATABASE_HOST=localhost -MPC_DATABASE_PORT=5432 -MPC_DATABASE_USER=mpc_user -MPC_DATABASE_PASSWORD=${POSTGRES_PASS} -MPC_DATABASE_DBNAME=mpc_system -MPC_DATABASE_SSLMODE=disable - -# Redis Cache (empty = no password) -REDIS_PASSWORD= -MPC_REDIS_HOST=localhost -MPC_REDIS_PORT=6379 -MPC_REDIS_PASSWORD= - -# RabbitMQ Message Queue -RABBITMQ_USER=mpc_user -RABBITMQ_PASSWORD=${RABBITMQ_PASS} -MPC_RABBITMQ_HOST=localhost -MPC_RABBITMQ_PORT=5672 -MPC_RABBITMQ_USER=mpc_user -MPC_RABBITMQ_PASSWORD=${RABBITMQ_PASS} - -# JWT Configuration -JWT_SECRET_KEY=${JWT_SECRET} -MPC_JWT_SECRET_KEY=${JWT_SECRET} -MPC_JWT_ISSUER=mpc-system - -# Crypto Master Key (64 hex characters = 256-bit key for encrypting key shares) -CRYPTO_MASTER_KEY=${MASTER_KEY} -MPC_CRYPTO_MASTER_KEY=${MASTER_KEY} - -# API Security -MPC_API_KEY=${API_KEY} -ALLOWED_IPS=192.168.1.111 - -# Server Configuration -MPC_SERVER_ENVIRONMENT=production -# NOTE: MPC_SERVER_HTTP_PORT and MPC_SERVER_GRPC_PORT are set per-service in systemd unit files -# Do NOT set them here as they are service-specific: -# session-coordinator: gRPC 50051, HTTP 8081 -# message-router: gRPC 50052, HTTP 8082 -# server-party-1/2/3: HTTP 8083/8084/8085 -# account-service: HTTP 8080 - -# Internal Service Addresses -SESSION_COORDINATOR_ADDR=localhost:50051 -MESSAGE_ROUTER_ADDR=localhost:50052 -EOF - - chmod 600 "$CONFIG_DIR/mpc.env" - chown "$MPC_USER:$MPC_GROUP" "$CONFIG_DIR/mpc.env" - - log_info "Environment file created with auto-generated secure keys" - log_info "Keys saved to: $CONFIG_DIR/mpc.env" - else - log_info "Environment file already exists" - fi -} - -# ============================================ -# Regenerate Keys (for existing installation) -# ============================================ -regenerate_keys() { - check_root - - log_info "Regenerating secure keys..." - - local MASTER_KEY=$(generate_random_hex_key) - local JWT_SECRET=$(generate_random_password) - local API_KEY=$(generate_random_password) - - if [ -f "$CONFIG_DIR/mpc.env" ]; then - # Replace CRYPTO_MASTER_KEY and MPC_CRYPTO_MASTER_KEY lines entirely - # This handles any existing value, not just specific placeholders - sed -i "s/^CRYPTO_MASTER_KEY=.*/CRYPTO_MASTER_KEY=${MASTER_KEY}/" "$CONFIG_DIR/mpc.env" - sed -i "s/^MPC_CRYPTO_MASTER_KEY=.*/MPC_CRYPTO_MASTER_KEY=${MASTER_KEY}/" "$CONFIG_DIR/mpc.env" - - # Replace JWT keys - sed -i "s/^JWT_SECRET_KEY=.*/JWT_SECRET_KEY=${JWT_SECRET}/" "$CONFIG_DIR/mpc.env" - sed -i "s/^MPC_JWT_SECRET_KEY=.*/MPC_JWT_SECRET_KEY=${JWT_SECRET}/" "$CONFIG_DIR/mpc.env" - - # Replace API key - sed -i "s/^MPC_API_KEY=.*/MPC_API_KEY=${API_KEY}/" "$CONFIG_DIR/mpc.env" - - log_info "Keys regenerated successfully" - log_info "New MASTER_KEY: ${MASTER_KEY:0:16}..." - log_info "New JWT_SECRET: ${JWT_SECRET:0:8}..." - log_info "New API_KEY: ${API_KEY:0:8}..." - log_info "" - log_info "Now reconfigure PostgreSQL with new password and restart services:" - log_info " $0 reconfigure" - log_info " $0 restart" - else - log_error "Environment file not found: $CONFIG_DIR/mpc.env" - exit 1 - fi -} - -# ============================================ -# Service Control Functions -# ============================================ -start_services() { - log_info "Starting MPC services..." - - # Start infrastructure first - systemctl start postgresql - systemctl start redis-server - systemctl start rabbitmq-server - - sleep 3 - - # Start MPC services in order - systemctl start mpc-session-coordinator - sleep 2 - systemctl start mpc-message-router - sleep 2 - systemctl start mpc-server-party-1 - systemctl start mpc-server-party-2 - systemctl start mpc-server-party-3 - sleep 2 - systemctl start mpc-account - - log_info "All services started" -} - -stop_services() { - log_info "Stopping MPC services..." - - systemctl stop mpc-account 2>/dev/null || true - systemctl stop mpc-server-party-1 2>/dev/null || true - systemctl stop mpc-server-party-2 2>/dev/null || true - systemctl stop mpc-server-party-3 2>/dev/null || true - systemctl stop mpc-message-router 2>/dev/null || true - systemctl stop mpc-session-coordinator 2>/dev/null || true - - log_info "All MPC services stopped" -} - -restart_services() { - stop_services - sleep 2 - start_services -} - -enable_services() { - log_info "Enabling MPC services to start on boot..." - - systemctl enable mpc-session-coordinator - systemctl enable mpc-message-router - systemctl enable mpc-server-party-1 - systemctl enable mpc-server-party-2 - systemctl enable mpc-server-party-3 - systemctl enable mpc-account - - log_info "Services enabled" -} - -status_services() { - echo "" - echo "============================================" - echo "MPC System Service Status" - echo "============================================" - echo "" - - # Infrastructure - echo "Infrastructure:" - echo " PostgreSQL: $(systemctl is-active postgresql)" - echo " Redis: $(systemctl is-active redis-server)" - echo " RabbitMQ: $(systemctl is-active rabbitmq-server)" - echo "" - - # MPC Services - echo "MPC Services:" - echo " Session Coordinator: $(systemctl is-active mpc-session-coordinator)" - echo " Message Router: $(systemctl is-active mpc-message-router)" - echo " Server Party 1: $(systemctl is-active mpc-server-party-1)" - echo " Server Party 2: $(systemctl is-active mpc-server-party-2)" - echo " Server Party 3: $(systemctl is-active mpc-server-party-3)" - echo " Account Service: $(systemctl is-active mpc-account)" - echo "" - - # Health check - echo "Health Check:" - if curl -s http://localhost:8080/health > /dev/null 2>&1; then - echo " Account Service API: ${GREEN}OK${NC}" - else - echo " Account Service API: ${RED}FAIL${NC}" - fi - echo "" -} - -view_logs() { - local SERVICE="${2:-mpc-account}" - echo "Viewing logs for $SERVICE..." - echo "Press Ctrl+C to exit" - echo "" - - if [ -f "$LOG_DIR/$SERVICE.log" ]; then - tail -f "$LOG_DIR/$SERVICE.log" - else - journalctl -u "$SERVICE" -f - fi -} - -# ============================================ -# Install Command -# ============================================ -install() { - check_root - - log_info "Starting MPC-System installation..." - - install_dependencies - setup_directories - create_env_config - - log_warn "Please edit the configuration file: $CONFIG_DIR/mpc.env" - log_warn "Then run: $0 build" -} - -build() { - check_root - - log_info "Building MPC-System..." - - build_services - create_systemd_services - configure_postgres - configure_redis - configure_rabbitmq - enable_services - - log_info "Build complete!" - log_info "Start services with: $0 start" -} - -# ============================================ -# Reconfigure Command (fix existing installation) -# ============================================ -reconfigure() { - check_root - - log_info "Reconfiguring MPC-System infrastructure..." - - configure_postgres - configure_redis - configure_rabbitmq - - log_info "Reconfiguration complete!" - log_info "Restart services with: $0 restart" -} - -# ============================================ -# Fix Port Conflicts (remove global port settings from mpc.env) -# ============================================ -fix_ports() { - check_root - - log_info "Fixing port configuration..." - - if [ ! -f "$CONFIG_DIR/mpc.env" ]; then - log_error "Environment file not found: $CONFIG_DIR/mpc.env" - exit 1 - fi - - # Remove MPC_SERVER_HTTP_PORT and MPC_SERVER_GRPC_PORT from mpc.env - # These should be set per-service in systemd unit files, not globally - if grep -q "^MPC_SERVER_HTTP_PORT=" "$CONFIG_DIR/mpc.env"; then - sed -i '/^MPC_SERVER_HTTP_PORT=/d' "$CONFIG_DIR/mpc.env" - log_info "Removed MPC_SERVER_HTTP_PORT from mpc.env" - fi - - if grep -q "^MPC_SERVER_GRPC_PORT=" "$CONFIG_DIR/mpc.env"; then - sed -i '/^MPC_SERVER_GRPC_PORT=/d' "$CONFIG_DIR/mpc.env" - log_info "Removed MPC_SERVER_GRPC_PORT from mpc.env" - fi - - # Add explanatory comment if not already present - if ! grep -q "# Port configuration is per-service" "$CONFIG_DIR/mpc.env"; then - cat >> "$CONFIG_DIR/mpc.env" << 'EOF' - -# Port configuration is per-service (set in systemd unit files): -# session-coordinator: gRPC 50051, HTTP 8081 -# message-router: gRPC 50052, HTTP 8082 -# server-party-1/2/3: HTTP 8083/8084/8085 -# account-service: HTTP 8080 -EOF - log_info "Added port documentation to mpc.env" - fi - - # Reload systemd and restart services - systemctl daemon-reload - - log_info "Port configuration fixed!" - log_info "Restart services with: $0 restart" -} - -# ============================================ -# Debug Command (troubleshooting) -# ============================================ -debug() { - echo "" - echo "============================================" - echo "MPC-System Debug Information" - echo "============================================" - echo "" - - # Load environment variables - if [ -f "$CONFIG_DIR/mpc.env" ]; then - source "$CONFIG_DIR/mpc.env" - log_info "Loaded environment from $CONFIG_DIR/mpc.env" - else - log_error "Environment file not found: $CONFIG_DIR/mpc.env" - return 1 - fi - - echo "" - echo "=== Environment Variables ===" - echo "MPC_DATABASE_HOST: ${MPC_DATABASE_HOST:-NOT SET}" - echo "MPC_DATABASE_PORT: ${MPC_DATABASE_PORT:-NOT SET}" - echo "MPC_DATABASE_USER: ${MPC_DATABASE_USER:-NOT SET}" - echo "MPC_DATABASE_PASSWORD: ${MPC_DATABASE_PASSWORD:+SET (hidden)}" - echo "MPC_DATABASE_DBNAME: ${MPC_DATABASE_DBNAME:-NOT SET}" - echo "SESSION_COORDINATOR_ADDR: ${SESSION_COORDINATOR_ADDR:-NOT SET}" - echo "MESSAGE_ROUTER_ADDR: ${MESSAGE_ROUTER_ADDR:-NOT SET}" - echo "" - - echo "=== PostgreSQL Connection Test ===" - local DB_USER="${MPC_DATABASE_USER:-mpc_user}" - local DB_PASS="${MPC_DATABASE_PASSWORD:-}" - local DB_NAME="${MPC_DATABASE_DBNAME:-mpc_system}" - local DB_HOST="${MPC_DATABASE_HOST:-localhost}" - - # Test PostgreSQL connection with password - echo "Testing connection to PostgreSQL..." - if PGPASSWORD="$DB_PASS" psql -h 127.0.0.1 -U "$DB_USER" -d "$DB_NAME" -c "SELECT 1;" > /dev/null 2>&1; then - echo " PostgreSQL connection: ${GREEN}OK${NC}" - else - echo " PostgreSQL connection: ${RED}FAILED${NC}" - echo "" - echo " Trying with verbose output:" - PGPASSWORD="$DB_PASS" psql -h 127.0.0.1 -U "$DB_USER" -d "$DB_NAME" -c "SELECT 1;" 2>&1 || true - echo "" - echo " Check pg_hba.conf authentication method:" - cat /etc/postgresql/*/main/pg_hba.conf 2>/dev/null | grep -v "^#" | grep -v "^$" | head -10 - fi - echo "" - - echo "=== Redis Connection Test ===" - if redis-cli ping > /dev/null 2>&1; then - echo " Redis connection: ${GREEN}OK${NC}" - else - echo " Redis connection: ${RED}FAILED${NC}" - fi - echo "" - - echo "=== RabbitMQ Connection Test ===" - if rabbitmqctl status > /dev/null 2>&1; then - echo " RabbitMQ status: ${GREEN}OK${NC}" - else - echo " RabbitMQ status: ${RED}FAILED${NC}" - fi - echo "" - - echo "=== Port Listening Status ===" - echo " PostgreSQL (5432): $(ss -tlnp | grep ':5432' > /dev/null && echo 'LISTENING' || echo 'NOT LISTENING')" - echo " Redis (6379): $(ss -tlnp | grep ':6379' > /dev/null && echo 'LISTENING' || echo 'NOT LISTENING')" - echo " RabbitMQ (5672): $(ss -tlnp | grep ':5672' > /dev/null && echo 'LISTENING' || echo 'NOT LISTENING')" - echo " Session Coordinator gRPC (50051): $(ss -tlnp | grep ':50051' > /dev/null && echo 'LISTENING' || echo 'NOT LISTENING')" - echo " Message Router gRPC (50052): $(ss -tlnp | grep ':50052' > /dev/null && echo 'LISTENING' || echo 'NOT LISTENING')" - echo " Account Service HTTP (8080): $(ss -tlnp | grep ':8080' > /dev/null && echo 'LISTENING' || echo 'NOT LISTENING')" - echo "" - - echo "=== Service Error Logs (last 10 lines) ===" - for service in mpc-session-coordinator mpc-message-router mpc-server-party-1 mpc-account; do - echo "" - echo "--- $service ---" - journalctl -u "$service" --no-pager -n 10 2>/dev/null || echo "No logs available" - done - echo "" - - echo "=== Manual Test Command ===" - echo "Run this command to manually test a service:" - echo "" - echo " sudo -u $MPC_USER bash -c 'source $CONFIG_DIR/mpc.env && $BIN_DIR/session-coordinator'" - echo "" -} - -# ============================================ -# Uninstall Command -# ============================================ -uninstall() { - check_root - - log_warn "This will remove all MPC services and data!" - read -p "Are you sure? (yes/no): " confirm - - if [ "$confirm" != "yes" ]; then - log_info "Uninstall cancelled" - exit 0 - fi - - stop_services - - # Disable and remove services - for service in mpc-account mpc-session-coordinator mpc-message-router mpc-server-party-1 mpc-server-party-2 mpc-server-party-3; do - systemctl disable "$service" 2>/dev/null || true - rm -f "/etc/systemd/system/$service.service" - done - - systemctl daemon-reload - - # Remove directories (keep data by default) - rm -rf "$BIN_DIR" "$PID_DIR" - - log_info "MPC services removed" - log_warn "Data directory preserved at: $DATA_DIR" - log_warn "Config directory preserved at: $CONFIG_DIR" - log_warn "To completely remove, run: rm -rf $MPC_HOME" -} - -# ============================================ -# Main -# ============================================ -case "${1:-}" in - install) - install - ;; - build) - build - ;; - reconfigure) - reconfigure - ;; - regenerate-keys) - regenerate_keys - ;; - fix-ports) - fix_ports - ;; - debug) - debug - ;; - start) - start_services - ;; - stop) - stop_services - ;; - restart) - restart_services - ;; - status) - status_services - ;; - logs) - view_logs "$@" - ;; - uninstall) - uninstall - ;; - *) - echo "MPC-System Deployment Script" - echo "" - echo "Usage: $0 {install|build|reconfigure|regenerate-keys|fix-ports|debug|start|stop|restart|status|logs|uninstall}" - echo "" - echo "Commands:" - echo " install - Install system dependencies (Go, PostgreSQL, Redis, RabbitMQ)" - echo " build - Build services and configure infrastructure" - echo " reconfigure - Reconfigure PostgreSQL/Redis/RabbitMQ (fix auth issues)" - echo " regenerate-keys - Regenerate secure keys (fix placeholder key issues)" - echo " fix-ports - Fix port conflicts (remove global port settings from mpc.env)" - echo " debug - Show debug information and test connections" - echo " start - Start all MPC services" - echo " stop - Stop all MPC services" - echo " restart - Restart all MPC services" - echo " status - Show service status" - echo " logs - View service logs (use: $0 logs [service-name])" - echo " uninstall - Remove MPC services" - echo "" - echo "Example:" - echo " $0 install # First time setup (auto-generates secure keys)" - echo " $0 build # Build and configure" - echo " $0 start # Start services" - echo " $0 status # Check status" - echo "" - echo "Troubleshooting:" - echo " $0 debug # Show debug info and test DB connection" - echo " $0 reconfigure # Fix database authentication issues" - echo " $0 regenerate-keys # Fix 'Invalid master key format' errors" - echo " $0 restart # Then restart services" - echo "" - exit 1 - ;; -esac +#!/bin/bash +# +# MPC-System Native Deployment Script (No Docker) +# For environments where Docker is not available (e.g., China) +# +# Usage: +# ./scripts/deploy.sh install # Install dependencies and build services +# ./scripts/deploy.sh start # Start all services +# ./scripts/deploy.sh stop # Stop all services +# ./scripts/deploy.sh restart # Restart all services +# ./scripts/deploy.sh status # Check service status +# ./scripts/deploy.sh logs # View logs +# ./scripts/deploy.sh uninstall # Remove all services +# + +set -e + +# ============================================ +# Configuration +# ============================================ +MPC_HOME="${MPC_HOME:-/opt/mpc-system}" +MPC_USER="${MPC_USER:-mpc}" +MPC_GROUP="${MPC_GROUP:-mpc}" +LOG_DIR="${MPC_HOME}/logs" +PID_DIR="${MPC_HOME}/pids" +BIN_DIR="${MPC_HOME}/bin" +CONFIG_DIR="${MPC_HOME}/config" +DATA_DIR="${MPC_HOME}/data" + +# Service names +SERVICES=("account-service" "session-coordinator" "message-router" "server-party-1" "server-party-2" "server-party-3") + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# ============================================ +# Helper Functions +# ============================================ +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +check_root() { + if [ "$EUID" -ne 0 ]; then + log_error "This script must be run as root" + exit 1 + fi +} + +# ============================================ +# Install Dependencies +# ============================================ +install_dependencies() { + log_info "Installing system dependencies..." + + # Update package list + apt-get update + + # Install basic tools + apt-get install -y curl wget git build-essential + + # Install Go 1.21 + log_info "Installing Go 1.21..." + if ! command -v go &> /dev/null || [[ $(go version) != *"go1.21"* ]]; then + wget -q https://go.dev/dl/go1.21.13.linux-amd64.tar.gz -O /tmp/go.tar.gz + rm -rf /usr/local/go + tar -C /usr/local -xzf /tmp/go.tar.gz + rm /tmp/go.tar.gz + + # Add Go to PATH for all users + echo 'export PATH=$PATH:/usr/local/go/bin' > /etc/profile.d/go.sh + source /etc/profile.d/go.sh + fi + log_info "Go version: $(go version)" + + # Install PostgreSQL 15 + log_info "Installing PostgreSQL 15..." + if ! command -v psql &> /dev/null; then + apt-get install -y postgresql postgresql-contrib + systemctl enable postgresql + systemctl start postgresql + fi + + # Install Redis + log_info "Installing Redis..." + if ! command -v redis-server &> /dev/null; then + apt-get install -y redis-server + systemctl enable redis-server + systemctl start redis-server + fi + + # Install RabbitMQ + log_info "Installing RabbitMQ..." + if ! command -v rabbitmqctl &> /dev/null; then + # Install Erlang first + apt-get install -y erlang-base erlang-nox erlang-dev erlang-src + + # Install RabbitMQ + apt-get install -y rabbitmq-server + systemctl enable rabbitmq-server + systemctl start rabbitmq-server + + # Enable management plugin + rabbitmq-plugins enable rabbitmq_management + fi + + log_info "All dependencies installed successfully" +} + +# ============================================ +# Create User and Directories +# ============================================ +setup_directories() { + log_info "Setting up directories..." + + # Create mpc user if not exists + if ! id "$MPC_USER" &>/dev/null; then + useradd -r -s /bin/false -d "$MPC_HOME" "$MPC_USER" + fi + + # Create directories + mkdir -p "$MPC_HOME" "$LOG_DIR" "$PID_DIR" "$BIN_DIR" "$CONFIG_DIR" "$DATA_DIR" + + # Set permissions + chown -R "$MPC_USER:$MPC_GROUP" "$MPC_HOME" + chmod 755 "$MPC_HOME" + + log_info "Directories created at $MPC_HOME" +} + +# ============================================ +# Configure Infrastructure +# ============================================ +configure_postgres() { + log_info "Configuring PostgreSQL..." + + # Load environment variables - use MPC_ prefix variables (same as Go code uses) + source "$CONFIG_DIR/mpc.env" 2>/dev/null || true + + local DB_USER="${MPC_DATABASE_USER:-mpc_user}" + local DB_PASS="${MPC_DATABASE_PASSWORD:-your_secure_postgres_password_here}" + local DB_NAME="${MPC_DATABASE_DBNAME:-mpc_system}" + + # Configure pg_hba.conf to allow password authentication for local connections + local PG_HBA="/etc/postgresql/*/main/pg_hba.conf" + for hba_file in $PG_HBA; do + if [ -f "$hba_file" ]; then + # Backup original + cp "$hba_file" "${hba_file}.bak" 2>/dev/null || true + # Change 'peer' to 'md5' for local connections to allow password auth + sed -i 's/local all all peer/local all all md5/' "$hba_file" + sed -i 's/host all all 127.0.0.1\/32 scram-sha-256/host all all 127.0.0.1\/32 md5/' "$hba_file" + sed -i 's/host all all ::1\/128 scram-sha-256/host all all ::1\/128 md5/' "$hba_file" + log_info "Updated pg_hba.conf at $hba_file" + fi + done + + # Reload PostgreSQL to apply pg_hba.conf changes + systemctl reload postgresql 2>/dev/null || systemctl restart postgresql + + # Create database and user + sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';" 2>/dev/null || \ + sudo -u postgres psql -c "ALTER USER $DB_USER WITH PASSWORD '$DB_PASS';" + sudo -u postgres psql -c "CREATE DATABASE $DB_NAME OWNER $DB_USER;" 2>/dev/null || true + sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;" 2>/dev/null || true + sudo -u postgres psql -d "$DB_NAME" -c "GRANT ALL ON SCHEMA public TO $DB_USER;" 2>/dev/null || true + + # Run migrations + log_info "Running database migrations..." + PGPASSWORD="$DB_PASS" psql -h 127.0.0.1 -U "$DB_USER" -d "$DB_NAME" -f "$MPC_HOME/migrations/001_init_schema.up.sql" 2>/dev/null || log_warn "Migration may have already been applied" + + log_info "PostgreSQL configured with user '$DB_USER' and database '$DB_NAME'" +} + +configure_redis() { + log_info "Configuring Redis..." + + source "$CONFIG_DIR/mpc.env" 2>/dev/null || true + + local REDIS_PASS="${REDIS_PASSWORD:-}" + + if [ -n "$REDIS_PASS" ]; then + # Set Redis password + sed -i "s/^# requirepass.*/requirepass $REDIS_PASS/" /etc/redis/redis.conf + systemctl restart redis-server + fi + + log_info "Redis configured" +} + +configure_rabbitmq() { + log_info "Configuring RabbitMQ..." + + source "$CONFIG_DIR/mpc.env" 2>/dev/null || true + + local RABBIT_USER="${RABBITMQ_USER:-mpc_user}" + local RABBIT_PASS="${RABBITMQ_PASSWORD:-mpc_rabbit_password}" + + # Create user + rabbitmqctl add_user "$RABBIT_USER" "$RABBIT_PASS" 2>/dev/null || rabbitmqctl change_password "$RABBIT_USER" "$RABBIT_PASS" + rabbitmqctl set_permissions -p / "$RABBIT_USER" ".*" ".*" ".*" + rabbitmqctl set_user_tags "$RABBIT_USER" administrator + + log_info "RabbitMQ configured" +} + +# ============================================ +# Build Services +# ============================================ +build_services() { + log_info "Building MPC services..." + + # Get the script's directory (where the source code is) + local SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + + export PATH=$PATH:/usr/local/go/bin + export GOPATH="$MPC_HOME/go" + export GOPROXY="https://goproxy.cn,direct" # Use Chinese proxy + + cd "$SOURCE_DIR" + + # Download dependencies + log_info "Downloading Go dependencies..." + go mod download + + # Build account service + log_info "Building account-service..." + go build -o "$BIN_DIR/account-service" ./services/account/cmd/server/ + + # Build session coordinator + log_info "Building session-coordinator..." + go build -o "$BIN_DIR/session-coordinator" ./services/session-coordinator/cmd/server/ + + # Build message router + log_info "Building message-router..." + go build -o "$BIN_DIR/message-router" ./services/message-router/cmd/server/ + + # Build server party (single binary, different config for each party) + log_info "Building server-party..." + go build -o "$BIN_DIR/server-party" ./services/server-party/cmd/server/ + + # Copy migrations + cp -r "$SOURCE_DIR/migrations" "$MPC_HOME/" + + # Set permissions + chmod +x "$BIN_DIR"/* + chown -R "$MPC_USER:$MPC_GROUP" "$BIN_DIR" + + log_info "All services built successfully" +} + +# ============================================ +# Create Systemd Service Files +# ============================================ +create_systemd_services() { + log_info "Creating systemd service files..." + + # Common service template + # Args: SERVICE_NAME, DESCRIPTION, EXEC_START, EXTRA_ENV (optional) + create_service_file() { + local SERVICE_NAME=$1 + local DESCRIPTION=$2 + local EXEC_START=$3 + local EXTRA_ENV=$4 + + cat > "/etc/systemd/system/$SERVICE_NAME.service" << EOF +[Unit] +Description=MPC System - $DESCRIPTION +After=network.target postgresql.service redis-server.service rabbitmq-server.service +Wants=postgresql.service redis-server.service rabbitmq-server.service + +[Service] +Type=simple +User=$MPC_USER +Group=$MPC_GROUP +WorkingDirectory=$MPC_HOME +EnvironmentFile=$CONFIG_DIR/mpc.env +${EXTRA_ENV:+$EXTRA_ENV} +ExecStart=$EXEC_START +Restart=always +RestartSec=5 +StandardOutput=append:$LOG_DIR/$SERVICE_NAME.log +StandardError=append:$LOG_DIR/$SERVICE_NAME.error.log + +# Security settings +NoNewPrivileges=yes +ProtectSystem=strict +ProtectHome=yes +ReadWritePaths=$MPC_HOME + +[Install] +WantedBy=multi-user.target +EOF + } + + # Create service files with different gRPC ports to avoid conflicts + # session-coordinator: gRPC 50051, HTTP 8081 + # message-router: gRPC 50052, HTTP 8082 + # server-party-1/2/3: HTTP 8083/8084/8085 + # account-service: HTTP 8080 + + create_service_file "mpc-account" "Account Service" "$BIN_DIR/account-service" \ + "Environment=MPC_SERVER_HTTP_PORT=8080" + + create_service_file "mpc-session-coordinator" "Session Coordinator" "$BIN_DIR/session-coordinator" \ + "Environment=MPC_SERVER_GRPC_PORT=50051 +Environment=MPC_SERVER_HTTP_PORT=8081" + + create_service_file "mpc-message-router" "Message Router" "$BIN_DIR/message-router" \ + "Environment=MPC_SERVER_GRPC_PORT=50052 +Environment=MPC_SERVER_HTTP_PORT=8082" + + create_service_file "mpc-server-party-1" "Server Party 1" "$BIN_DIR/server-party" \ + "Environment=PARTY_ID=server-party-1 +Environment=MPC_SERVER_HTTP_PORT=8083" + + create_service_file "mpc-server-party-2" "Server Party 2" "$BIN_DIR/server-party" \ + "Environment=PARTY_ID=server-party-2 +Environment=MPC_SERVER_HTTP_PORT=8084" + + create_service_file "mpc-server-party-3" "Server Party 3" "$BIN_DIR/server-party" \ + "Environment=PARTY_ID=server-party-3 +Environment=MPC_SERVER_HTTP_PORT=8085" + + # Reload systemd + systemctl daemon-reload + + log_info "Systemd services created" +} + +# ============================================ +# Generate Secure Random Keys +# ============================================ +generate_random_password() { + # Generate a random 32-character alphanumeric password + openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 32 +} + +generate_random_hex_key() { + # Generate a random 64-character hex key (256-bit) + openssl rand -hex 32 +} + +# ============================================ +# Create Environment Configuration +# ============================================ +create_env_config() { + log_info "Creating environment configuration..." + + if [ ! -f "$CONFIG_DIR/mpc.env" ]; then + # Generate secure random keys + local POSTGRES_PASS=$(generate_random_password) + local RABBITMQ_PASS=$(generate_random_password) + local JWT_SECRET=$(generate_random_password) + local API_KEY=$(generate_random_password) + local MASTER_KEY=$(generate_random_hex_key) + + log_info "Generating secure random keys..." + + cat > "$CONFIG_DIR/mpc.env" << EOF +# MPC-System Environment Configuration +# Auto-generated secure keys - modify if needed + +# Environment +ENVIRONMENT=production + +# PostgreSQL Database +POSTGRES_USER=mpc_user +POSTGRES_PASSWORD=${POSTGRES_PASS} +MPC_DATABASE_HOST=localhost +MPC_DATABASE_PORT=5432 +MPC_DATABASE_USER=mpc_user +MPC_DATABASE_PASSWORD=${POSTGRES_PASS} +MPC_DATABASE_DBNAME=mpc_system +MPC_DATABASE_SSLMODE=disable + +# Redis Cache (empty = no password) +REDIS_PASSWORD= +MPC_REDIS_HOST=localhost +MPC_REDIS_PORT=6379 +MPC_REDIS_PASSWORD= + +# RabbitMQ Message Queue +RABBITMQ_USER=mpc_user +RABBITMQ_PASSWORD=${RABBITMQ_PASS} +MPC_RABBITMQ_HOST=localhost +MPC_RABBITMQ_PORT=5672 +MPC_RABBITMQ_USER=mpc_user +MPC_RABBITMQ_PASSWORD=${RABBITMQ_PASS} + +# JWT Configuration +JWT_SECRET_KEY=${JWT_SECRET} +MPC_JWT_SECRET_KEY=${JWT_SECRET} +MPC_JWT_ISSUER=mpc-system + +# Crypto Master Key (64 hex characters = 256-bit key for encrypting key shares) +CRYPTO_MASTER_KEY=${MASTER_KEY} +MPC_CRYPTO_MASTER_KEY=${MASTER_KEY} + +# API Security +MPC_API_KEY=${API_KEY} +ALLOWED_IPS=192.168.1.111 + +# Server Configuration +MPC_SERVER_ENVIRONMENT=production +# NOTE: MPC_SERVER_HTTP_PORT and MPC_SERVER_GRPC_PORT are set per-service in systemd unit files +# Do NOT set them here as they are service-specific: +# session-coordinator: gRPC 50051, HTTP 8081 +# message-router: gRPC 50052, HTTP 8082 +# server-party-1/2/3: HTTP 8083/8084/8085 +# account-service: HTTP 8080 + +# Internal Service Addresses +SESSION_COORDINATOR_ADDR=localhost:50051 +MESSAGE_ROUTER_ADDR=localhost:50052 +EOF + + chmod 600 "$CONFIG_DIR/mpc.env" + chown "$MPC_USER:$MPC_GROUP" "$CONFIG_DIR/mpc.env" + + log_info "Environment file created with auto-generated secure keys" + log_info "Keys saved to: $CONFIG_DIR/mpc.env" + else + log_info "Environment file already exists" + fi +} + +# ============================================ +# Regenerate Keys (for existing installation) +# ============================================ +regenerate_keys() { + check_root + + log_info "Regenerating secure keys..." + + local MASTER_KEY=$(generate_random_hex_key) + local JWT_SECRET=$(generate_random_password) + local API_KEY=$(generate_random_password) + + if [ -f "$CONFIG_DIR/mpc.env" ]; then + # Replace CRYPTO_MASTER_KEY and MPC_CRYPTO_MASTER_KEY lines entirely + # This handles any existing value, not just specific placeholders + sed -i "s/^CRYPTO_MASTER_KEY=.*/CRYPTO_MASTER_KEY=${MASTER_KEY}/" "$CONFIG_DIR/mpc.env" + sed -i "s/^MPC_CRYPTO_MASTER_KEY=.*/MPC_CRYPTO_MASTER_KEY=${MASTER_KEY}/" "$CONFIG_DIR/mpc.env" + + # Replace JWT keys + sed -i "s/^JWT_SECRET_KEY=.*/JWT_SECRET_KEY=${JWT_SECRET}/" "$CONFIG_DIR/mpc.env" + sed -i "s/^MPC_JWT_SECRET_KEY=.*/MPC_JWT_SECRET_KEY=${JWT_SECRET}/" "$CONFIG_DIR/mpc.env" + + # Replace API key + sed -i "s/^MPC_API_KEY=.*/MPC_API_KEY=${API_KEY}/" "$CONFIG_DIR/mpc.env" + + log_info "Keys regenerated successfully" + log_info "New MASTER_KEY: ${MASTER_KEY:0:16}..." + log_info "New JWT_SECRET: ${JWT_SECRET:0:8}..." + log_info "New API_KEY: ${API_KEY:0:8}..." + log_info "" + log_info "Now reconfigure PostgreSQL with new password and restart services:" + log_info " $0 reconfigure" + log_info " $0 restart" + else + log_error "Environment file not found: $CONFIG_DIR/mpc.env" + exit 1 + fi +} + +# ============================================ +# Service Control Functions +# ============================================ +start_services() { + log_info "Starting MPC services..." + + # Start infrastructure first + systemctl start postgresql + systemctl start redis-server + systemctl start rabbitmq-server + + sleep 3 + + # Start MPC services in order + systemctl start mpc-session-coordinator + sleep 2 + systemctl start mpc-message-router + sleep 2 + systemctl start mpc-server-party-1 + systemctl start mpc-server-party-2 + systemctl start mpc-server-party-3 + sleep 2 + systemctl start mpc-account + + log_info "All services started" +} + +stop_services() { + log_info "Stopping MPC services..." + + systemctl stop mpc-account 2>/dev/null || true + systemctl stop mpc-server-party-1 2>/dev/null || true + systemctl stop mpc-server-party-2 2>/dev/null || true + systemctl stop mpc-server-party-3 2>/dev/null || true + systemctl stop mpc-message-router 2>/dev/null || true + systemctl stop mpc-session-coordinator 2>/dev/null || true + + log_info "All MPC services stopped" +} + +restart_services() { + stop_services + sleep 2 + start_services +} + +enable_services() { + log_info "Enabling MPC services to start on boot..." + + systemctl enable mpc-session-coordinator + systemctl enable mpc-message-router + systemctl enable mpc-server-party-1 + systemctl enable mpc-server-party-2 + systemctl enable mpc-server-party-3 + systemctl enable mpc-account + + log_info "Services enabled" +} + +status_services() { + echo "" + echo "============================================" + echo "MPC System Service Status" + echo "============================================" + echo "" + + # Infrastructure + echo "Infrastructure:" + echo " PostgreSQL: $(systemctl is-active postgresql)" + echo " Redis: $(systemctl is-active redis-server)" + echo " RabbitMQ: $(systemctl is-active rabbitmq-server)" + echo "" + + # MPC Services + echo "MPC Services:" + echo " Session Coordinator: $(systemctl is-active mpc-session-coordinator)" + echo " Message Router: $(systemctl is-active mpc-message-router)" + echo " Server Party 1: $(systemctl is-active mpc-server-party-1)" + echo " Server Party 2: $(systemctl is-active mpc-server-party-2)" + echo " Server Party 3: $(systemctl is-active mpc-server-party-3)" + echo " Account Service: $(systemctl is-active mpc-account)" + echo "" + + # Health check + echo "Health Check:" + if curl -s http://localhost:8080/health > /dev/null 2>&1; then + echo " Account Service API: ${GREEN}OK${NC}" + else + echo " Account Service API: ${RED}FAIL${NC}" + fi + echo "" +} + +view_logs() { + local SERVICE="${2:-mpc-account}" + echo "Viewing logs for $SERVICE..." + echo "Press Ctrl+C to exit" + echo "" + + if [ -f "$LOG_DIR/$SERVICE.log" ]; then + tail -f "$LOG_DIR/$SERVICE.log" + else + journalctl -u "$SERVICE" -f + fi +} + +# ============================================ +# Install Command +# ============================================ +install() { + check_root + + log_info "Starting MPC-System installation..." + + install_dependencies + setup_directories + create_env_config + + log_warn "Please edit the configuration file: $CONFIG_DIR/mpc.env" + log_warn "Then run: $0 build" +} + +build() { + check_root + + log_info "Building MPC-System..." + + build_services + create_systemd_services + configure_postgres + configure_redis + configure_rabbitmq + enable_services + + log_info "Build complete!" + log_info "Start services with: $0 start" +} + +# ============================================ +# Reconfigure Command (fix existing installation) +# ============================================ +reconfigure() { + check_root + + log_info "Reconfiguring MPC-System infrastructure..." + + configure_postgres + configure_redis + configure_rabbitmq + + log_info "Reconfiguration complete!" + log_info "Restart services with: $0 restart" +} + +# ============================================ +# Fix Port Conflicts (remove global port settings from mpc.env) +# ============================================ +fix_ports() { + check_root + + log_info "Fixing port configuration..." + + if [ ! -f "$CONFIG_DIR/mpc.env" ]; then + log_error "Environment file not found: $CONFIG_DIR/mpc.env" + exit 1 + fi + + # Remove MPC_SERVER_HTTP_PORT and MPC_SERVER_GRPC_PORT from mpc.env + # These should be set per-service in systemd unit files, not globally + if grep -q "^MPC_SERVER_HTTP_PORT=" "$CONFIG_DIR/mpc.env"; then + sed -i '/^MPC_SERVER_HTTP_PORT=/d' "$CONFIG_DIR/mpc.env" + log_info "Removed MPC_SERVER_HTTP_PORT from mpc.env" + fi + + if grep -q "^MPC_SERVER_GRPC_PORT=" "$CONFIG_DIR/mpc.env"; then + sed -i '/^MPC_SERVER_GRPC_PORT=/d' "$CONFIG_DIR/mpc.env" + log_info "Removed MPC_SERVER_GRPC_PORT from mpc.env" + fi + + # Add explanatory comment if not already present + if ! grep -q "# Port configuration is per-service" "$CONFIG_DIR/mpc.env"; then + cat >> "$CONFIG_DIR/mpc.env" << 'EOF' + +# Port configuration is per-service (set in systemd unit files): +# session-coordinator: gRPC 50051, HTTP 8081 +# message-router: gRPC 50052, HTTP 8082 +# server-party-1/2/3: HTTP 8083/8084/8085 +# account-service: HTTP 8080 +EOF + log_info "Added port documentation to mpc.env" + fi + + # Reload systemd and restart services + systemctl daemon-reload + + log_info "Port configuration fixed!" + log_info "Restart services with: $0 restart" +} + +# ============================================ +# Debug Command (troubleshooting) +# ============================================ +debug() { + echo "" + echo "============================================" + echo "MPC-System Debug Information" + echo "============================================" + echo "" + + # Load environment variables + if [ -f "$CONFIG_DIR/mpc.env" ]; then + source "$CONFIG_DIR/mpc.env" + log_info "Loaded environment from $CONFIG_DIR/mpc.env" + else + log_error "Environment file not found: $CONFIG_DIR/mpc.env" + return 1 + fi + + echo "" + echo "=== Environment Variables ===" + echo "MPC_DATABASE_HOST: ${MPC_DATABASE_HOST:-NOT SET}" + echo "MPC_DATABASE_PORT: ${MPC_DATABASE_PORT:-NOT SET}" + echo "MPC_DATABASE_USER: ${MPC_DATABASE_USER:-NOT SET}" + echo "MPC_DATABASE_PASSWORD: ${MPC_DATABASE_PASSWORD:+SET (hidden)}" + echo "MPC_DATABASE_DBNAME: ${MPC_DATABASE_DBNAME:-NOT SET}" + echo "SESSION_COORDINATOR_ADDR: ${SESSION_COORDINATOR_ADDR:-NOT SET}" + echo "MESSAGE_ROUTER_ADDR: ${MESSAGE_ROUTER_ADDR:-NOT SET}" + echo "" + + echo "=== PostgreSQL Connection Test ===" + local DB_USER="${MPC_DATABASE_USER:-mpc_user}" + local DB_PASS="${MPC_DATABASE_PASSWORD:-}" + local DB_NAME="${MPC_DATABASE_DBNAME:-mpc_system}" + local DB_HOST="${MPC_DATABASE_HOST:-localhost}" + + # Test PostgreSQL connection with password + echo "Testing connection to PostgreSQL..." + if PGPASSWORD="$DB_PASS" psql -h 127.0.0.1 -U "$DB_USER" -d "$DB_NAME" -c "SELECT 1;" > /dev/null 2>&1; then + echo " PostgreSQL connection: ${GREEN}OK${NC}" + else + echo " PostgreSQL connection: ${RED}FAILED${NC}" + echo "" + echo " Trying with verbose output:" + PGPASSWORD="$DB_PASS" psql -h 127.0.0.1 -U "$DB_USER" -d "$DB_NAME" -c "SELECT 1;" 2>&1 || true + echo "" + echo " Check pg_hba.conf authentication method:" + cat /etc/postgresql/*/main/pg_hba.conf 2>/dev/null | grep -v "^#" | grep -v "^$" | head -10 + fi + echo "" + + echo "=== Redis Connection Test ===" + if redis-cli ping > /dev/null 2>&1; then + echo " Redis connection: ${GREEN}OK${NC}" + else + echo " Redis connection: ${RED}FAILED${NC}" + fi + echo "" + + echo "=== RabbitMQ Connection Test ===" + if rabbitmqctl status > /dev/null 2>&1; then + echo " RabbitMQ status: ${GREEN}OK${NC}" + else + echo " RabbitMQ status: ${RED}FAILED${NC}" + fi + echo "" + + echo "=== Port Listening Status ===" + echo " PostgreSQL (5432): $(ss -tlnp | grep ':5432' > /dev/null && echo 'LISTENING' || echo 'NOT LISTENING')" + echo " Redis (6379): $(ss -tlnp | grep ':6379' > /dev/null && echo 'LISTENING' || echo 'NOT LISTENING')" + echo " RabbitMQ (5672): $(ss -tlnp | grep ':5672' > /dev/null && echo 'LISTENING' || echo 'NOT LISTENING')" + echo " Session Coordinator gRPC (50051): $(ss -tlnp | grep ':50051' > /dev/null && echo 'LISTENING' || echo 'NOT LISTENING')" + echo " Message Router gRPC (50052): $(ss -tlnp | grep ':50052' > /dev/null && echo 'LISTENING' || echo 'NOT LISTENING')" + echo " Account Service HTTP (8080): $(ss -tlnp | grep ':8080' > /dev/null && echo 'LISTENING' || echo 'NOT LISTENING')" + echo "" + + echo "=== Service Error Logs (last 10 lines) ===" + for service in mpc-session-coordinator mpc-message-router mpc-server-party-1 mpc-account; do + echo "" + echo "--- $service ---" + journalctl -u "$service" --no-pager -n 10 2>/dev/null || echo "No logs available" + done + echo "" + + echo "=== Manual Test Command ===" + echo "Run this command to manually test a service:" + echo "" + echo " sudo -u $MPC_USER bash -c 'source $CONFIG_DIR/mpc.env && $BIN_DIR/session-coordinator'" + echo "" +} + +# ============================================ +# Uninstall Command +# ============================================ +uninstall() { + check_root + + log_warn "This will remove all MPC services and data!" + read -p "Are you sure? (yes/no): " confirm + + if [ "$confirm" != "yes" ]; then + log_info "Uninstall cancelled" + exit 0 + fi + + stop_services + + # Disable and remove services + for service in mpc-account mpc-session-coordinator mpc-message-router mpc-server-party-1 mpc-server-party-2 mpc-server-party-3; do + systemctl disable "$service" 2>/dev/null || true + rm -f "/etc/systemd/system/$service.service" + done + + systemctl daemon-reload + + # Remove directories (keep data by default) + rm -rf "$BIN_DIR" "$PID_DIR" + + log_info "MPC services removed" + log_warn "Data directory preserved at: $DATA_DIR" + log_warn "Config directory preserved at: $CONFIG_DIR" + log_warn "To completely remove, run: rm -rf $MPC_HOME" +} + +# ============================================ +# Main +# ============================================ +case "${1:-}" in + install) + install + ;; + build) + build + ;; + reconfigure) + reconfigure + ;; + regenerate-keys) + regenerate_keys + ;; + fix-ports) + fix_ports + ;; + debug) + debug + ;; + start) + start_services + ;; + stop) + stop_services + ;; + restart) + restart_services + ;; + status) + status_services + ;; + logs) + view_logs "$@" + ;; + uninstall) + uninstall + ;; + *) + echo "MPC-System Deployment Script" + echo "" + echo "Usage: $0 {install|build|reconfigure|regenerate-keys|fix-ports|debug|start|stop|restart|status|logs|uninstall}" + echo "" + echo "Commands:" + echo " install - Install system dependencies (Go, PostgreSQL, Redis, RabbitMQ)" + echo " build - Build services and configure infrastructure" + echo " reconfigure - Reconfigure PostgreSQL/Redis/RabbitMQ (fix auth issues)" + echo " regenerate-keys - Regenerate secure keys (fix placeholder key issues)" + echo " fix-ports - Fix port conflicts (remove global port settings from mpc.env)" + echo " debug - Show debug information and test connections" + echo " start - Start all MPC services" + echo " stop - Stop all MPC services" + echo " restart - Restart all MPC services" + echo " status - Show service status" + echo " logs - View service logs (use: $0 logs [service-name])" + echo " uninstall - Remove MPC services" + echo "" + echo "Example:" + echo " $0 install # First time setup (auto-generates secure keys)" + echo " $0 build # Build and configure" + echo " $0 start # Start services" + echo " $0 status # Check status" + echo "" + echo "Troubleshooting:" + echo " $0 debug # Show debug info and test DB connection" + echo " $0 reconfigure # Fix database authentication issues" + echo " $0 regenerate-keys # Fix 'Invalid master key format' errors" + echo " $0 restart # Then restart services" + echo "" + exit 1 + ;; +esac diff --git a/backend/services/admin-service/deploy.sh b/backend/services/admin-service/deploy.sh index bdd8cbd5..4054ebc8 100755 --- a/backend/services/admin-service/deploy.sh +++ b/backend/services/admin-service/deploy.sh @@ -1,366 +1,366 @@ -#!/bin/bash -# ============================================================================= -# Admin Service - Deployment Script -# ============================================================================= -# 用法: ./deploy.sh -# ============================================================================= - -set -e - -SERVICE_NAME="admin-service" -CONTAINER_NAME="rwa-admin-service" -IMAGE_NAME="services-admin-service" -PORT=3010 -HEALTH_ENDPOINT="http://localhost:${PORT}/api/v1/health" - -# Colors -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -CYAN='\033[0;36m' -NC='\033[0m' - -log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } -log_success() { echo -e "${GREEN}[OK]${NC} $1"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } -log_error() { echo -e "${RED}[ERROR]${NC} $1"; } -log_step() { echo -e "${CYAN}[STEP]${NC} $1"; } - -# Get script directory -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -SERVICES_DIR="$(dirname "$SCRIPT_DIR")" - -# Load environment from parent services directory (shared .env) -load_env() { - if [ -f "$SERVICES_DIR/.env" ]; then - export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) - log_info "Loaded .env from $SERVICES_DIR" - elif [ -f "$SCRIPT_DIR/.env" ]; then - export $(cat "$SCRIPT_DIR/.env" | grep -v '^#' | xargs) - log_info "Loaded .env from $SCRIPT_DIR" - fi -} - -# Show banner -show_banner() { - echo -e "${CYAN}" - echo "╔═══════════════════════════════════════════════════════════════╗" - echo "║ Admin Service Deployment Script ║" - echo "║ Version Management API ║" - echo "╚═══════════════════════════════════════════════════════════════╝" - echo -e "${NC}" -} - -case "$1" in - # ========================================================================= - # Build Commands - # ========================================================================= - build) - show_banner - log_info "Building $SERVICE_NAME Docker image..." - docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - - build-no-cache) - show_banner - log_info "Building $SERVICE_NAME (no cache)..." - docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully (no cache)" - ;; - - # ========================================================================= - # Lifecycle Commands - # ========================================================================= - start) - show_banner - load_env - log_info "Starting $SERVICE_NAME using shared infrastructure..." - cd "$SERVICES_DIR" - docker compose up -d "$SERVICE_NAME" - log_success "$SERVICE_NAME started" - log_info "Waiting for service to be healthy..." - sleep 5 - "$SCRIPT_DIR/deploy.sh" health - ;; - - stop) - show_banner - log_info "Stopping $SERVICE_NAME..." - docker stop "$CONTAINER_NAME" 2>/dev/null || true - docker rm "$CONTAINER_NAME" 2>/dev/null || true - log_success "$SERVICE_NAME stopped" - ;; - - restart) - show_banner - "$SCRIPT_DIR/deploy.sh" stop - "$SCRIPT_DIR/deploy.sh" start - ;; - - up) - show_banner - load_env - log_info "Starting $SERVICE_NAME in foreground..." - cd "$SERVICES_DIR" - docker compose up "$SERVICE_NAME" - ;; - - down) - show_banner - log_info "Stopping $SERVICE_NAME container..." - docker stop "$CONTAINER_NAME" 2>/dev/null || true - docker rm "$CONTAINER_NAME" 2>/dev/null || true - log_success "$SERVICE_NAME container removed" - ;; - - # ========================================================================= - # Monitoring Commands - # ========================================================================= - logs) - docker logs -f "$CONTAINER_NAME" - ;; - - logs-tail) - docker logs --tail 100 "$CONTAINER_NAME" - ;; - - logs-all) - cd "$SERVICES_DIR" - docker compose logs -f "$SERVICE_NAME" - ;; - - status) - show_banner - log_info "Checking $SERVICE_NAME status..." - echo "" - if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - log_success "$SERVICE_NAME is running" - echo "" - docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" - else - log_warn "$SERVICE_NAME is not running" - fi - echo "" - log_info "All related containers:" - docker ps --filter "name=rwa-admin" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" - ;; - - health) - log_info "Checking health endpoint..." - if curl -sf "$HEALTH_ENDPOINT" > /dev/null 2>&1; then - log_success "Health check passed" - curl -s "$HEALTH_ENDPOINT" | jq . 2>/dev/null || curl -s "$HEALTH_ENDPOINT" - else - log_error "Health check failed" - exit 1 - fi - ;; - - # ========================================================================= - # Database Commands - # ========================================================================= - init-db) - show_banner - log_info "Creating database rwa_admin if not exists..." - docker exec rwa-postgres psql -U "${POSTGRES_USER:-rwa_user}" -c "CREATE DATABASE rwa_admin;" 2>/dev/null || log_warn "Database already exists" - log_success "Database ready" - log_info "Running migrations..." - "$SCRIPT_DIR/deploy.sh" migrate - ;; - - migrate) - show_banner - log_info "Running database migrations (production)..." - docker exec "$CONTAINER_NAME" npx prisma migrate deploy - log_success "Migrations completed" - ;; - - migrate-dev) - show_banner - log_info "Running database migrations (development)..." - docker exec -it "$CONTAINER_NAME" npx prisma migrate dev - log_success "Dev migrations completed" - ;; - - migrate-status) - log_info "Checking migration status..." - docker exec "$CONTAINER_NAME" npx prisma migrate status - ;; - - prisma-studio) - log_info "Starting Prisma Studio..." - log_warn "Make sure DATABASE_URL is set in your environment" - cd "$SCRIPT_DIR" - npx prisma studio - ;; - - db-push) - log_info "Pushing schema to database (development only)..." - docker exec "$CONTAINER_NAME" npx prisma db push - log_success "Schema pushed to database" - ;; - - db-seed) - log_info "Seeding database..." - docker exec "$CONTAINER_NAME" npx prisma db seed - log_success "Database seeded" - ;; - - # ========================================================================= - # Development Commands - # ========================================================================= - shell) - log_info "Entering $SERVICE_NAME container shell..." - docker exec -it "$CONTAINER_NAME" sh - ;; - - dev) - show_banner - log_info "Starting development mode..." - cd "$SCRIPT_DIR" - npm run start:dev - ;; - - test) - show_banner - log_info "Running tests..." - cd "$SCRIPT_DIR" - npm test - ;; - - test-unit) - log_info "Running unit tests..." - cd "$SCRIPT_DIR" - npm run test:unit - ;; - - test-integration) - log_info "Running integration tests..." - cd "$SCRIPT_DIR" - npm run test:integration - ;; - - test-e2e) - log_info "Running E2E tests..." - cd "$SCRIPT_DIR" - npm run test:e2e - ;; - - lint) - log_info "Running linter..." - cd "$SCRIPT_DIR" - npm run lint - ;; - - format) - log_info "Formatting code..." - cd "$SCRIPT_DIR" - npm run format - ;; - - # ========================================================================= - # Cleanup Commands - # ========================================================================= - clean) - show_banner - log_warn "Cleaning $SERVICE_NAME (removing containers)..." - "$SCRIPT_DIR/deploy.sh" stop - log_success "$SERVICE_NAME cleaned" - ;; - - clean-all) - show_banner - log_warn "Cleaning $SERVICE_NAME (removing container and image)..." - docker stop "$CONTAINER_NAME" 2>/dev/null || true - docker rm "$CONTAINER_NAME" 2>/dev/null || true - docker rmi "$IMAGE_NAME" 2>/dev/null || true - log_success "$SERVICE_NAME fully cleaned" - ;; - - prune) - show_banner - log_warn "Pruning unused Docker resources..." - docker system prune -f - log_success "Docker resources pruned" - ;; - - # ========================================================================= - # Info Commands - # ========================================================================= - info) - show_banner - echo -e "${CYAN}Service Information:${NC}" - echo " Name: $SERVICE_NAME" - echo " Container: $CONTAINER_NAME" - echo " Image: $IMAGE_NAME" - echo " Port: $PORT" - echo " Health: $HEALTH_ENDPOINT" - echo "" - echo -e "${CYAN}API Endpoints:${NC}" - echo " Health: GET /api/v1/health" - echo " Check Update: GET /api/v1/versions/check-update" - echo " Create: POST /api/v1/versions" - echo "" - echo -e "${CYAN}Environment Files:${NC}" - echo " .env.example - Template" - echo " .env.development - Local development" - echo " .env.production - Production (uses variable references)" - echo " .env.test - Testing" - ;; - - # ========================================================================= - # Help - # ========================================================================= - *) - show_banner - echo "Usage: $0 " - echo "" - echo -e "${CYAN}Build Commands:${NC}" - echo " build Build Docker image" - echo " build-no-cache Build Docker image without cache" - echo "" - echo -e "${CYAN}Lifecycle Commands:${NC}" - echo " start Start all services (detached)" - echo " stop Stop all services" - echo " restart Restart all services" - echo " up Start all services (foreground)" - echo " down Stop and remove all containers and volumes" - echo "" - echo -e "${CYAN}Monitoring Commands:${NC}" - echo " logs Follow service logs" - echo " logs-tail Show last 100 lines of logs" - echo " logs-all Follow all container logs" - echo " status Check service status" - echo " health Check health endpoint" - echo "" - echo -e "${CYAN}Database Commands:${NC}" - echo " init-db Create database and run migrations" - echo " migrate Run migrations (production)" - echo " migrate-dev Run migrations (development)" - echo " migrate-status Check migration status" - echo " prisma-studio Open Prisma Studio" - echo " db-push Push schema to database" - echo " db-seed Seed database" - echo "" - echo -e "${CYAN}Development Commands:${NC}" - echo " shell Enter container shell" - echo " dev Start in development mode" - echo " test Run all tests" - echo " test-unit Run unit tests" - echo " test-integration Run integration tests" - echo " test-e2e Run E2E tests" - echo " lint Run linter" - echo " format Format code" - echo "" - echo -e "${CYAN}Cleanup Commands:${NC}" - echo " clean Remove containers" - echo " clean-all Remove containers, volumes, and images" - echo " prune Prune unused Docker resources" - echo "" - echo -e "${CYAN}Info Commands:${NC}" - echo " info Show service information" - exit 1 - ;; -esac +#!/bin/bash +# ============================================================================= +# Admin Service - Deployment Script +# ============================================================================= +# 用法: ./deploy.sh +# ============================================================================= + +set -e + +SERVICE_NAME="admin-service" +CONTAINER_NAME="rwa-admin-service" +IMAGE_NAME="services-admin-service" +PORT=3010 +HEALTH_ENDPOINT="http://localhost:${PORT}/api/v1/health" + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +NC='\033[0m' + +log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } +log_success() { echo -e "${GREEN}[OK]${NC} $1"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } +log_step() { echo -e "${CYAN}[STEP]${NC} $1"; } + +# Get script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVICES_DIR="$(dirname "$SCRIPT_DIR")" + +# Load environment from parent services directory (shared .env) +load_env() { + if [ -f "$SERVICES_DIR/.env" ]; then + export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) + log_info "Loaded .env from $SERVICES_DIR" + elif [ -f "$SCRIPT_DIR/.env" ]; then + export $(cat "$SCRIPT_DIR/.env" | grep -v '^#' | xargs) + log_info "Loaded .env from $SCRIPT_DIR" + fi +} + +# Show banner +show_banner() { + echo -e "${CYAN}" + echo "╔═══════════════════════════════════════════════════════════════╗" + echo "║ Admin Service Deployment Script ║" + echo "║ Version Management API ║" + echo "╚═══════════════════════════════════════════════════════════════╝" + echo -e "${NC}" +} + +case "$1" in + # ========================================================================= + # Build Commands + # ========================================================================= + build) + show_banner + log_info "Building $SERVICE_NAME Docker image..." + docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + + build-no-cache) + show_banner + log_info "Building $SERVICE_NAME (no cache)..." + docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully (no cache)" + ;; + + # ========================================================================= + # Lifecycle Commands + # ========================================================================= + start) + show_banner + load_env + log_info "Starting $SERVICE_NAME using shared infrastructure..." + cd "$SERVICES_DIR" + docker compose up -d "$SERVICE_NAME" + log_success "$SERVICE_NAME started" + log_info "Waiting for service to be healthy..." + sleep 5 + "$SCRIPT_DIR/deploy.sh" health + ;; + + stop) + show_banner + log_info "Stopping $SERVICE_NAME..." + docker stop "$CONTAINER_NAME" 2>/dev/null || true + docker rm "$CONTAINER_NAME" 2>/dev/null || true + log_success "$SERVICE_NAME stopped" + ;; + + restart) + show_banner + "$SCRIPT_DIR/deploy.sh" stop + "$SCRIPT_DIR/deploy.sh" start + ;; + + up) + show_banner + load_env + log_info "Starting $SERVICE_NAME in foreground..." + cd "$SERVICES_DIR" + docker compose up "$SERVICE_NAME" + ;; + + down) + show_banner + log_info "Stopping $SERVICE_NAME container..." + docker stop "$CONTAINER_NAME" 2>/dev/null || true + docker rm "$CONTAINER_NAME" 2>/dev/null || true + log_success "$SERVICE_NAME container removed" + ;; + + # ========================================================================= + # Monitoring Commands + # ========================================================================= + logs) + docker logs -f "$CONTAINER_NAME" + ;; + + logs-tail) + docker logs --tail 100 "$CONTAINER_NAME" + ;; + + logs-all) + cd "$SERVICES_DIR" + docker compose logs -f "$SERVICE_NAME" + ;; + + status) + show_banner + log_info "Checking $SERVICE_NAME status..." + echo "" + if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + log_success "$SERVICE_NAME is running" + echo "" + docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" + else + log_warn "$SERVICE_NAME is not running" + fi + echo "" + log_info "All related containers:" + docker ps --filter "name=rwa-admin" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" + ;; + + health) + log_info "Checking health endpoint..." + if curl -sf "$HEALTH_ENDPOINT" > /dev/null 2>&1; then + log_success "Health check passed" + curl -s "$HEALTH_ENDPOINT" | jq . 2>/dev/null || curl -s "$HEALTH_ENDPOINT" + else + log_error "Health check failed" + exit 1 + fi + ;; + + # ========================================================================= + # Database Commands + # ========================================================================= + init-db) + show_banner + log_info "Creating database rwa_admin if not exists..." + docker exec rwa-postgres psql -U "${POSTGRES_USER:-rwa_user}" -c "CREATE DATABASE rwa_admin;" 2>/dev/null || log_warn "Database already exists" + log_success "Database ready" + log_info "Running migrations..." + "$SCRIPT_DIR/deploy.sh" migrate + ;; + + migrate) + show_banner + log_info "Running database migrations (production)..." + docker exec "$CONTAINER_NAME" npx prisma migrate deploy + log_success "Migrations completed" + ;; + + migrate-dev) + show_banner + log_info "Running database migrations (development)..." + docker exec -it "$CONTAINER_NAME" npx prisma migrate dev + log_success "Dev migrations completed" + ;; + + migrate-status) + log_info "Checking migration status..." + docker exec "$CONTAINER_NAME" npx prisma migrate status + ;; + + prisma-studio) + log_info "Starting Prisma Studio..." + log_warn "Make sure DATABASE_URL is set in your environment" + cd "$SCRIPT_DIR" + npx prisma studio + ;; + + db-push) + log_info "Pushing schema to database (development only)..." + docker exec "$CONTAINER_NAME" npx prisma db push + log_success "Schema pushed to database" + ;; + + db-seed) + log_info "Seeding database..." + docker exec "$CONTAINER_NAME" npx prisma db seed + log_success "Database seeded" + ;; + + # ========================================================================= + # Development Commands + # ========================================================================= + shell) + log_info "Entering $SERVICE_NAME container shell..." + docker exec -it "$CONTAINER_NAME" sh + ;; + + dev) + show_banner + log_info "Starting development mode..." + cd "$SCRIPT_DIR" + npm run start:dev + ;; + + test) + show_banner + log_info "Running tests..." + cd "$SCRIPT_DIR" + npm test + ;; + + test-unit) + log_info "Running unit tests..." + cd "$SCRIPT_DIR" + npm run test:unit + ;; + + test-integration) + log_info "Running integration tests..." + cd "$SCRIPT_DIR" + npm run test:integration + ;; + + test-e2e) + log_info "Running E2E tests..." + cd "$SCRIPT_DIR" + npm run test:e2e + ;; + + lint) + log_info "Running linter..." + cd "$SCRIPT_DIR" + npm run lint + ;; + + format) + log_info "Formatting code..." + cd "$SCRIPT_DIR" + npm run format + ;; + + # ========================================================================= + # Cleanup Commands + # ========================================================================= + clean) + show_banner + log_warn "Cleaning $SERVICE_NAME (removing containers)..." + "$SCRIPT_DIR/deploy.sh" stop + log_success "$SERVICE_NAME cleaned" + ;; + + clean-all) + show_banner + log_warn "Cleaning $SERVICE_NAME (removing container and image)..." + docker stop "$CONTAINER_NAME" 2>/dev/null || true + docker rm "$CONTAINER_NAME" 2>/dev/null || true + docker rmi "$IMAGE_NAME" 2>/dev/null || true + log_success "$SERVICE_NAME fully cleaned" + ;; + + prune) + show_banner + log_warn "Pruning unused Docker resources..." + docker system prune -f + log_success "Docker resources pruned" + ;; + + # ========================================================================= + # Info Commands + # ========================================================================= + info) + show_banner + echo -e "${CYAN}Service Information:${NC}" + echo " Name: $SERVICE_NAME" + echo " Container: $CONTAINER_NAME" + echo " Image: $IMAGE_NAME" + echo " Port: $PORT" + echo " Health: $HEALTH_ENDPOINT" + echo "" + echo -e "${CYAN}API Endpoints:${NC}" + echo " Health: GET /api/v1/health" + echo " Check Update: GET /api/v1/versions/check-update" + echo " Create: POST /api/v1/versions" + echo "" + echo -e "${CYAN}Environment Files:${NC}" + echo " .env.example - Template" + echo " .env.development - Local development" + echo " .env.production - Production (uses variable references)" + echo " .env.test - Testing" + ;; + + # ========================================================================= + # Help + # ========================================================================= + *) + show_banner + echo "Usage: $0 " + echo "" + echo -e "${CYAN}Build Commands:${NC}" + echo " build Build Docker image" + echo " build-no-cache Build Docker image without cache" + echo "" + echo -e "${CYAN}Lifecycle Commands:${NC}" + echo " start Start all services (detached)" + echo " stop Stop all services" + echo " restart Restart all services" + echo " up Start all services (foreground)" + echo " down Stop and remove all containers and volumes" + echo "" + echo -e "${CYAN}Monitoring Commands:${NC}" + echo " logs Follow service logs" + echo " logs-tail Show last 100 lines of logs" + echo " logs-all Follow all container logs" + echo " status Check service status" + echo " health Check health endpoint" + echo "" + echo -e "${CYAN}Database Commands:${NC}" + echo " init-db Create database and run migrations" + echo " migrate Run migrations (production)" + echo " migrate-dev Run migrations (development)" + echo " migrate-status Check migration status" + echo " prisma-studio Open Prisma Studio" + echo " db-push Push schema to database" + echo " db-seed Seed database" + echo "" + echo -e "${CYAN}Development Commands:${NC}" + echo " shell Enter container shell" + echo " dev Start in development mode" + echo " test Run all tests" + echo " test-unit Run unit tests" + echo " test-integration Run integration tests" + echo " test-e2e Run E2E tests" + echo " lint Run linter" + echo " format Format code" + echo "" + echo -e "${CYAN}Cleanup Commands:${NC}" + echo " clean Remove containers" + echo " clean-all Remove containers, volumes, and images" + echo " prune Prune unused Docker resources" + echo "" + echo -e "${CYAN}Info Commands:${NC}" + echo " info Show service information" + exit 1 + ;; +esac diff --git a/backend/services/authorization-service/deploy.sh b/backend/services/authorization-service/deploy.sh index fd52b303..3f1dd479 100755 --- a/backend/services/authorization-service/deploy.sh +++ b/backend/services/authorization-service/deploy.sh @@ -1,94 +1,94 @@ -#!/bin/bash -# ============================================================================= -# Authorization Service - Individual Deployment Script -# ============================================================================= - -set -e - -SERVICE_NAME="authorization-service" -CONTAINER_NAME="rwa-authorization-service" -IMAGE_NAME="services-authorization-service" -PORT=3009 - -# 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}[OK]${NC} $1"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } -log_error() { echo -e "${RED}[ERROR]${NC} $1"; } - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -SERVICES_DIR="$(dirname "$SCRIPT_DIR")" - -if [ -f "$SERVICES_DIR/.env" ]; then - export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) -fi - -case "$1" in - build) - log_info "Building $SERVICE_NAME..." - docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - build-no-cache) - log_info "Building $SERVICE_NAME (no cache)..." - docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - start) - log_info "Starting $SERVICE_NAME..." - cd "$SERVICES_DIR" - docker compose up -d "$SERVICE_NAME" - log_success "$SERVICE_NAME started" - ;; - stop) - log_info "Stopping $SERVICE_NAME..." - docker stop "$CONTAINER_NAME" 2>/dev/null || true - docker rm "$CONTAINER_NAME" 2>/dev/null || true - log_success "$SERVICE_NAME stopped" - ;; - restart) - $0 stop - $0 start - ;; - logs) - docker logs -f "$CONTAINER_NAME" - ;; - logs-tail) - docker logs --tail 100 "$CONTAINER_NAME" - ;; - status) - if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - log_success "$SERVICE_NAME is running" - docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" - else - log_warn "$SERVICE_NAME is not running" - fi - ;; - health) - log_info "Checking health of $SERVICE_NAME..." - if curl -sf "http://localhost:$PORT/health" > /dev/null 2>&1; then - log_success "$SERVICE_NAME is healthy" - else - log_error "$SERVICE_NAME health check failed" - exit 1 - fi - ;; - migrate) - log_info "Running migrations for $SERVICE_NAME..." - docker exec "$CONTAINER_NAME" npx prisma migrate deploy - log_success "Migrations completed" - ;; - shell) - docker exec -it "$CONTAINER_NAME" sh - ;; - *) - echo "Usage: $0 {build|build-no-cache|start|stop|restart|logs|logs-tail|status|health|migrate|shell}" - exit 1 - ;; -esac +#!/bin/bash +# ============================================================================= +# Authorization Service - Individual Deployment Script +# ============================================================================= + +set -e + +SERVICE_NAME="authorization-service" +CONTAINER_NAME="rwa-authorization-service" +IMAGE_NAME="services-authorization-service" +PORT=3009 + +# 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}[OK]${NC} $1"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVICES_DIR="$(dirname "$SCRIPT_DIR")" + +if [ -f "$SERVICES_DIR/.env" ]; then + export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) +fi + +case "$1" in + build) + log_info "Building $SERVICE_NAME..." + docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + build-no-cache) + log_info "Building $SERVICE_NAME (no cache)..." + docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + start) + log_info "Starting $SERVICE_NAME..." + cd "$SERVICES_DIR" + docker compose up -d "$SERVICE_NAME" + log_success "$SERVICE_NAME started" + ;; + stop) + log_info "Stopping $SERVICE_NAME..." + docker stop "$CONTAINER_NAME" 2>/dev/null || true + docker rm "$CONTAINER_NAME" 2>/dev/null || true + log_success "$SERVICE_NAME stopped" + ;; + restart) + $0 stop + $0 start + ;; + logs) + docker logs -f "$CONTAINER_NAME" + ;; + logs-tail) + docker logs --tail 100 "$CONTAINER_NAME" + ;; + status) + if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + log_success "$SERVICE_NAME is running" + docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" + else + log_warn "$SERVICE_NAME is not running" + fi + ;; + health) + log_info "Checking health of $SERVICE_NAME..." + if curl -sf "http://localhost:$PORT/health" > /dev/null 2>&1; then + log_success "$SERVICE_NAME is healthy" + else + log_error "$SERVICE_NAME health check failed" + exit 1 + fi + ;; + migrate) + log_info "Running migrations for $SERVICE_NAME..." + docker exec "$CONTAINER_NAME" npx prisma migrate deploy + log_success "Migrations completed" + ;; + shell) + docker exec -it "$CONTAINER_NAME" sh + ;; + *) + echo "Usage: $0 {build|build-no-cache|start|stop|restart|logs|logs-tail|status|health|migrate|shell}" + exit 1 + ;; +esac diff --git a/backend/services/identity-service/package-lock.json b/backend/services/identity-service/package-lock.json index 81d34618..e129442e 100644 --- a/backend/services/identity-service/package-lock.json +++ b/backend/services/identity-service/package-lock.json @@ -259,7 +259,6 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -1763,7 +1762,6 @@ "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.4.20.tgz", "integrity": "sha512-hxJxZF7jcKGuUzM9EYbuES80Z/36piJbiqmPy86mk8qOn5gglFebBTvcx7PWVbRNSb4gngASYnefBj/Y2HAzpQ==", "license": "MIT", - "peer": true, "dependencies": { "file-type": "20.4.1", "iterare": "1.2.1", @@ -1810,7 +1808,6 @@ "integrity": "sha512-kRdtyKA3+Tu70N3RQ4JgmO1E3LzAMs/eppj7SfjabC7TgqNWoS4RLhWl4BqmsNVmjj6D5jgfPVtHtgYkU3AfpQ==", "hasInstallScript": true, "license": "MIT", - "peer": true, "dependencies": { "@nuxtjs/opencollective": "0.3.2", "fast-safe-stringify": "2.1.1", @@ -1890,7 +1887,6 @@ "resolved": "https://registry.npmjs.org/@nestjs/microservices/-/microservices-10.4.20.tgz", "integrity": "sha512-zu/o84Z0uTUClNnGIGfIjcrO3z6T60h/pZPSJK50o4mehbEvJ76fijj6R/WTW0VP+1N16qOv/NsiYLKJA5Cc3w==", "license": "MIT", - "peer": true, "dependencies": { "iterare": "1.2.1", "tslib": "2.8.1" @@ -1959,7 +1955,6 @@ "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.4.20.tgz", "integrity": "sha512-rh97mX3rimyf4xLMLHuTOBKe6UD8LOJ14VlJ1F/PTd6C6ZK9Ak6EHuJvdaGcSFQhd3ZMBh3I6CuujKGW9pNdIg==", "license": "MIT", - "peer": true, "dependencies": { "body-parser": "1.20.3", "cors": "2.8.5", @@ -2467,7 +2462,6 @@ "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -2622,7 +2616,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz", "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~6.21.0" } @@ -2816,7 +2809,6 @@ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", @@ -3174,7 +3166,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3188,6 +3179,7 @@ "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10.13.0" }, @@ -3230,7 +3222,6 @@ "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -3708,7 +3699,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", @@ -3987,15 +3977,13 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz", "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/class-validator": { "version": "0.14.3", "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.3.tgz", "integrity": "sha512-rXXekcjofVN1LTOSw+u4u9WXVEUvNBVjORW154q/IdmYWy1nMbOU9aNtZB0t8m+FJQ9q91jlr2f9CwwUFdFMRA==", "license": "MIT", - "peer": true, "dependencies": { "@types/validator": "^13.15.3", "libphonenumber-js": "^1.11.1", @@ -4759,7 +4747,6 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -4816,7 +4803,6 @@ "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -5485,6 +5471,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=4.0" }, @@ -6142,7 +6129,6 @@ "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.8.2.tgz", "integrity": "sha512-C6uC+kleiIMmjViJINWk80sOQw5lEzse1ZmvD+S/s8p8CWapftSaC+kocGTx6xrbrJ4WmYQGC08ffHLr6ToR6Q==", "license": "MIT", - "peer": true, "dependencies": { "@ioredis/commands": "1.4.0", "cluster-key-slot": "^1.1.0", @@ -6425,7 +6411,6 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -7270,7 +7255,6 @@ "resolved": "https://registry.npmjs.org/kafkajs/-/kafkajs-2.2.4.tgz", "integrity": "sha512-j/YeapB1vfPT2iOIUn/vxdyKEuhuY2PxMBvf5JWux6iSaukAccrMtXEY/Lb7OvavDhOWME589bpLrEdnVHjfjA==", "license": "MIT", - "peer": true, "engines": { "node": ">=14.0.0" } @@ -8147,7 +8131,8 @@ "node_modules/pause": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", - "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" + "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==", + "peer": true }, "node_modules/picocolors": { "version": "1.1.1", @@ -8274,7 +8259,6 @@ "integrity": "sha512-QgODejq9K3OzoBbuyobZlUhznP5SKwPqp+6Q6xw6o8gnhr4O85L2U915iM2IDcfF2NPXVaM9zlo9tdwipnYwzg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -8333,7 +8317,6 @@ "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@prisma/engines": "5.22.0" }, @@ -8378,7 +8361,8 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/punycode": { "version": "2.3.1", @@ -8549,8 +8533,7 @@ "version": "0.1.14", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==", - "license": "Apache-2.0", - "peer": true + "license": "Apache-2.0" }, "node_modules/repeat-string": { "version": "1.6.1", @@ -8780,7 +8763,6 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "license": "Apache-2.0", - "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -8836,7 +8818,6 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -9804,7 +9785,6 @@ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -9951,7 +9931,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10248,6 +10227,7 @@ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -10262,6 +10242,7 @@ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "engines": { "node": ">=4.0" } @@ -10272,6 +10253,7 @@ "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", diff --git a/backend/services/leaderboard-service/deploy.sh b/backend/services/leaderboard-service/deploy.sh index f6258caa..63e5aea4 100755 --- a/backend/services/leaderboard-service/deploy.sh +++ b/backend/services/leaderboard-service/deploy.sh @@ -1,94 +1,94 @@ -#!/bin/bash -# ============================================================================= -# Leaderboard Service - Individual Deployment Script -# ============================================================================= - -set -e - -SERVICE_NAME="leaderboard-service" -CONTAINER_NAME="rwa-leaderboard-service" -IMAGE_NAME="services-leaderboard-service" -PORT=3007 - -# 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}[OK]${NC} $1"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } -log_error() { echo -e "${RED}[ERROR]${NC} $1"; } - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -SERVICES_DIR="$(dirname "$SCRIPT_DIR")" - -if [ -f "$SERVICES_DIR/.env" ]; then - export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) -fi - -case "$1" in - build) - log_info "Building $SERVICE_NAME..." - docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - build-no-cache) - log_info "Building $SERVICE_NAME (no cache)..." - docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - start) - log_info "Starting $SERVICE_NAME..." - cd "$SERVICES_DIR" - docker compose up -d "$SERVICE_NAME" - log_success "$SERVICE_NAME started" - ;; - stop) - log_info "Stopping $SERVICE_NAME..." - docker stop "$CONTAINER_NAME" 2>/dev/null || true - docker rm "$CONTAINER_NAME" 2>/dev/null || true - log_success "$SERVICE_NAME stopped" - ;; - restart) - $0 stop - $0 start - ;; - logs) - docker logs -f "$CONTAINER_NAME" - ;; - logs-tail) - docker logs --tail 100 "$CONTAINER_NAME" - ;; - status) - if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - log_success "$SERVICE_NAME is running" - docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" - else - log_warn "$SERVICE_NAME is not running" - fi - ;; - health) - log_info "Checking health of $SERVICE_NAME..." - if curl -sf "http://localhost:$PORT/health" > /dev/null 2>&1; then - log_success "$SERVICE_NAME is healthy" - else - log_error "$SERVICE_NAME health check failed" - exit 1 - fi - ;; - migrate) - log_info "Running migrations for $SERVICE_NAME..." - docker exec "$CONTAINER_NAME" npx prisma migrate deploy - log_success "Migrations completed" - ;; - shell) - docker exec -it "$CONTAINER_NAME" sh - ;; - *) - echo "Usage: $0 {build|build-no-cache|start|stop|restart|logs|logs-tail|status|health|migrate|shell}" - exit 1 - ;; -esac +#!/bin/bash +# ============================================================================= +# Leaderboard Service - Individual Deployment Script +# ============================================================================= + +set -e + +SERVICE_NAME="leaderboard-service" +CONTAINER_NAME="rwa-leaderboard-service" +IMAGE_NAME="services-leaderboard-service" +PORT=3007 + +# 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}[OK]${NC} $1"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVICES_DIR="$(dirname "$SCRIPT_DIR")" + +if [ -f "$SERVICES_DIR/.env" ]; then + export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) +fi + +case "$1" in + build) + log_info "Building $SERVICE_NAME..." + docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + build-no-cache) + log_info "Building $SERVICE_NAME (no cache)..." + docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + start) + log_info "Starting $SERVICE_NAME..." + cd "$SERVICES_DIR" + docker compose up -d "$SERVICE_NAME" + log_success "$SERVICE_NAME started" + ;; + stop) + log_info "Stopping $SERVICE_NAME..." + docker stop "$CONTAINER_NAME" 2>/dev/null || true + docker rm "$CONTAINER_NAME" 2>/dev/null || true + log_success "$SERVICE_NAME stopped" + ;; + restart) + $0 stop + $0 start + ;; + logs) + docker logs -f "$CONTAINER_NAME" + ;; + logs-tail) + docker logs --tail 100 "$CONTAINER_NAME" + ;; + status) + if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + log_success "$SERVICE_NAME is running" + docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" + else + log_warn "$SERVICE_NAME is not running" + fi + ;; + health) + log_info "Checking health of $SERVICE_NAME..." + if curl -sf "http://localhost:$PORT/health" > /dev/null 2>&1; then + log_success "$SERVICE_NAME is healthy" + else + log_error "$SERVICE_NAME health check failed" + exit 1 + fi + ;; + migrate) + log_info "Running migrations for $SERVICE_NAME..." + docker exec "$CONTAINER_NAME" npx prisma migrate deploy + log_success "Migrations completed" + ;; + shell) + docker exec -it "$CONTAINER_NAME" sh + ;; + *) + echo "Usage: $0 {build|build-no-cache|start|stop|restart|logs|logs-tail|status|health|migrate|shell}" + exit 1 + ;; +esac diff --git a/backend/services/planting-service/deploy.sh b/backend/services/planting-service/deploy.sh index eb91ff31..aa5590c9 100755 --- a/backend/services/planting-service/deploy.sh +++ b/backend/services/planting-service/deploy.sh @@ -1,94 +1,94 @@ -#!/bin/bash -# ============================================================================= -# Planting Service - Individual Deployment Script -# ============================================================================= - -set -e - -SERVICE_NAME="planting-service" -CONTAINER_NAME="rwa-planting-service" -IMAGE_NAME="services-planting-service" -PORT=3003 - -# 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}[OK]${NC} $1"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } -log_error() { echo -e "${RED}[ERROR]${NC} $1"; } - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -SERVICES_DIR="$(dirname "$SCRIPT_DIR")" - -if [ -f "$SERVICES_DIR/.env" ]; then - export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) -fi - -case "$1" in - build) - log_info "Building $SERVICE_NAME..." - docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - build-no-cache) - log_info "Building $SERVICE_NAME (no cache)..." - docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - start) - log_info "Starting $SERVICE_NAME..." - cd "$SERVICES_DIR" - docker compose up -d "$SERVICE_NAME" - log_success "$SERVICE_NAME started" - ;; - stop) - log_info "Stopping $SERVICE_NAME..." - docker stop "$CONTAINER_NAME" 2>/dev/null || true - docker rm "$CONTAINER_NAME" 2>/dev/null || true - log_success "$SERVICE_NAME stopped" - ;; - restart) - $0 stop - $0 start - ;; - logs) - docker logs -f "$CONTAINER_NAME" - ;; - logs-tail) - docker logs --tail 100 "$CONTAINER_NAME" - ;; - status) - if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - log_success "$SERVICE_NAME is running" - docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" - else - log_warn "$SERVICE_NAME is not running" - fi - ;; - health) - log_info "Checking health of $SERVICE_NAME..." - if curl -sf "http://localhost:$PORT/api/v1/health" > /dev/null 2>&1; then - log_success "$SERVICE_NAME is healthy" - else - log_error "$SERVICE_NAME health check failed" - exit 1 - fi - ;; - migrate) - log_info "Running migrations for $SERVICE_NAME..." - docker exec "$CONTAINER_NAME" npx prisma migrate deploy - log_success "Migrations completed" - ;; - shell) - docker exec -it "$CONTAINER_NAME" sh - ;; - *) - echo "Usage: $0 {build|build-no-cache|start|stop|restart|logs|logs-tail|status|health|migrate|shell}" - exit 1 - ;; -esac +#!/bin/bash +# ============================================================================= +# Planting Service - Individual Deployment Script +# ============================================================================= + +set -e + +SERVICE_NAME="planting-service" +CONTAINER_NAME="rwa-planting-service" +IMAGE_NAME="services-planting-service" +PORT=3003 + +# 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}[OK]${NC} $1"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVICES_DIR="$(dirname "$SCRIPT_DIR")" + +if [ -f "$SERVICES_DIR/.env" ]; then + export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) +fi + +case "$1" in + build) + log_info "Building $SERVICE_NAME..." + docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + build-no-cache) + log_info "Building $SERVICE_NAME (no cache)..." + docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + start) + log_info "Starting $SERVICE_NAME..." + cd "$SERVICES_DIR" + docker compose up -d "$SERVICE_NAME" + log_success "$SERVICE_NAME started" + ;; + stop) + log_info "Stopping $SERVICE_NAME..." + docker stop "$CONTAINER_NAME" 2>/dev/null || true + docker rm "$CONTAINER_NAME" 2>/dev/null || true + log_success "$SERVICE_NAME stopped" + ;; + restart) + $0 stop + $0 start + ;; + logs) + docker logs -f "$CONTAINER_NAME" + ;; + logs-tail) + docker logs --tail 100 "$CONTAINER_NAME" + ;; + status) + if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + log_success "$SERVICE_NAME is running" + docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" + else + log_warn "$SERVICE_NAME is not running" + fi + ;; + health) + log_info "Checking health of $SERVICE_NAME..." + if curl -sf "http://localhost:$PORT/api/v1/health" > /dev/null 2>&1; then + log_success "$SERVICE_NAME is healthy" + else + log_error "$SERVICE_NAME health check failed" + exit 1 + fi + ;; + migrate) + log_info "Running migrations for $SERVICE_NAME..." + docker exec "$CONTAINER_NAME" npx prisma migrate deploy + log_success "Migrations completed" + ;; + shell) + docker exec -it "$CONTAINER_NAME" sh + ;; + *) + echo "Usage: $0 {build|build-no-cache|start|stop|restart|logs|logs-tail|status|health|migrate|shell}" + exit 1 + ;; +esac diff --git a/backend/services/presence-service/deploy.sh b/backend/services/presence-service/deploy.sh index 05d3e148..80e5aa59 100755 --- a/backend/services/presence-service/deploy.sh +++ b/backend/services/presence-service/deploy.sh @@ -1,253 +1,253 @@ -#!/bin/bash -# ============================================================================= -# Presence Service - Individual Deployment Script -# ============================================================================= -# Uses shared infrastructure from main docker-compose.yml -# ============================================================================= - -set -e - -SERVICE_NAME="presence-service" -CONTAINER_NAME="rwa-presence-service" -IMAGE_NAME="services-presence-service" -PORT=3011 -HEALTH_ENDPOINT="http://localhost:${PORT}/api/v1/health" - -# 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}[OK]${NC} $1"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } -log_error() { echo -e "${RED}[ERROR]${NC} $1"; } - -# Get script directory -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -SERVICES_DIR="$(dirname "$SCRIPT_DIR")" - -# Load environment from parent services directory (shared .env) -load_env() { - if [ -f "$SERVICES_DIR/.env" ]; then - export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) - log_info "Loaded .env from $SERVICES_DIR" - elif [ -f "$SCRIPT_DIR/.env.production" ]; then - export $(cat "$SCRIPT_DIR/.env.production" | grep -v '^#' | xargs) - log_info "Loaded .env.production from $SCRIPT_DIR" - fi -} - -case "$1" in - build) - log_info "Building $SERVICE_NAME..." - docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - - build-no-cache) - log_info "Building $SERVICE_NAME (no cache)..." - docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - - start) - load_env - log_info "Starting $SERVICE_NAME using shared infrastructure..." - cd "$SERVICES_DIR" - # Use --no-deps to avoid recreating infrastructure that's already running - docker compose up -d --no-deps "$SERVICE_NAME" - log_success "$SERVICE_NAME started" - log_info "Waiting for service to be healthy..." - sleep 5 - bash "$SCRIPT_DIR/deploy.sh" health - ;; - - start-deps) - log_info "Starting dependencies only (for local development)..." - cd "$SCRIPT_DIR" - docker compose -f docker-compose.dev.yml up -d - log_success "Dependencies started" - ;; - - stop) - log_info "Stopping $SERVICE_NAME..." - docker stop "$CONTAINER_NAME" 2>/dev/null || true - docker rm "$CONTAINER_NAME" 2>/dev/null || true - log_success "$SERVICE_NAME stopped" - ;; - - stop-deps) - log_info "Stopping dependencies..." - cd "$SCRIPT_DIR" - docker compose -f docker-compose.dev.yml down - log_success "Dependencies stopped" - ;; - - restart) - bash "$SCRIPT_DIR/deploy.sh" stop - bash "$SCRIPT_DIR/deploy.sh" start - ;; - - up) - load_env - log_info "Starting $SERVICE_NAME in foreground..." - cd "$SERVICES_DIR" - # Use --no-deps to avoid recreating infrastructure that's already running - docker compose up --no-deps "$SERVICE_NAME" - ;; - - logs) - docker logs -f "$CONTAINER_NAME" - ;; - - logs-tail) - docker logs --tail 100 "$CONTAINER_NAME" - ;; - - logs-all) - cd "$SERVICES_DIR" - docker compose logs -f "$SERVICE_NAME" - ;; - - status) - if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - log_success "$SERVICE_NAME is running" - docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" - else - log_warn "$SERVICE_NAME is not running" - fi - ;; - - health) - log_info "Checking health of $SERVICE_NAME..." - if curl -sf "$HEALTH_ENDPOINT" > /dev/null 2>&1; then - HEALTH=$(curl -s "$HEALTH_ENDPOINT") - log_success "$SERVICE_NAME is healthy" - echo "$HEALTH" | jq . 2>/dev/null || echo "$HEALTH" - else - log_error "$SERVICE_NAME health check failed" - exit 1 - fi - ;; - - init-db) - log_info "Creating database rwa_presence..." - docker exec rwa-postgres psql -U rwa_user -d postgres -c "CREATE DATABASE rwa_presence;" 2>/dev/null || \ - log_warn "Database may already exist" - log_success "Database rwa_presence created (or already exists)" - log_info "Running Prisma db push to create tables..." - docker exec "$CONTAINER_NAME" npx prisma db push --skip-generate 2>/dev/null || \ - log_warn "Could not push schema (container may not be running)" - ;; - - migrate) - log_info "Running migrations for $SERVICE_NAME..." - docker exec "$CONTAINER_NAME" npx prisma migrate deploy - log_success "Migrations completed" - ;; - - migrate-dev) - log_info "Running dev migrations for $SERVICE_NAME..." - docker exec "$CONTAINER_NAME" npx prisma migrate dev - ;; - - db-push) - log_info "Pushing schema to database..." - docker exec "$CONTAINER_NAME" npx prisma db push - log_success "Schema pushed" - ;; - - prisma-studio) - log_info "Starting Prisma Studio..." - docker exec -it "$CONTAINER_NAME" npx prisma studio - ;; - - shell) - log_info "Opening shell in $SERVICE_NAME container..." - docker exec -it "$CONTAINER_NAME" sh - ;; - - test) - log_info "Running tests for $SERVICE_NAME..." - cd "$SCRIPT_DIR" - npm test - ;; - - test-unit) - log_info "Running unit tests..." - cd "$SCRIPT_DIR" - npm run test:unit - ;; - - test-integration) - log_info "Running integration tests..." - cd "$SCRIPT_DIR" - npm run test:integration - ;; - - test-e2e) - log_info "Running E2E tests..." - cd "$SCRIPT_DIR" - npm run test:e2e - ;; - - clean) - log_info "Cleaning up..." - docker stop "$CONTAINER_NAME" 2>/dev/null || true - docker rm "$CONTAINER_NAME" 2>/dev/null || true - log_success "Cleanup completed" - ;; - - clean-all) - log_info "Cleaning $SERVICE_NAME (removing container and image)..." - docker stop "$CONTAINER_NAME" 2>/dev/null || true - docker rm "$CONTAINER_NAME" 2>/dev/null || true - docker rmi "$IMAGE_NAME" 2>/dev/null || true - log_success "$SERVICE_NAME fully cleaned" - ;; - - *) - echo "Usage: $0 {command}" - echo "" - echo "Build Commands:" - echo " build - Build Docker image" - echo " build-no-cache - Build Docker image without cache" - echo "" - echo "Service Commands:" - echo " start - Start using shared infrastructure" - echo " start-deps - Start dependencies only (for local development)" - echo " stop - Stop the service container" - echo " stop-deps - Stop dependencies only" - echo " restart - Restart the service" - echo " up - Start in foreground mode" - echo "" - echo "Monitoring Commands:" - echo " logs - Follow logs" - echo " logs-tail - Show last 100 log lines" - echo " logs-all - Follow logs via docker compose" - echo " status - Show service status" - echo " health - Check service health" - echo "" - echo "Database Commands:" - echo " init-db - Create database and push schema" - echo " migrate - Run database migrations (production)" - echo " migrate-dev - Run dev migrations" - echo " db-push - Push Prisma schema to database" - echo " prisma-studio - Open Prisma Studio" - echo "" - echo "Development Commands:" - echo " shell - Open shell in container" - echo " test - Run all tests" - echo " test-unit - Run unit tests only" - echo " test-integration - Run integration tests only" - echo " test-e2e - Run E2E tests only" - echo "" - echo "Maintenance Commands:" - echo " clean - Remove container" - echo " clean-all - Remove container and image" - exit 1 - ;; -esac +#!/bin/bash +# ============================================================================= +# Presence Service - Individual Deployment Script +# ============================================================================= +# Uses shared infrastructure from main docker-compose.yml +# ============================================================================= + +set -e + +SERVICE_NAME="presence-service" +CONTAINER_NAME="rwa-presence-service" +IMAGE_NAME="services-presence-service" +PORT=3011 +HEALTH_ENDPOINT="http://localhost:${PORT}/api/v1/health" + +# 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}[OK]${NC} $1"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +# Get script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVICES_DIR="$(dirname "$SCRIPT_DIR")" + +# Load environment from parent services directory (shared .env) +load_env() { + if [ -f "$SERVICES_DIR/.env" ]; then + export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) + log_info "Loaded .env from $SERVICES_DIR" + elif [ -f "$SCRIPT_DIR/.env.production" ]; then + export $(cat "$SCRIPT_DIR/.env.production" | grep -v '^#' | xargs) + log_info "Loaded .env.production from $SCRIPT_DIR" + fi +} + +case "$1" in + build) + log_info "Building $SERVICE_NAME..." + docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + + build-no-cache) + log_info "Building $SERVICE_NAME (no cache)..." + docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + + start) + load_env + log_info "Starting $SERVICE_NAME using shared infrastructure..." + cd "$SERVICES_DIR" + # Use --no-deps to avoid recreating infrastructure that's already running + docker compose up -d --no-deps "$SERVICE_NAME" + log_success "$SERVICE_NAME started" + log_info "Waiting for service to be healthy..." + sleep 5 + bash "$SCRIPT_DIR/deploy.sh" health + ;; + + start-deps) + log_info "Starting dependencies only (for local development)..." + cd "$SCRIPT_DIR" + docker compose -f docker-compose.dev.yml up -d + log_success "Dependencies started" + ;; + + stop) + log_info "Stopping $SERVICE_NAME..." + docker stop "$CONTAINER_NAME" 2>/dev/null || true + docker rm "$CONTAINER_NAME" 2>/dev/null || true + log_success "$SERVICE_NAME stopped" + ;; + + stop-deps) + log_info "Stopping dependencies..." + cd "$SCRIPT_DIR" + docker compose -f docker-compose.dev.yml down + log_success "Dependencies stopped" + ;; + + restart) + bash "$SCRIPT_DIR/deploy.sh" stop + bash "$SCRIPT_DIR/deploy.sh" start + ;; + + up) + load_env + log_info "Starting $SERVICE_NAME in foreground..." + cd "$SERVICES_DIR" + # Use --no-deps to avoid recreating infrastructure that's already running + docker compose up --no-deps "$SERVICE_NAME" + ;; + + logs) + docker logs -f "$CONTAINER_NAME" + ;; + + logs-tail) + docker logs --tail 100 "$CONTAINER_NAME" + ;; + + logs-all) + cd "$SERVICES_DIR" + docker compose logs -f "$SERVICE_NAME" + ;; + + status) + if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + log_success "$SERVICE_NAME is running" + docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" + else + log_warn "$SERVICE_NAME is not running" + fi + ;; + + health) + log_info "Checking health of $SERVICE_NAME..." + if curl -sf "$HEALTH_ENDPOINT" > /dev/null 2>&1; then + HEALTH=$(curl -s "$HEALTH_ENDPOINT") + log_success "$SERVICE_NAME is healthy" + echo "$HEALTH" | jq . 2>/dev/null || echo "$HEALTH" + else + log_error "$SERVICE_NAME health check failed" + exit 1 + fi + ;; + + init-db) + log_info "Creating database rwa_presence..." + docker exec rwa-postgres psql -U rwa_user -d postgres -c "CREATE DATABASE rwa_presence;" 2>/dev/null || \ + log_warn "Database may already exist" + log_success "Database rwa_presence created (or already exists)" + log_info "Running Prisma db push to create tables..." + docker exec "$CONTAINER_NAME" npx prisma db push --skip-generate 2>/dev/null || \ + log_warn "Could not push schema (container may not be running)" + ;; + + migrate) + log_info "Running migrations for $SERVICE_NAME..." + docker exec "$CONTAINER_NAME" npx prisma migrate deploy + log_success "Migrations completed" + ;; + + migrate-dev) + log_info "Running dev migrations for $SERVICE_NAME..." + docker exec "$CONTAINER_NAME" npx prisma migrate dev + ;; + + db-push) + log_info "Pushing schema to database..." + docker exec "$CONTAINER_NAME" npx prisma db push + log_success "Schema pushed" + ;; + + prisma-studio) + log_info "Starting Prisma Studio..." + docker exec -it "$CONTAINER_NAME" npx prisma studio + ;; + + shell) + log_info "Opening shell in $SERVICE_NAME container..." + docker exec -it "$CONTAINER_NAME" sh + ;; + + test) + log_info "Running tests for $SERVICE_NAME..." + cd "$SCRIPT_DIR" + npm test + ;; + + test-unit) + log_info "Running unit tests..." + cd "$SCRIPT_DIR" + npm run test:unit + ;; + + test-integration) + log_info "Running integration tests..." + cd "$SCRIPT_DIR" + npm run test:integration + ;; + + test-e2e) + log_info "Running E2E tests..." + cd "$SCRIPT_DIR" + npm run test:e2e + ;; + + clean) + log_info "Cleaning up..." + docker stop "$CONTAINER_NAME" 2>/dev/null || true + docker rm "$CONTAINER_NAME" 2>/dev/null || true + log_success "Cleanup completed" + ;; + + clean-all) + log_info "Cleaning $SERVICE_NAME (removing container and image)..." + docker stop "$CONTAINER_NAME" 2>/dev/null || true + docker rm "$CONTAINER_NAME" 2>/dev/null || true + docker rmi "$IMAGE_NAME" 2>/dev/null || true + log_success "$SERVICE_NAME fully cleaned" + ;; + + *) + echo "Usage: $0 {command}" + echo "" + echo "Build Commands:" + echo " build - Build Docker image" + echo " build-no-cache - Build Docker image without cache" + echo "" + echo "Service Commands:" + echo " start - Start using shared infrastructure" + echo " start-deps - Start dependencies only (for local development)" + echo " stop - Stop the service container" + echo " stop-deps - Stop dependencies only" + echo " restart - Restart the service" + echo " up - Start in foreground mode" + echo "" + echo "Monitoring Commands:" + echo " logs - Follow logs" + echo " logs-tail - Show last 100 log lines" + echo " logs-all - Follow logs via docker compose" + echo " status - Show service status" + echo " health - Check service health" + echo "" + echo "Database Commands:" + echo " init-db - Create database and push schema" + echo " migrate - Run database migrations (production)" + echo " migrate-dev - Run dev migrations" + echo " db-push - Push Prisma schema to database" + echo " prisma-studio - Open Prisma Studio" + echo "" + echo "Development Commands:" + echo " shell - Open shell in container" + echo " test - Run all tests" + echo " test-unit - Run unit tests only" + echo " test-integration - Run integration tests only" + echo " test-e2e - Run E2E tests only" + echo "" + echo "Maintenance Commands:" + echo " clean - Remove container" + echo " clean-all - Remove container and image" + exit 1 + ;; +esac diff --git a/backend/services/referral-service/deploy.sh b/backend/services/referral-service/deploy.sh index 5dc5dc17..0c661768 100755 --- a/backend/services/referral-service/deploy.sh +++ b/backend/services/referral-service/deploy.sh @@ -1,94 +1,94 @@ -#!/bin/bash -# ============================================================================= -# Referral Service - Individual Deployment Script -# ============================================================================= - -set -e - -SERVICE_NAME="referral-service" -CONTAINER_NAME="rwa-referral-service" -IMAGE_NAME="services-referral-service" -PORT=3004 - -# 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}[OK]${NC} $1"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } -log_error() { echo -e "${RED}[ERROR]${NC} $1"; } - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -SERVICES_DIR="$(dirname "$SCRIPT_DIR")" - -if [ -f "$SERVICES_DIR/.env" ]; then - export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) -fi - -case "$1" in - build) - log_info "Building $SERVICE_NAME..." - docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - build-no-cache) - log_info "Building $SERVICE_NAME (no cache)..." - docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - start) - log_info "Starting $SERVICE_NAME..." - cd "$SERVICES_DIR" - docker compose up -d "$SERVICE_NAME" - log_success "$SERVICE_NAME started" - ;; - stop) - log_info "Stopping $SERVICE_NAME..." - docker stop "$CONTAINER_NAME" 2>/dev/null || true - docker rm "$CONTAINER_NAME" 2>/dev/null || true - log_success "$SERVICE_NAME stopped" - ;; - restart) - $0 stop - $0 start - ;; - logs) - docker logs -f "$CONTAINER_NAME" - ;; - logs-tail) - docker logs --tail 100 "$CONTAINER_NAME" - ;; - status) - if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - log_success "$SERVICE_NAME is running" - docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" - else - log_warn "$SERVICE_NAME is not running" - fi - ;; - health) - log_info "Checking health of $SERVICE_NAME..." - if curl -sf "http://localhost:$PORT/health" > /dev/null 2>&1; then - log_success "$SERVICE_NAME is healthy" - else - log_error "$SERVICE_NAME health check failed" - exit 1 - fi - ;; - migrate) - log_info "Running migrations for $SERVICE_NAME..." - docker exec "$CONTAINER_NAME" npx prisma migrate deploy - log_success "Migrations completed" - ;; - shell) - docker exec -it "$CONTAINER_NAME" sh - ;; - *) - echo "Usage: $0 {build|build-no-cache|start|stop|restart|logs|logs-tail|status|health|migrate|shell}" - exit 1 - ;; -esac +#!/bin/bash +# ============================================================================= +# Referral Service - Individual Deployment Script +# ============================================================================= + +set -e + +SERVICE_NAME="referral-service" +CONTAINER_NAME="rwa-referral-service" +IMAGE_NAME="services-referral-service" +PORT=3004 + +# 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}[OK]${NC} $1"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVICES_DIR="$(dirname "$SCRIPT_DIR")" + +if [ -f "$SERVICES_DIR/.env" ]; then + export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) +fi + +case "$1" in + build) + log_info "Building $SERVICE_NAME..." + docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + build-no-cache) + log_info "Building $SERVICE_NAME (no cache)..." + docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + start) + log_info "Starting $SERVICE_NAME..." + cd "$SERVICES_DIR" + docker compose up -d "$SERVICE_NAME" + log_success "$SERVICE_NAME started" + ;; + stop) + log_info "Stopping $SERVICE_NAME..." + docker stop "$CONTAINER_NAME" 2>/dev/null || true + docker rm "$CONTAINER_NAME" 2>/dev/null || true + log_success "$SERVICE_NAME stopped" + ;; + restart) + $0 stop + $0 start + ;; + logs) + docker logs -f "$CONTAINER_NAME" + ;; + logs-tail) + docker logs --tail 100 "$CONTAINER_NAME" + ;; + status) + if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + log_success "$SERVICE_NAME is running" + docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" + else + log_warn "$SERVICE_NAME is not running" + fi + ;; + health) + log_info "Checking health of $SERVICE_NAME..." + if curl -sf "http://localhost:$PORT/health" > /dev/null 2>&1; then + log_success "$SERVICE_NAME is healthy" + else + log_error "$SERVICE_NAME health check failed" + exit 1 + fi + ;; + migrate) + log_info "Running migrations for $SERVICE_NAME..." + docker exec "$CONTAINER_NAME" npx prisma migrate deploy + log_success "Migrations completed" + ;; + shell) + docker exec -it "$CONTAINER_NAME" sh + ;; + *) + echo "Usage: $0 {build|build-no-cache|start|stop|restart|logs|logs-tail|status|health|migrate|shell}" + exit 1 + ;; +esac diff --git a/backend/services/reporting-service/deploy.sh b/backend/services/reporting-service/deploy.sh index ba9660c4..4b22f6aa 100755 --- a/backend/services/reporting-service/deploy.sh +++ b/backend/services/reporting-service/deploy.sh @@ -1,94 +1,94 @@ -#!/bin/bash -# ============================================================================= -# Reporting Service - Individual Deployment Script -# ============================================================================= - -set -e - -SERVICE_NAME="reporting-service" -CONTAINER_NAME="rwa-reporting-service" -IMAGE_NAME="services-reporting-service" -PORT=3008 - -# 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}[OK]${NC} $1"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } -log_error() { echo -e "${RED}[ERROR]${NC} $1"; } - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -SERVICES_DIR="$(dirname "$SCRIPT_DIR")" - -if [ -f "$SERVICES_DIR/.env" ]; then - export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) -fi - -case "$1" in - build) - log_info "Building $SERVICE_NAME..." - docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - build-no-cache) - log_info "Building $SERVICE_NAME (no cache)..." - docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - start) - log_info "Starting $SERVICE_NAME..." - cd "$SERVICES_DIR" - docker compose up -d "$SERVICE_NAME" - log_success "$SERVICE_NAME started" - ;; - stop) - log_info "Stopping $SERVICE_NAME..." - docker stop "$CONTAINER_NAME" 2>/dev/null || true - docker rm "$CONTAINER_NAME" 2>/dev/null || true - log_success "$SERVICE_NAME stopped" - ;; - restart) - $0 stop - $0 start - ;; - logs) - docker logs -f "$CONTAINER_NAME" - ;; - logs-tail) - docker logs --tail 100 "$CONTAINER_NAME" - ;; - status) - if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - log_success "$SERVICE_NAME is running" - docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" - else - log_warn "$SERVICE_NAME is not running" - fi - ;; - health) - log_info "Checking health of $SERVICE_NAME..." - if curl -sf "http://localhost:$PORT/health" > /dev/null 2>&1; then - log_success "$SERVICE_NAME is healthy" - else - log_error "$SERVICE_NAME health check failed" - exit 1 - fi - ;; - migrate) - log_info "Running migrations for $SERVICE_NAME..." - docker exec "$CONTAINER_NAME" npx prisma migrate deploy - log_success "Migrations completed" - ;; - shell) - docker exec -it "$CONTAINER_NAME" sh - ;; - *) - echo "Usage: $0 {build|build-no-cache|start|stop|restart|logs|logs-tail|status|health|migrate|shell}" - exit 1 - ;; -esac +#!/bin/bash +# ============================================================================= +# Reporting Service - Individual Deployment Script +# ============================================================================= + +set -e + +SERVICE_NAME="reporting-service" +CONTAINER_NAME="rwa-reporting-service" +IMAGE_NAME="services-reporting-service" +PORT=3008 + +# 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}[OK]${NC} $1"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVICES_DIR="$(dirname "$SCRIPT_DIR")" + +if [ -f "$SERVICES_DIR/.env" ]; then + export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) +fi + +case "$1" in + build) + log_info "Building $SERVICE_NAME..." + docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + build-no-cache) + log_info "Building $SERVICE_NAME (no cache)..." + docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + start) + log_info "Starting $SERVICE_NAME..." + cd "$SERVICES_DIR" + docker compose up -d "$SERVICE_NAME" + log_success "$SERVICE_NAME started" + ;; + stop) + log_info "Stopping $SERVICE_NAME..." + docker stop "$CONTAINER_NAME" 2>/dev/null || true + docker rm "$CONTAINER_NAME" 2>/dev/null || true + log_success "$SERVICE_NAME stopped" + ;; + restart) + $0 stop + $0 start + ;; + logs) + docker logs -f "$CONTAINER_NAME" + ;; + logs-tail) + docker logs --tail 100 "$CONTAINER_NAME" + ;; + status) + if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + log_success "$SERVICE_NAME is running" + docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" + else + log_warn "$SERVICE_NAME is not running" + fi + ;; + health) + log_info "Checking health of $SERVICE_NAME..." + if curl -sf "http://localhost:$PORT/health" > /dev/null 2>&1; then + log_success "$SERVICE_NAME is healthy" + else + log_error "$SERVICE_NAME health check failed" + exit 1 + fi + ;; + migrate) + log_info "Running migrations for $SERVICE_NAME..." + docker exec "$CONTAINER_NAME" npx prisma migrate deploy + log_success "Migrations completed" + ;; + shell) + docker exec -it "$CONTAINER_NAME" sh + ;; + *) + echo "Usage: $0 {build|build-no-cache|start|stop|restart|logs|logs-tail|status|health|migrate|shell}" + exit 1 + ;; +esac diff --git a/backend/services/reward-service/deploy.sh b/backend/services/reward-service/deploy.sh index 417136ba..603428da 100755 --- a/backend/services/reward-service/deploy.sh +++ b/backend/services/reward-service/deploy.sh @@ -1,94 +1,94 @@ -#!/bin/bash -# ============================================================================= -# Reward Service - Individual Deployment Script -# ============================================================================= - -set -e - -SERVICE_NAME="reward-service" -CONTAINER_NAME="rwa-reward-service" -IMAGE_NAME="services-reward-service" -PORT=3005 - -# 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}[OK]${NC} $1"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } -log_error() { echo -e "${RED}[ERROR]${NC} $1"; } - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -SERVICES_DIR="$(dirname "$SCRIPT_DIR")" - -if [ -f "$SERVICES_DIR/.env" ]; then - export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) -fi - -case "$1" in - build) - log_info "Building $SERVICE_NAME..." - docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - build-no-cache) - log_info "Building $SERVICE_NAME (no cache)..." - docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - start) - log_info "Starting $SERVICE_NAME..." - cd "$SERVICES_DIR" - docker compose up -d "$SERVICE_NAME" - log_success "$SERVICE_NAME started" - ;; - stop) - log_info "Stopping $SERVICE_NAME..." - docker stop "$CONTAINER_NAME" 2>/dev/null || true - docker rm "$CONTAINER_NAME" 2>/dev/null || true - log_success "$SERVICE_NAME stopped" - ;; - restart) - $0 stop - $0 start - ;; - logs) - docker logs -f "$CONTAINER_NAME" - ;; - logs-tail) - docker logs --tail 100 "$CONTAINER_NAME" - ;; - status) - if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - log_success "$SERVICE_NAME is running" - docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" - else - log_warn "$SERVICE_NAME is not running" - fi - ;; - health) - log_info "Checking health of $SERVICE_NAME..." - if curl -sf "http://localhost:$PORT/health" > /dev/null 2>&1; then - log_success "$SERVICE_NAME is healthy" - else - log_error "$SERVICE_NAME health check failed" - exit 1 - fi - ;; - migrate) - log_info "Running migrations for $SERVICE_NAME..." - docker exec "$CONTAINER_NAME" npx prisma migrate deploy - log_success "Migrations completed" - ;; - shell) - docker exec -it "$CONTAINER_NAME" sh - ;; - *) - echo "Usage: $0 {build|build-no-cache|start|stop|restart|logs|logs-tail|status|health|migrate|shell}" - exit 1 - ;; -esac +#!/bin/bash +# ============================================================================= +# Reward Service - Individual Deployment Script +# ============================================================================= + +set -e + +SERVICE_NAME="reward-service" +CONTAINER_NAME="rwa-reward-service" +IMAGE_NAME="services-reward-service" +PORT=3005 + +# 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}[OK]${NC} $1"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVICES_DIR="$(dirname "$SCRIPT_DIR")" + +if [ -f "$SERVICES_DIR/.env" ]; then + export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) +fi + +case "$1" in + build) + log_info "Building $SERVICE_NAME..." + docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + build-no-cache) + log_info "Building $SERVICE_NAME (no cache)..." + docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + start) + log_info "Starting $SERVICE_NAME..." + cd "$SERVICES_DIR" + docker compose up -d "$SERVICE_NAME" + log_success "$SERVICE_NAME started" + ;; + stop) + log_info "Stopping $SERVICE_NAME..." + docker stop "$CONTAINER_NAME" 2>/dev/null || true + docker rm "$CONTAINER_NAME" 2>/dev/null || true + log_success "$SERVICE_NAME stopped" + ;; + restart) + $0 stop + $0 start + ;; + logs) + docker logs -f "$CONTAINER_NAME" + ;; + logs-tail) + docker logs --tail 100 "$CONTAINER_NAME" + ;; + status) + if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + log_success "$SERVICE_NAME is running" + docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" + else + log_warn "$SERVICE_NAME is not running" + fi + ;; + health) + log_info "Checking health of $SERVICE_NAME..." + if curl -sf "http://localhost:$PORT/health" > /dev/null 2>&1; then + log_success "$SERVICE_NAME is healthy" + else + log_error "$SERVICE_NAME health check failed" + exit 1 + fi + ;; + migrate) + log_info "Running migrations for $SERVICE_NAME..." + docker exec "$CONTAINER_NAME" npx prisma migrate deploy + log_success "Migrations completed" + ;; + shell) + docker exec -it "$CONTAINER_NAME" sh + ;; + *) + echo "Usage: $0 {build|build-no-cache|start|stop|restart|logs|logs-tail|status|health|migrate|shell}" + exit 1 + ;; +esac diff --git a/backend/services/wallet-service/deploy.sh b/backend/services/wallet-service/deploy.sh index 07af16c2..8cb06942 100755 --- a/backend/services/wallet-service/deploy.sh +++ b/backend/services/wallet-service/deploy.sh @@ -1,94 +1,94 @@ -#!/bin/bash -# ============================================================================= -# Wallet Service - Individual Deployment Script -# ============================================================================= - -set -e - -SERVICE_NAME="wallet-service" -CONTAINER_NAME="rwa-wallet-service" -IMAGE_NAME="services-wallet-service" -PORT=3001 - -# 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}[OK]${NC} $1"; } -log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } -log_error() { echo -e "${RED}[ERROR]${NC} $1"; } - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -SERVICES_DIR="$(dirname "$SCRIPT_DIR")" - -if [ -f "$SERVICES_DIR/.env" ]; then - export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) -fi - -case "$1" in - build) - log_info "Building $SERVICE_NAME..." - docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - build-no-cache) - log_info "Building $SERVICE_NAME (no cache)..." - docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" - log_success "$SERVICE_NAME built successfully" - ;; - start) - log_info "Starting $SERVICE_NAME..." - cd "$SERVICES_DIR" - docker compose up -d "$SERVICE_NAME" - log_success "$SERVICE_NAME started" - ;; - stop) - log_info "Stopping $SERVICE_NAME..." - docker stop "$CONTAINER_NAME" 2>/dev/null || true - docker rm "$CONTAINER_NAME" 2>/dev/null || true - log_success "$SERVICE_NAME stopped" - ;; - restart) - $0 stop - $0 start - ;; - logs) - docker logs -f "$CONTAINER_NAME" - ;; - logs-tail) - docker logs --tail 100 "$CONTAINER_NAME" - ;; - status) - if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - log_success "$SERVICE_NAME is running" - docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" - else - log_warn "$SERVICE_NAME is not running" - fi - ;; - health) - log_info "Checking health of $SERVICE_NAME..." - if curl -sf "http://localhost:$PORT/health" > /dev/null 2>&1; then - log_success "$SERVICE_NAME is healthy" - else - log_error "$SERVICE_NAME health check failed" - exit 1 - fi - ;; - migrate) - log_info "Running migrations for $SERVICE_NAME..." - docker exec "$CONTAINER_NAME" npx prisma migrate deploy - log_success "Migrations completed" - ;; - shell) - docker exec -it "$CONTAINER_NAME" sh - ;; - *) - echo "Usage: $0 {build|build-no-cache|start|stop|restart|logs|logs-tail|status|health|migrate|shell}" - exit 1 - ;; -esac +#!/bin/bash +# ============================================================================= +# Wallet Service - Individual Deployment Script +# ============================================================================= + +set -e + +SERVICE_NAME="wallet-service" +CONTAINER_NAME="rwa-wallet-service" +IMAGE_NAME="services-wallet-service" +PORT=3001 + +# 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}[OK]${NC} $1"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVICES_DIR="$(dirname "$SCRIPT_DIR")" + +if [ -f "$SERVICES_DIR/.env" ]; then + export $(cat "$SERVICES_DIR/.env" | grep -v '^#' | xargs) +fi + +case "$1" in + build) + log_info "Building $SERVICE_NAME..." + docker build -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + build-no-cache) + log_info "Building $SERVICE_NAME (no cache)..." + docker build --no-cache -t "$IMAGE_NAME" "$SCRIPT_DIR" + log_success "$SERVICE_NAME built successfully" + ;; + start) + log_info "Starting $SERVICE_NAME..." + cd "$SERVICES_DIR" + docker compose up -d "$SERVICE_NAME" + log_success "$SERVICE_NAME started" + ;; + stop) + log_info "Stopping $SERVICE_NAME..." + docker stop "$CONTAINER_NAME" 2>/dev/null || true + docker rm "$CONTAINER_NAME" 2>/dev/null || true + log_success "$SERVICE_NAME stopped" + ;; + restart) + $0 stop + $0 start + ;; + logs) + docker logs -f "$CONTAINER_NAME" + ;; + logs-tail) + docker logs --tail 100 "$CONTAINER_NAME" + ;; + status) + if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + log_success "$SERVICE_NAME is running" + docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Status}}\t{{.Ports}}" + else + log_warn "$SERVICE_NAME is not running" + fi + ;; + health) + log_info "Checking health of $SERVICE_NAME..." + if curl -sf "http://localhost:$PORT/health" > /dev/null 2>&1; then + log_success "$SERVICE_NAME is healthy" + else + log_error "$SERVICE_NAME health check failed" + exit 1 + fi + ;; + migrate) + log_info "Running migrations for $SERVICE_NAME..." + docker exec "$CONTAINER_NAME" npx prisma migrate deploy + log_success "Migrations completed" + ;; + shell) + docker exec -it "$CONTAINER_NAME" sh + ;; + *) + echo "Usage: $0 {build|build-no-cache|start|stop|restart|logs|logs-tail|status|health|migrate|shell}" + exit 1 + ;; +esac diff --git a/frontend/admin-web/deploy.sh b/frontend/admin-web/deploy.sh index 724198cd..103c2e79 100755 --- a/frontend/admin-web/deploy.sh +++ b/frontend/admin-web/deploy.sh @@ -1,216 +1,216 @@ -#!/bin/bash - -# RWADurian Admin Web 一键部署脚本 -# 使用方法: ./deploy.sh [命令] -# 命令: -# build - 仅构建镜像 -# start - 构建并启动服务 -# stop - 停止服务 -# restart - 重启服务 -# logs - 查看日志 -# clean - 清理容器和镜像 - -set -e - -# 颜色定义 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -# 项目信息 -PROJECT_NAME="rwadurian-admin-web" -IMAGE_NAME="rwadurian-admin-web" -CONTAINER_NAME="rwadurian-admin-web" -DEFAULT_PORT=3000 - -# 日志函数 -log_info() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -log_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -# 检查 Docker 是否安装 -check_docker() { - if ! command -v docker &> /dev/null; then - log_error "Docker 未安装,请先安装 Docker" - exit 1 - fi - - if ! docker info &> /dev/null; then - log_error "Docker 服务未运行,请启动 Docker" - exit 1 - fi - - log_success "Docker 检查通过" -} - -# 检查 Docker Compose 是否安装 -check_docker_compose() { - if docker compose version &> /dev/null; then - COMPOSE_CMD="docker compose" - elif command -v docker-compose &> /dev/null; then - COMPOSE_CMD="docker-compose" - else - log_error "Docker Compose 未安装" - exit 1 - fi - - log_success "Docker Compose 检查通过 ($COMPOSE_CMD)" -} - -# 构建镜像 -build() { - log_info "开始构建 Docker 镜像..." - $COMPOSE_CMD build --no-cache - log_success "镜像构建完成" -} - -# 启动服务 -start() { - log_info "开始部署服务..." - - # 检查端口是否被占用 - PORT=${PORT:-$DEFAULT_PORT} - if lsof -Pi :$PORT -sTCP:LISTEN -t >/dev/null 2>&1; then - log_warn "端口 $PORT 已被占用,尝试停止旧服务..." - stop - fi - - # 构建并启动 - $COMPOSE_CMD up -d --build - - # 等待服务启动 - log_info "等待服务启动..." - sleep 5 - - # 检查服务状态 - if docker ps | grep -q $CONTAINER_NAME; then - log_success "服务部署成功!" - log_info "访问地址: http://localhost:$PORT" - else - log_error "服务启动失败,请查看日志: ./deploy.sh logs" - exit 1 - fi -} - -# 停止服务 -stop() { - log_info "停止服务..." - $COMPOSE_CMD down - log_success "服务已停止" -} - -# 重启服务 -restart() { - log_info "重启服务..." - stop - start -} - -# 查看日志 -logs() { - $COMPOSE_CMD logs -f -} - -# 清理 -clean() { - log_info "清理容器和镜像..." - - # 停止并删除容器 - $COMPOSE_CMD down --rmi local --volumes --remove-orphans - - # 删除悬空镜像 - docker image prune -f - - log_success "清理完成" -} - -# 显示状态 -status() { - log_info "服务状态:" - docker ps -a --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" -} - -# 显示帮助 -show_help() { - echo "" - echo "RWADurian Admin Web 部署脚本" - echo "" - echo "使用方法: ./deploy.sh [命令]" - echo "" - echo "命令:" - echo " build 仅构建 Docker 镜像" - echo " start 构建并启动服务 (默认)" - echo " stop 停止服务" - echo " restart 重启服务" - echo " logs 查看服务日志" - echo " status 查看服务状态" - echo " clean 清理容器和镜像" - echo " help 显示此帮助信息" - echo "" - echo "环境变量:" - echo " PORT 服务端口 (默认: 3000)" - echo "" - echo "示例:" - echo " ./deploy.sh start # 默认端口 3000 启动" - echo " PORT=8080 ./deploy.sh start # 指定端口 8080 启动" - echo "" -} - -# 主函数 -main() { - # 切换到脚本所在目录 - cd "$(dirname "$0")" - - # 检查环境 - check_docker - check_docker_compose - - # 执行命令 - case "${1:-start}" in - build) - build - ;; - start) - start - ;; - stop) - stop - ;; - restart) - restart - ;; - logs) - logs - ;; - status) - status - ;; - clean) - clean - ;; - help|--help|-h) - show_help - ;; - *) - log_error "未知命令: $1" - show_help - exit 1 - ;; - esac -} - -main "$@" +#!/bin/bash + +# RWADurian Admin Web 一键部署脚本 +# 使用方法: ./deploy.sh [命令] +# 命令: +# build - 仅构建镜像 +# start - 构建并启动服务 +# stop - 停止服务 +# restart - 重启服务 +# logs - 查看日志 +# clean - 清理容器和镜像 + +set -e + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# 项目信息 +PROJECT_NAME="rwadurian-admin-web" +IMAGE_NAME="rwadurian-admin-web" +CONTAINER_NAME="rwadurian-admin-web" +DEFAULT_PORT=3000 + +# 日志函数 +log_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +log_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# 检查 Docker 是否安装 +check_docker() { + if ! command -v docker &> /dev/null; then + log_error "Docker 未安装,请先安装 Docker" + exit 1 + fi + + if ! docker info &> /dev/null; then + log_error "Docker 服务未运行,请启动 Docker" + exit 1 + fi + + log_success "Docker 检查通过" +} + +# 检查 Docker Compose 是否安装 +check_docker_compose() { + if docker compose version &> /dev/null; then + COMPOSE_CMD="docker compose" + elif command -v docker-compose &> /dev/null; then + COMPOSE_CMD="docker-compose" + else + log_error "Docker Compose 未安装" + exit 1 + fi + + log_success "Docker Compose 检查通过 ($COMPOSE_CMD)" +} + +# 构建镜像 +build() { + log_info "开始构建 Docker 镜像..." + $COMPOSE_CMD build --no-cache + log_success "镜像构建完成" +} + +# 启动服务 +start() { + log_info "开始部署服务..." + + # 检查端口是否被占用 + PORT=${PORT:-$DEFAULT_PORT} + if lsof -Pi :$PORT -sTCP:LISTEN -t >/dev/null 2>&1; then + log_warn "端口 $PORT 已被占用,尝试停止旧服务..." + stop + fi + + # 构建并启动 + $COMPOSE_CMD up -d --build + + # 等待服务启动 + log_info "等待服务启动..." + sleep 5 + + # 检查服务状态 + if docker ps | grep -q $CONTAINER_NAME; then + log_success "服务部署成功!" + log_info "访问地址: http://localhost:$PORT" + else + log_error "服务启动失败,请查看日志: ./deploy.sh logs" + exit 1 + fi +} + +# 停止服务 +stop() { + log_info "停止服务..." + $COMPOSE_CMD down + log_success "服务已停止" +} + +# 重启服务 +restart() { + log_info "重启服务..." + stop + start +} + +# 查看日志 +logs() { + $COMPOSE_CMD logs -f +} + +# 清理 +clean() { + log_info "清理容器和镜像..." + + # 停止并删除容器 + $COMPOSE_CMD down --rmi local --volumes --remove-orphans + + # 删除悬空镜像 + docker image prune -f + + log_success "清理完成" +} + +# 显示状态 +status() { + log_info "服务状态:" + docker ps -a --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" +} + +# 显示帮助 +show_help() { + echo "" + echo "RWADurian Admin Web 部署脚本" + echo "" + echo "使用方法: ./deploy.sh [命令]" + echo "" + echo "命令:" + echo " build 仅构建 Docker 镜像" + echo " start 构建并启动服务 (默认)" + echo " stop 停止服务" + echo " restart 重启服务" + echo " logs 查看服务日志" + echo " status 查看服务状态" + echo " clean 清理容器和镜像" + echo " help 显示此帮助信息" + echo "" + echo "环境变量:" + echo " PORT 服务端口 (默认: 3000)" + echo "" + echo "示例:" + echo " ./deploy.sh start # 默认端口 3000 启动" + echo " PORT=8080 ./deploy.sh start # 指定端口 8080 启动" + echo "" +} + +# 主函数 +main() { + # 切换到脚本所在目录 + cd "$(dirname "$0")" + + # 检查环境 + check_docker + check_docker_compose + + # 执行命令 + case "${1:-start}" in + build) + build + ;; + start) + start + ;; + stop) + stop + ;; + restart) + restart + ;; + logs) + logs + ;; + status) + status + ;; + clean) + clean + ;; + help|--help|-h) + show_help + ;; + *) + log_error "未知命令: $1" + show_help + exit 1 + ;; + esac +} + +main "$@" diff --git a/frontend/mobile-upgrade/deploy.sh b/frontend/mobile-upgrade/deploy.sh index 625facd0..ad7bb85d 100755 --- a/frontend/mobile-upgrade/deploy.sh +++ b/frontend/mobile-upgrade/deploy.sh @@ -1,216 +1,216 @@ -#!/bin/bash - -# RWADurian Mobile Upgrade 一键部署脚本 -# 使用方法: ./deploy.sh [命令] -# 命令: -# build - 仅构建镜像 -# start - 构建并启动服务 -# stop - 停止服务 -# restart - 重启服务 -# logs - 查看日志 -# clean - 清理容器和镜像 - -set -e - -# 颜色定义 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -# 项目信息 -PROJECT_NAME="rwadurian-mobile-upgrade" -IMAGE_NAME="rwadurian-mobile-upgrade" -CONTAINER_NAME="rwadurian-mobile-upgrade" -DEFAULT_PORT=3020 - -# 日志函数 -log_info() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -log_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -# 检查 Docker 是否安装 -check_docker() { - if ! command -v docker &> /dev/null; then - log_error "Docker 未安装,请先安装 Docker" - exit 1 - fi - - if ! docker info &> /dev/null; then - log_error "Docker 服务未运行,请启动 Docker" - exit 1 - fi - - log_success "Docker 检查通过" -} - -# 检查 Docker Compose 是否安装 -check_docker_compose() { - if docker compose version &> /dev/null; then - COMPOSE_CMD="docker compose" - elif command -v docker-compose &> /dev/null; then - COMPOSE_CMD="docker-compose" - else - log_error "Docker Compose 未安装" - exit 1 - fi - - log_success "Docker Compose 检查通过 ($COMPOSE_CMD)" -} - -# 构建镜像 -build() { - log_info "开始构建 Docker 镜像..." - $COMPOSE_CMD build --no-cache - log_success "镜像构建完成" -} - -# 启动服务 -start() { - log_info "开始部署服务..." - - # 检查端口是否被占用 - PORT=${PORT:-$DEFAULT_PORT} - if lsof -Pi :$PORT -sTCP:LISTEN -t >/dev/null 2>&1; then - log_warn "端口 $PORT 已被占用,尝试停止旧服务..." - stop - fi - - # 构建并启动 - $COMPOSE_CMD up -d --build - - # 等待服务启动 - log_info "等待服务启动..." - sleep 5 - - # 检查服务状态 - if docker ps | grep -q $CONTAINER_NAME; then - log_success "服务部署成功!" - log_info "访问地址: http://localhost:$PORT" - else - log_error "服务启动失败,请查看日志: ./deploy.sh logs" - exit 1 - fi -} - -# 停止服务 -stop() { - log_info "停止服务..." - $COMPOSE_CMD down - log_success "服务已停止" -} - -# 重启服务 -restart() { - log_info "重启服务..." - stop - start -} - -# 查看日志 -logs() { - $COMPOSE_CMD logs -f -} - -# 清理 -clean() { - log_info "清理容器和镜像..." - - # 停止并删除容器 - $COMPOSE_CMD down --rmi local --volumes --remove-orphans - - # 删除悬空镜像 - docker image prune -f - - log_success "清理完成" -} - -# 显示状态 -status() { - log_info "服务状态:" - docker ps -a --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" -} - -# 显示帮助 -show_help() { - echo "" - echo "RWADurian Mobile Upgrade 部署脚本" - echo "" - echo "使用方法: ./deploy.sh [命令]" - echo "" - echo "命令:" - echo " build 仅构建 Docker 镜像" - echo " start 构建并启动服务 (默认)" - echo " stop 停止服务" - echo " restart 重启服务" - echo " logs 查看服务日志" - echo " status 查看服务状态" - echo " clean 清理容器和镜像" - echo " help 显示此帮助信息" - echo "" - echo "环境变量:" - echo " PORT 服务端口 (默认: 3020)" - echo "" - echo "示例:" - echo " ./deploy.sh start # 默认端口 3020 启动" - echo " PORT=8080 ./deploy.sh start # 指定端口 8080 启动" - echo "" -} - -# 主函数 -main() { - # 切换到脚本所在目录 - cd "$(dirname "$0")" - - # 检查环境 - check_docker - check_docker_compose - - # 执行命令 - case "${1:-start}" in - build) - build - ;; - start) - start - ;; - stop) - stop - ;; - restart) - restart - ;; - logs) - logs - ;; - status) - status - ;; - clean) - clean - ;; - help|--help|-h) - show_help - ;; - *) - log_error "未知命令: $1" - show_help - exit 1 - ;; - esac -} - -main "$@" +#!/bin/bash + +# RWADurian Mobile Upgrade 一键部署脚本 +# 使用方法: ./deploy.sh [命令] +# 命令: +# build - 仅构建镜像 +# start - 构建并启动服务 +# stop - 停止服务 +# restart - 重启服务 +# logs - 查看日志 +# clean - 清理容器和镜像 + +set -e + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# 项目信息 +PROJECT_NAME="rwadurian-mobile-upgrade" +IMAGE_NAME="rwadurian-mobile-upgrade" +CONTAINER_NAME="rwadurian-mobile-upgrade" +DEFAULT_PORT=3020 + +# 日志函数 +log_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +log_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# 检查 Docker 是否安装 +check_docker() { + if ! command -v docker &> /dev/null; then + log_error "Docker 未安装,请先安装 Docker" + exit 1 + fi + + if ! docker info &> /dev/null; then + log_error "Docker 服务未运行,请启动 Docker" + exit 1 + fi + + log_success "Docker 检查通过" +} + +# 检查 Docker Compose 是否安装 +check_docker_compose() { + if docker compose version &> /dev/null; then + COMPOSE_CMD="docker compose" + elif command -v docker-compose &> /dev/null; then + COMPOSE_CMD="docker-compose" + else + log_error "Docker Compose 未安装" + exit 1 + fi + + log_success "Docker Compose 检查通过 ($COMPOSE_CMD)" +} + +# 构建镜像 +build() { + log_info "开始构建 Docker 镜像..." + $COMPOSE_CMD build --no-cache + log_success "镜像构建完成" +} + +# 启动服务 +start() { + log_info "开始部署服务..." + + # 检查端口是否被占用 + PORT=${PORT:-$DEFAULT_PORT} + if lsof -Pi :$PORT -sTCP:LISTEN -t >/dev/null 2>&1; then + log_warn "端口 $PORT 已被占用,尝试停止旧服务..." + stop + fi + + # 构建并启动 + $COMPOSE_CMD up -d --build + + # 等待服务启动 + log_info "等待服务启动..." + sleep 5 + + # 检查服务状态 + if docker ps | grep -q $CONTAINER_NAME; then + log_success "服务部署成功!" + log_info "访问地址: http://localhost:$PORT" + else + log_error "服务启动失败,请查看日志: ./deploy.sh logs" + exit 1 + fi +} + +# 停止服务 +stop() { + log_info "停止服务..." + $COMPOSE_CMD down + log_success "服务已停止" +} + +# 重启服务 +restart() { + log_info "重启服务..." + stop + start +} + +# 查看日志 +logs() { + $COMPOSE_CMD logs -f +} + +# 清理 +clean() { + log_info "清理容器和镜像..." + + # 停止并删除容器 + $COMPOSE_CMD down --rmi local --volumes --remove-orphans + + # 删除悬空镜像 + docker image prune -f + + log_success "清理完成" +} + +# 显示状态 +status() { + log_info "服务状态:" + docker ps -a --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" +} + +# 显示帮助 +show_help() { + echo "" + echo "RWADurian Mobile Upgrade 部署脚本" + echo "" + echo "使用方法: ./deploy.sh [命令]" + echo "" + echo "命令:" + echo " build 仅构建 Docker 镜像" + echo " start 构建并启动服务 (默认)" + echo " stop 停止服务" + echo " restart 重启服务" + echo " logs 查看服务日志" + echo " status 查看服务状态" + echo " clean 清理容器和镜像" + echo " help 显示此帮助信息" + echo "" + echo "环境变量:" + echo " PORT 服务端口 (默认: 3020)" + echo "" + echo "示例:" + echo " ./deploy.sh start # 默认端口 3020 启动" + echo " PORT=8080 ./deploy.sh start # 指定端口 8080 启动" + echo "" +} + +# 主函数 +main() { + # 切换到脚本所在目录 + cd "$(dirname "$0")" + + # 检查环境 + check_docker + check_docker_compose + + # 执行命令 + case "${1:-start}" in + build) + build + ;; + start) + start + ;; + stop) + stop + ;; + restart) + restart + ;; + logs) + logs + ;; + status) + status + ;; + clean) + clean + ;; + help|--help|-h) + show_help + ;; + *) + log_error "未知命令: $1" + show_help + exit 1 + ;; + esac +} + +main "$@"