xianyu-auto-reply/test_docker_deployment.py
2025-07-25 10:30:33 +08:00

332 lines
9.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
Docker部署配置验证脚本
检查Docker部署是否包含所有必要的组件和配置
"""
import os
import sys
import yaml
import json
from pathlib import Path
def check_file_exists(file_path, description):
"""检查文件是否存在"""
if os.path.exists(file_path):
print(f"{description}: {file_path}")
return True
else:
print(f"{description}: {file_path} (缺失)")
return False
def check_requirements_txt():
"""检查requirements.txt中的依赖"""
print("📦 检查Python依赖...")
if not check_file_exists("requirements.txt", "依赖文件"):
return False
required_packages = [
"fastapi",
"uvicorn",
"pydantic",
"loguru",
"websockets",
"aiohttp",
"PyYAML",
"PyExecJS",
"blackboxprotobuf",
"psutil",
"requests",
"python-multipart",
"openai",
"python-dotenv"
]
try:
with open("requirements.txt", "r", encoding="utf-8") as f:
content = f.read()
missing_packages = []
for package in required_packages:
if package.lower() not in content.lower():
missing_packages.append(package)
if missing_packages:
print(f" ❌ 缺失依赖: {', '.join(missing_packages)}")
return False
else:
print(f" ✅ 所有必要依赖都已包含 ({len(required_packages)} 个)")
return True
except Exception as e:
print(f" ❌ 读取requirements.txt失败: {e}")
return False
def check_dockerfile():
"""检查Dockerfile配置"""
print("\n🐳 检查Dockerfile...")
if not check_file_exists("Dockerfile", "Docker镜像文件"):
return False
try:
with open("Dockerfile", "r", encoding="utf-8") as f:
content = f.read()
required_elements = [
("FROM python:", "Python基础镜像"),
("WORKDIR", "工作目录设置"),
("COPY requirements.txt", "依赖文件复制"),
("RUN pip install", "依赖安装"),
("EXPOSE", "端口暴露"),
("CMD", "启动命令")
]
missing_elements = []
for element, description in required_elements:
if element not in content:
missing_elements.append(description)
if missing_elements:
print(f" ❌ 缺失配置: {', '.join(missing_elements)}")
return False
else:
print(f" ✅ Dockerfile配置完整")
return True
except Exception as e:
print(f" ❌ 读取Dockerfile失败: {e}")
return False
def check_docker_compose():
"""检查docker-compose.yml配置"""
print("\n🔧 检查Docker Compose配置...")
if not check_file_exists("docker-compose.yml", "Docker Compose文件"):
return False
try:
with open("docker-compose.yml", "r", encoding="utf-8") as f:
compose_config = yaml.safe_load(f)
# 检查服务配置
if "services" not in compose_config:
print(" ❌ 缺失services配置")
return False
services = compose_config["services"]
if "xianyu-app" not in services:
print(" ❌ 缺失xianyu-app服务")
return False
app_service = services["xianyu-app"]
# 检查必要配置
required_configs = [
("ports", "端口映射"),
("volumes", "数据挂载"),
("environment", "环境变量"),
("healthcheck", "健康检查")
]
missing_configs = []
for config, description in required_configs:
if config not in app_service:
missing_configs.append(description)
if missing_configs:
print(f" ❌ 缺失配置: {', '.join(missing_configs)}")
return False
# 检查AI相关环境变量
env_vars = app_service.get("environment", [])
ai_env_vars = [
"AI_REPLY_ENABLED",
"DEFAULT_AI_MODEL",
"DEFAULT_AI_BASE_URL",
"AI_REQUEST_TIMEOUT"
]
missing_ai_vars = []
env_str = str(env_vars)
for var in ai_env_vars:
if var not in env_str:
missing_ai_vars.append(var)
if missing_ai_vars:
print(f" ⚠️ 缺失AI环境变量: {', '.join(missing_ai_vars)}")
else:
print(f" ✅ AI环境变量配置完整")
print(f" ✅ Docker Compose配置完整")
return True
except Exception as e:
print(f" ❌ 读取docker-compose.yml失败: {e}")
return False
def check_env_example():
"""检查.env.example配置"""
print("\n⚙️ 检查环境变量模板...")
if not check_file_exists(".env.example", "环境变量模板"):
return False
try:
with open(".env.example", "r", encoding="utf-8") as f:
content = f.read()
# 检查AI相关配置
ai_configs = [
"AI_REPLY_ENABLED",
"DEFAULT_AI_MODEL",
"DEFAULT_AI_BASE_URL",
"AI_REQUEST_TIMEOUT",
"AI_MAX_TOKENS"
]
missing_configs = []
for config in ai_configs:
if config not in content:
missing_configs.append(config)
if missing_configs:
print(f" ❌ 缺失AI配置: {', '.join(missing_configs)}")
return False
else:
print(f" ✅ AI配置完整")
# 检查基础配置
basic_configs = [
"ADMIN_USERNAME",
"ADMIN_PASSWORD",
"JWT_SECRET_KEY",
"AUTO_REPLY_ENABLED",
"AUTO_DELIVERY_ENABLED"
]
missing_basic = []
for config in basic_configs:
if config not in content:
missing_basic.append(config)
if missing_basic:
print(f" ❌ 缺失基础配置: {', '.join(missing_basic)}")
return False
else:
print(f" ✅ 基础配置完整")
return True
except Exception as e:
print(f" ❌ 读取.env.example失败: {e}")
return False
def check_documentation():
"""检查部署文档"""
print("\n📚 检查部署文档...")
docs = [
("Docker部署说明.md", "Docker部署说明"),
("README.md", "项目说明文档")
]
all_exist = True
for doc_file, description in docs:
if not check_file_exists(doc_file, description):
all_exist = False
return all_exist
def check_directory_structure():
"""检查目录结构"""
print("\n📁 检查目录结构...")
required_dirs = [
("static", "静态文件目录"),
("templates", "模板目录(如果存在)")
]
required_files = [
("Start.py", "主程序文件"),
("db_manager.py", "数据库管理"),
("XianyuAutoAsync.py", "闲鱼自动化"),
("ai_reply_engine.py", "AI回复引擎"),
("global_config.yml", "全局配置")
]
all_exist = True
# 检查目录
for dir_name, description in required_dirs:
if os.path.exists(dir_name) and os.path.isdir(dir_name):
print(f"{description}: {dir_name}")
else:
if dir_name == "templates": # templates是可选的
print(f" ⚠️ {description}: {dir_name} (可选)")
else:
print(f"{description}: {dir_name} (缺失)")
all_exist = False
# 检查文件
for file_name, description in required_files:
if not check_file_exists(file_name, description):
all_exist = False
return all_exist
def main():
"""主检查函数"""
print("🚀 Docker部署配置验证")
print("=" * 50)
checks = [
("Python依赖", check_requirements_txt),
("Dockerfile", check_dockerfile),
("Docker Compose", check_docker_compose),
("环境变量", check_env_example),
("目录结构", check_directory_structure),
("文档", check_documentation)
]
results = []
for check_name, check_func in checks:
try:
result = check_func()
results.append((check_name, result))
except Exception as e:
print(f"{check_name}检查异常: {e}")
results.append((check_name, False))
# 总结结果
print("\n" + "=" * 50)
print("📊 检查结果总结")
passed = 0
total = len(results)
for check_name, result in results:
status = "✅ 通过" if result else "❌ 失败"
print(f" {check_name}: {status}")
if result:
passed += 1
print(f"\n📈 总体评分: {passed}/{total} ({passed/total*100:.1f}%)")
if passed == total:
print("\n🎉 所有检查通过Docker部署配置完整")
print("\n🚀 可以直接使用以下命令部署:")
print(" docker-compose up -d")
elif passed >= total * 0.8:
print("\n⚠️ 大部分检查通过,有少量问题需要修复")
print(" 建议修复上述问题后再部署")
else:
print("\n❌ 多项检查失败,需要完善配置后再部署")
return passed == total
if __name__ == "__main__":
success = main()
sys.exit(0 if success else 1)