update
This commit is contained in:
parent
fd378b32c5
commit
9d6ba6cc29
37
Dockerfile
37
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"]
|
||||
@ -9,7 +9,23 @@ from urllib.parse import urljoin
|
||||
|
||||
from qcloud_cos import CosConfig, CosS3Client
|
||||
from qcloud_cos.cos_exception import CosServiceError, CosClientError
|
||||
|
||||
# 修改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
|
||||
|
||||
|
||||
71
check_dependencies.py
Executable file
71
check_dependencies.py
Executable file
@ -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())
|
||||
114
entrypoint.sh
114
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
|
||||
# 如果主要依赖都在,尝试连接数据库
|
||||
if [ $MISSING_VARS -eq 0 ]; then
|
||||
echo "尝试连接到数据库..."
|
||||
MAX_RETRIES=5
|
||||
RETRY_COUNT=0
|
||||
|
||||
# 检查依赖服务连接
|
||||
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 "数据库连接成功!"
|
||||
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 "警告:无法连接到数据库。服务将继续启动,但可能无法正常工作。"
|
||||
fi
|
||||
else
|
||||
echo "跳过数据库连接检查:未设置DB_HOST或DB_PORT"
|
||||
fi
|
||||
if [ $RETRY_COUNT -lt $MAX_RETRIES ]; then
|
||||
echo "数据库连接成功!"
|
||||
|
||||
# 应用数据库迁移
|
||||
echo "应用数据库迁移..."
|
||||
if [ -f "create_migration.py" ]; then
|
||||
python create_migration.py upgrade || echo "警告:数据库迁移失败,但将继续启动服务"
|
||||
else
|
||||
echo "未找到create_migration.py,跳过数据库迁移"
|
||||
python3 create_migration.py upgrade
|
||||
fi
|
||||
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
|
||||
# 启动应用
|
||||
echo "启动API服务..."
|
||||
exec "$@"
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user