#!/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