From 9d6ba6cc292269af076c55b8fbad83c0b088b532 Mon Sep 17 00:00:00 2001 From: aaron <> Date: Fri, 21 Mar 2025 23:02:15 +0800 Subject: [PATCH] update --- Dockerfile | 37 ++++++++-- app/services/qcloud_service.py | 20 +++++- check_dependencies.py | 71 +++++++++++++++++++ entrypoint.sh | 122 ++++++++++++--------------------- requirements.txt | 1 + 5 files changed, 165 insertions(+), 86 deletions(-) create mode 100755 check_dependencies.py diff --git a/Dockerfile b/Dockerfile index 85474c5..a282f43 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,9 @@ # 使用Python 3.10作为基础镜像 FROM python:3.10-slim +# 设置工作目录 +WORKDIR /app + # 设置时区 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime # 清空所有默认源 @@ -24,22 +27,42 @@ RUN apt-get update \ && apt-get install -y --no-install-recommends \ build-essential \ default-libmysqlclient-dev \ + default-mysql-client \ pkg-config \ + curl \ && rm -rf /var/lib/apt/lists/* -# 设置工作目录 -WORKDIR /app - # 复制项目文件 COPY requirements.txt . -COPY app app/ + +# 显示当前的requirements.txt内容 +RUN echo "========== requirements.txt content ==========" && \ + cat requirements.txt && \ + echo "==============================================" # 安装Python依赖 -RUN pip install -i https://mirrors.aliyun.com/pypi/simple/ -r requirements.txt \ - && pip install uvicorn +RUN pip install -i https://mirrors.aliyun.com/pypi/simple/ --no-cache-dir -r requirements.txt \ + && pip install -i https://mirrors.aliyun.com/pypi/simple/ --no-cache-dir uvicorn \ + && pip list + +# 复制应用程序代码 +COPY . . + +# 添加执行权限 +RUN chmod +x entrypoint.sh + +# 设置PYTHONPATH +ENV PYTHONPATH=/app # 暴露端口 EXPOSE 8000 -# 启动命令 +# 添加健康检查 +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:8000/health || exit 1 + +# 设置入口点 +ENTRYPOINT ["/app/entrypoint.sh"] + +# 默认命令 CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/app/services/qcloud_service.py b/app/services/qcloud_service.py index 4399e9d..4d2a0f3 100644 --- a/app/services/qcloud_service.py +++ b/app/services/qcloud_service.py @@ -9,7 +9,23 @@ from urllib.parse import urljoin from qcloud_cos import CosConfig, CosS3Client from qcloud_cos.cos_exception import CosServiceError, CosClientError -import sts.sts + +# 修改STS导入方式 +try: + # 尝试直接从安装的包导入 + from qcloud_python_sts.sts import Sts +except ImportError: + try: + # 尝试旧的导入方式 + import sts.sts + Sts = sts.sts.Sts + except ImportError: + # 如果都不存在,记录错误 + logging.error("无法导入腾讯云STS SDK,请检查qcloud-python-sts是否已安装") + # 创建一个空类,避免运行时错误,但实际使用时会报错提示 + class Sts: + def __init__(self, *args, **kwargs): + raise ImportError("腾讯云STS SDK未正确安装,请执行 pip install qcloud-python-sts") from app.utils.config import get_settings @@ -192,7 +208,7 @@ class QCloudCOSService: } } - sts_client = sts.sts.Sts(config) + sts_client = Sts(config) response = sts_client.get_credential() return response diff --git a/check_dependencies.py b/check_dependencies.py new file mode 100755 index 0000000..1d4e6ab --- /dev/null +++ b/check_dependencies.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +""" +依赖检查脚本 - 在应用启动前检查所有必要依赖是否已正确安装 +""" + +import importlib +import sys +import logging + +# 配置日志 +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" +) +logger = logging.getLogger("依赖检查") + +# 定义必要的依赖列表 +REQUIRED_PACKAGES = [ + ("fastapi", "FastAPI框架"), + ("uvicorn", "ASGI服务器"), + ("sqlalchemy", "ORM数据库框架"), + ("alembic", "数据库迁移工具"), + ("pymysql", "MySQL驱动"), + ("dashscope", "阿里云DashScope SDK"), + ("qcloud_cos", "腾讯云COS SDK"), + ("qcloud_python_sts", "腾讯云STS SDK", ["qcloud_python_sts.sts", "sts.sts"]), + ("dotenv", "环境变量处理", ["dotenv", "python_dotenv"]), +] + +def check_dependency(package_name, description, import_names=None): + """检查依赖是否已安装""" + if import_names is None: + import_names = [package_name] + + for import_name in import_names: + try: + importlib.import_module(import_name) + logger.info(f"✅ {description} ({package_name}) 已安装") + return True + except ImportError: + continue + + logger.error(f"❌ {description} ({package_name}) 未安装或无法导入") + return False + +def main(): + """检查所有依赖""" + logger.info("开始检查依赖...") + + all_dependencies_ok = True + + for package_info in REQUIRED_PACKAGES: + if len(package_info) == 2: + package_name, description = package_info + import_names = None + else: + package_name, description, import_names = package_info + + if not check_dependency(package_name, description, import_names): + all_dependencies_ok = False + + if all_dependencies_ok: + logger.info("所有依赖检查通过 ✓") + return 0 + else: + logger.error("存在未安装或无法导入的依赖,请安装后再试") + logger.error("可以运行 pip install -r requirements.txt 安装所有依赖") + return 1 + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh index 92a9900..3789f11 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,93 +1,61 @@ #!/bin/bash set -e -echo "正在启动AI Dressing服务..." +# 显示当前环境 +echo "============================================" +echo "容器启动 - 环境: ${ENV:-production}" +echo "============================================" -# 检查是否存在.env文件,不存在则使用内置的.env.built -if [ ! -f ".env" ]; then - echo "未找到.env文件,使用构建时创建的.env.built文件" - if [ -f ".env.built" ]; then - cp .env.built .env - echo "已复制.env.built到.env" - else - echo "警告:未找到.env.built文件,将使用系统环境变量" - fi -else - echo "使用已存在的.env文件" +# 检查是否存在.env文件 +if [ -f .env ]; then + echo "从.env文件加载环境变量..." + export $(grep -v '^#' .env | xargs) fi -# 输出关键环境变量(隐藏敏感信息) -echo "检查关键环境变量:" -# 数据库配置 -if [ -n "$DB_HOST" ]; then - echo "- DB_HOST: 已设置 ✓" -else - echo "- DB_HOST: 未设置 ❌" -fi +# 检查关键环境变量 +echo "检查关键环境变量..." +MISSING_VARS=0 -if [ -n "$DB_PORT" ]; then - echo "- DB_PORT: 已设置 ✓" -else - echo "- DB_PORT: 未设置 ❌" -fi +# 检查数据库配置 +if [ -z "$DB_HOST" ]; then echo "警告: DB_HOST 未设置"; MISSING_VARS=$((MISSING_VARS+1)); fi +if [ -z "$DB_USER" ]; then echo "警告: DB_USER 未设置"; MISSING_VARS=$((MISSING_VARS+1)); fi +if [ -z "$DB_PASSWORD" ]; then echo "警告: DB_PASSWORD 未设置"; MISSING_VARS=$((MISSING_VARS+1)); fi +if [ -z "$DB_NAME" ]; then echo "警告: DB_NAME 未设置"; MISSING_VARS=$((MISSING_VARS+1)); fi -if [ -n "$DB_NAME" ]; then - echo "- DB_NAME: 已设置 ✓" -else - echo "- DB_NAME: 未设置 ❌" -fi +# 检查API密钥 +if [ -z "$DASHSCOPE_API_KEY" ]; then echo "警告: DASHSCOPE_API_KEY 未设置"; fi +if [ -z "$QCLOUD_SECRET_ID" ]; then echo "警告: QCLOUD_SECRET_ID 未设置"; fi +if [ -z "$QCLOUD_SECRET_KEY" ]; then echo "警告: QCLOUD_SECRET_KEY 未设置"; fi -# API密钥 -if [ -n "$DASHSCOPE_API_KEY" ]; then - echo "- DASHSCOPE_API_KEY: 已设置(已隐藏) ✓" -else - echo "- DASHSCOPE_API_KEY: 未设置 ❌" -fi +# 检查依赖 +echo "检查Python依赖..." +python3 check_dependencies.py -if [ -n "$QCLOUD_SECRET_ID" ] && [ -n "$QCLOUD_SECRET_KEY" ]; then - echo "- 腾讯云凭证: 已设置(已隐藏) ✓" -else - echo "- 腾讯云凭证: 未设置 ❌" -fi - -# 检查依赖服务连接 -echo "检查数据库连接..." -MAX_RETRIES=10 -COUNT=0 - -if [ -n "$DB_HOST" ] && [ -n "$DB_PORT" ]; then - while [ $COUNT -lt $MAX_RETRIES ]; do - if nc -z -w3 $DB_HOST $DB_PORT; then - echo "数据库连接成功!" +# 如果主要依赖都在,尝试连接数据库 +if [ $MISSING_VARS -eq 0 ]; then + echo "尝试连接到数据库..." + MAX_RETRIES=5 + RETRY_COUNT=0 + + until PGPASSWORD=$DB_PASSWORD mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" -e "SELECT 1" > /dev/null 2>&1; do + RETRY_COUNT=$((RETRY_COUNT+1)) + if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then + echo "无法连接到数据库 - 达到最大重试次数" break fi - echo "等待数据库连接... ($((COUNT+1))/$MAX_RETRIES)" - COUNT=$((COUNT+1)) - sleep 2 + echo "无法连接到数据库,将在5秒后重试... ($RETRY_COUNT/$MAX_RETRIES)" + sleep 5 done - - if [ $COUNT -eq $MAX_RETRIES ]; then - echo "警告:无法连接到数据库。服务将继续启动,但可能无法正常工作。" + + if [ $RETRY_COUNT -lt $MAX_RETRIES ]; then + echo "数据库连接成功!" + + # 应用数据库迁移 + echo "应用数据库迁移..." + python3 create_migration.py upgrade fi -else - echo "跳过数据库连接检查:未设置DB_HOST或DB_PORT" fi -# 应用数据库迁移 -echo "应用数据库迁移..." -if [ -f "create_migration.py" ]; then - python create_migration.py upgrade || echo "警告:数据库迁移失败,但将继续启动服务" -else - echo "未找到create_migration.py,跳过数据库迁移" -fi - -# 启动服务 -echo "AI Dressing服务启动中..." -# 根据环境变量决定是否使用热重载 -if [ "$ENV" = "development" ]; then - echo "以开发模式启动,启用热重载..." - exec uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload -else - echo "以生产模式启动..." - exec uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4 -fi \ No newline at end of file +# 启动应用 +echo "启动API服务..." +exec "$@" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 1c2a3d3..0c0eaf2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,6 +17,7 @@ dashscope>=1.5.0,<1.6.0 # 腾讯云SDK cos-python-sdk-v5>=1.9.0,<2.0.0 +qcloud-python-sts>=3.0.0,<4.0.0 # 工具库 python-dotenv>=0.19.1,<0.20.0