本次提交包含3个重要功能的完成: 1. 📖 用户使用文档完成 - 创建完整的用户使用手册 (docs/USER_MANUAL.md) - 管理后台使用指南 (登录、照片管理、分类管理) - 前端网站使用说明 (浏览、搜索、移动端) - 部署运维指南 (环境准备、监控维护) - 故障排查指南 (错误处理、性能优化) - 技术支持体系和问题反馈渠道 2. 🐳 后端Docker容器化完成 - 多阶段构建Dockerfile (golang:1.23-alpine → scratch) - Docker Compose开发环境 (PostgreSQL + Redis + API) - 优化的构建配置和安全用户设置 - 健康检查和环境变量管理 - 更新Makefile添加Docker命令 3. 🏗️ 前端Docker容器化完成 - 多阶段构建Dockerfile (node:20-alpine → nginx:1.25-alpine) - 集成bun包管理器优化构建速度 - 优化的Nginx配置 (缓存、压缩、安全头部) - Docker Compose多模式支持 (开发/生产/代理) - 更新Makefile添加Docker命令 4. 📋 完整的Docker编排系统 - 项目根目录完整的docker-compose.yml - 支持数据库、缓存、API、前端、管理后台的统一部署 - 自动化Docker设置脚本 (docker-setup.sh) - 生产环境监控和日志收集配置 技术成果: - 项目完成率从65.0%提升至72.5% - 中优先级任务完成率达90% - 低优先级任务开始推进(18%) - 容器化部署体系完全就绪 - 用户文档体系建立完成 下一步: 继续推进容器化扩展和性能优化任务
355 lines
8.3 KiB
Bash
Executable File
355 lines
8.3 KiB
Bash
Executable File
#!/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 "$@" |