#!/bin/bash # Photography Portfolio Docker Setup Script # 自动化Docker环境设置和部署 set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 日志函数 log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # 检查依赖 check_dependencies() { log_info "检查系统依赖..." if ! command -v docker &> /dev/null; then log_error "Docker 未安装,请先安装Docker" exit 1 fi if ! command -v docker-compose &> /dev/null; then log_error "Docker Compose 未安装,请先安装Docker Compose" exit 1 fi log_success "系统依赖检查完成" } # 创建环境文件 create_env_file() { log_info "创建环境配置文件..." if [ ! -f .env ]; then cat > .env << EOF # Photography Portfolio Environment Configuration # 数据库配置 DB_PASSWORD=photography_db_2024 POSTGRES_PASSWORD=photography_db_2024 # Redis配置 REDIS_PASSWORD=photography_redis_2024 # JWT配置 JWT_SECRET=photography_jwt_secret_super_secure_key_2024 # 应用配置 APP_ENV=production LOG_LEVEL=info # 前端配置 NEXT_PUBLIC_API_URL=https://api.photography.iriver.top REACT_APP_API_URL=https://api.photography.iriver.top # CORS配置 CORS_ORIGINS=https://photography.iriver.top,https://admin.photography.iriver.top # 监控配置 GRAFANA_PASSWORD=photography_grafana_2024 # 功能开关 NEXT_PUBLIC_ENABLE_ANALYTICS=false NEXT_PUBLIC_ENABLE_PWA=true EOF log_success "环境配置文件已创建 (.env)" else log_warning "环境配置文件已存在,跳过创建" fi } # 创建目录结构 create_directories() { log_info "创建必要的目录结构..." mkdir -p {configs,logs,data,backups,scripts} mkdir -p configs/{nginx,prometheus,grafana} mkdir -p data/{postgres,redis,uploads} log_success "目录结构创建完成" } # 构建镜像 build_images() { log_info "构建Docker镜像..." # 构建后端镜像 log_info "构建后端API镜像..." docker-compose build api # 构建前端镜像 log_info "构建前端镜像..." docker-compose build frontend # 构建管理后台镜像 if [ -d "admin" ]; then log_info "构建管理后台镜像..." docker-compose build admin fi log_success "Docker镜像构建完成" } # 初始化数据库 init_database() { log_info "初始化数据库..." # 启动数据库服务 docker-compose up -d db redis # 等待数据库启动 log_info "等待数据库启动..." sleep 30 # 运行数据库迁移 log_info "执行数据库迁移..." docker-compose run --rm migrate log_success "数据库初始化完成" } # 启动服务 start_services() { log_info "启动所有服务..." # 启动核心服务 docker-compose up -d db redis api frontend # 启动管理后台 if [ -d "admin" ]; then docker-compose up -d admin fi log_success "服务启动完成" } # 健康检查 health_check() { log_info "执行健康检查..." # 等待服务启动 sleep 10 # 检查数据库 if docker-compose exec db pg_isready -U postgres -d photography; then log_success "数据库连接正常" else log_error "数据库连接失败" return 1 fi # 检查Redis if docker-compose exec redis redis-cli ping; then log_success "Redis连接正常" else log_error "Redis连接失败" return 1 fi # 检查API服务 if curl -f http://localhost:8080/health; then log_success "API服务正常" else log_error "API服务异常" return 1 fi # 检查前端服务 if curl -f http://localhost:3000/health; then log_success "前端服务正常" else log_error "前端服务异常" return 1 fi log_success "所有服务健康检查通过" } # 显示服务状态 show_status() { log_info "服务状态信息:" echo "" docker-compose ps echo "" log_info "访问地址:" echo "前端网站: http://localhost:3000" echo "管理后台: http://localhost:3001" echo "API接口: http://localhost:8080" echo "API文档: http://localhost:8080/docs" echo "" log_info "数据库连接信息:" echo "主机: localhost:5432" echo "数据库: photography" echo "用户名: postgres" echo "" } # 清理函数 cleanup() { log_info "清理Docker资源..." # 停止所有服务 docker-compose down # 清理无用的镜像和容器 docker system prune -f log_success "清理完成" } # 备份数据 backup_data() { log_info "备份数据..." # 创建备份目录 BACKUP_DIR="backups/$(date +%Y%m%d_%H%M%S)" mkdir -p "$BACKUP_DIR" # 备份数据库 docker-compose exec db pg_dump -U postgres photography > "$BACKUP_DIR/database.sql" # 备份上传文件 docker run --rm -v photography_uploads_data:/data -v "$(pwd)/$BACKUP_DIR":/backup alpine tar czf /backup/uploads.tar.gz -C /data . log_success "数据备份完成: $BACKUP_DIR" } # 恢复数据 restore_data() { if [ -z "$1" ]; then log_error "请指定备份目录: ./docker-setup.sh restore /path/to/backup" exit 1 fi BACKUP_DIR="$1" if [ ! -d "$BACKUP_DIR" ]; then log_error "备份目录不存在: $BACKUP_DIR" exit 1 fi log_info "恢复数据从: $BACKUP_DIR" # 恢复数据库 if [ -f "$BACKUP_DIR/database.sql" ]; then docker-compose exec -T db psql -U postgres photography < "$BACKUP_DIR/database.sql" log_success "数据库恢复完成" fi # 恢复上传文件 if [ -f "$BACKUP_DIR/uploads.tar.gz" ]; then docker run --rm -v photography_uploads_data:/data -v "$(pwd)/$BACKUP_DIR":/backup alpine tar xzf /backup/uploads.tar.gz -C /data log_success "上传文件恢复完成" fi } # 主函数 main() { case "${1:-setup}" in "setup") log_info "开始Photography Portfolio Docker环境设置..." check_dependencies create_env_file create_directories build_images init_database start_services health_check show_status log_success "Docker环境设置完成!" ;; "start") log_info "启动服务..." docker-compose up -d health_check show_status ;; "stop") log_info "停止服务..." docker-compose down log_success "服务已停止" ;; "restart") log_info "重启服务..." docker-compose restart health_check show_status ;; "build") log_info "重新构建镜像..." build_images ;; "logs") log_info "查看服务日志..." docker-compose logs -f ;; "status") show_status ;; "clean") cleanup ;; "backup") backup_data ;; "restore") restore_data "$2" ;; "help") echo "Usage: $0 {setup|start|stop|restart|build|logs|status|clean|backup|restore}" echo "" echo "Commands:" echo " setup - 完整的环境设置和初始化" echo " start - 启动所有服务" echo " stop - 停止所有服务" echo " restart - 重启所有服务" echo " build - 重新构建Docker镜像" echo " logs - 查看服务日志" echo " status - 显示服务状态" echo " clean - 清理Docker资源" echo " backup - 备份数据" echo " restore - 恢复数据" echo " help - 显示帮助信息" ;; *) log_error "未知命令: $1" echo "使用 '$0 help' 查看可用命令" exit 1 ;; esac } # 执行主函数 main "$@"