main
mula.liu 2025-09-03 18:11:07 +08:00
parent d85f12fb9d
commit d6602435c4
7 changed files with 231 additions and 19 deletions

31
Dockerfile 100644
View File

@ -0,0 +1,31 @@
# 使用Python 3.9.6基础镜像
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/python:3.12.9-slim
# 设置工作目录
WORKDIR /app
# 设置环境变量
ENV PYTHONPATH=/app
ENV PYTHONUNBUFFERED=1
# 安装系统依赖
RUN apt-get update && apt-get install -y \
gcc \
default-libmysqlclient-dev \
pkg-config \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
COPY requirements-prod.txt .
# 安装Python依赖
RUN pip install --no-cache-dir -r requirements-prod.txt
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 8001
# 启动命令
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8001"]

View File

@ -22,7 +22,7 @@ MARKDOWN_DIR.mkdir(exist_ok=True)
DATABASE_CONFIG = {
'host': os.getenv('DB_HOST', 'localhost'),
'user': os.getenv('DB_USER', 'root'),
'password': os.getenv('DB_PASSWORD', ''),
'password': os.getenv('DB_PASSWORD', 'sagacity'),
'database': os.getenv('DB_NAME', 'imeeting'),
'port': int(os.getenv('DB_PORT', '3306')),
'charset': 'utf8mb4'
@ -31,8 +31,7 @@ DATABASE_CONFIG = {
# API配置
API_CONFIG = {
'host': os.getenv('API_HOST', '0.0.0.0'),
'port': int(os.getenv('API_PORT', '8000')),
'cors_origins': os.getenv('CORS_ORIGINS', 'http://localhost:5173').split(',')
'port': int(os.getenv('API_PORT', '8000'))
}
# 七牛云配置

View File

@ -2,24 +2,14 @@
from fastapi import HTTPException
import mysql.connector
from mysql.connector import Error
from app.core.config import DATABASE_CONFIG
from contextlib import contextmanager
DB_CONFIG = {
'host': 'localhost',
'database': 'imeeting',
'user': 'root',
'password': 'sagacity',
'port': 3306,
'charset': 'utf8mb4',
'autocommit': False, # 禁用自动提交
'consume_results': True # 自动消费未读结果
}
@contextmanager
def get_db_connection():
connection = None
try:
connection = mysql.connector.connect(**DB_CONFIG)
connection = mysql.connector.connect(**DATABASE_CONFIG)
yield connection
except Error as e:
print(f"数据库连接错误: {e}")

41
deploy-prod.sh 100755
View File

@ -0,0 +1,41 @@
#!/bin/bash
echo "🚀 开始部署iMeeting后端服务..."
# 检查虚拟环境
if [ ! -d "venv" ]; then
echo "❌ 虚拟环境不存在!请先创建虚拟环境"
exit 1
fi
echo "✅ 发现虚拟环境,继续部署..."
# 停止并删除现有容器
echo "📦 停止现有容器..."
docker-compose -f docker-compose.prod.yml down
# 构建新镜像
echo "🔨 构建Docker镜像..."
docker-compose -f docker-compose.prod.yml build --no-cache
# 启动服务
echo "▶️ 启动服务..."
docker-compose -f docker-compose.prod.yml up -d
# 检查服务状态
echo "🔍 检查服务状态..."
sleep 10
docker-compose -f docker-compose.prod.yml ps
# 检查健康状态
echo "🏥 检查健康状态..."
curl -f http://localhost:8001/health && echo "✅ 后端服务健康检查通过" || echo "❌ 后端服务健康检查失败"
echo ""
echo "🎉 部署完成!"
echo "🔧 后端服务访问地址: http://localhost:8001"
echo "📊 查看日志: docker-compose -f docker-compose.prod.yml logs -f"
echo "🛑 停止服务: docker-compose -f docker-compose.prod.yml down"
echo ""
echo "💡 提示:如需更新后端,请:"
echo " 1. 修改代码后运行 ./deploy-prod.sh 重新部署"

View File

@ -0,0 +1,59 @@
version: '3.8'
services:
imeeting-backend:
build:
context: .
dockerfile: Dockerfile
ports:
- "8001:8001"
environment:
# Python运行环境
- PYTHONPATH=/app
- PYTHONUNBUFFERED=1
# 数据库配置
- DB_HOST=host.docker.internal
- DB_USER=root
- DB_PASSWORD=sagacity
- DB_NAME=imeeting
- DB_PORT=3306
# Redis配置
- REDIS_HOST=host.docker.internal
- REDIS_PORT=6379
- REDIS_DB=6
- REDIS_PASSWORD=
# API配置
- API_HOST=0.0.0.0
- API_PORT=8001
# 应用配置
- BASE_URL=http://imeeting.unisspace.com
# 七牛云配置
- QINIU_ACCESS_KEY=A0tp96HCtg-wZCughTgi5vc2pJnw3btClwxRE_e8
- QINIU_SECRET_KEY=Lj-MSHpaVbmzpS86kMIjmwikvYOT9iPBjCk9hm6k
- QINIU_BUCKET=imeeting
- QINIU_DOMAIN=t0vogyxkz.hn-bkt.clouddn.com
# LLM配置
- QWEN_API_KEY=sk-c2bf06ea56b4491ea3d1e37fdb472b8f
- LLM_MODEL_NAME=qwen-plus
- LLM_API_URL=https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation
- LLM_MAX_TOKENS=2000
- LLM_TEMPERATURE=0.7
- LLM_TOP_P=0.9
volumes:
# 挂载上传目录保持数据持久化
- ./uploads:/app/uploads
restart: unless-stopped
container_name: imeeting-backend
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8001/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s

42
main.py
View File

@ -1,9 +1,9 @@
import uvicorn
from fastapi import FastAPI
from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from app.api.endpoints import auth, users, meetings
from app.core.config import UPLOAD_DIR, API_CONFIG
from app.core.config import UPLOAD_DIR, API_CONFIG, MAX_FILE_SIZE
import os
app = FastAPI(
@ -12,10 +12,23 @@ app = FastAPI(
version="1.0.0"
)
# 添加请求体大小检查中间件
@app.middleware("http")
async def check_content_size(request: Request, call_next):
# 检查Content-Length头
content_length = request.headers.get("content-length")
if content_length:
content_length = int(content_length)
if content_length > MAX_FILE_SIZE:
raise HTTPException(status_code=413, detail=f"Request entity too large. Maximum size is {MAX_FILE_SIZE//1024//1024}MB")
response = await call_next(request)
return response
# 添加CORS中间件
app.add_middleware(
CORSMiddleware,
allow_origins=API_CONFIG['cors_origins'],
# allow_origins=API_CONFIG['cors_origins'],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
@ -34,5 +47,26 @@ app.include_router(meetings.router, prefix="/api", tags=["Meetings"])
def read_root():
return {"message": "Welcome to iMeeting API"}
@app.get("/health")
def health_check():
"""健康检查端点"""
return {
"status": "healthy",
"service": "iMeeting API",
"version": "1.0.0"
}
if __name__ == "__main__":
uvicorn.run(app, host=API_CONFIG['host'], port=API_CONFIG['port'])
# 简单的uvicorn配置避免参数冲突
uvicorn.run(
"main:app",
host=API_CONFIG['host'],
port=API_CONFIG['port'],
limit_max_requests=1000,
timeout_keep_alive=30,
reload=True,
# 设置更大的请求体限制以支持音频文件上传
h11_max_incomplete_event_size=104857600, # 100MB
)

View File

@ -0,0 +1,58 @@
aiohappyeyeballs==2.6.1
aiohttp==3.12.15
aiosignal==1.4.0
annotated-types==0.7.0
anyio==3.7.1
async-timeout==5.0.1
attrs==25.3.0
bcrypt==4.3.0
certifi==2025.8.3
cffi==1.17.1
charset-normalizer==3.4.3
click==8.1.8
cryptography==45.0.6
dashscope==1.24.1
distro==1.9.0
dnspython==2.7.0
ecdsa==0.19.1
email_validator==2.2.0
exceptiongroup==1.3.0
fastapi==0.104.1
frozenlist==1.7.0
h11==0.16.0
httpcore==1.0.9
httptools==0.6.4
httpx==0.28.1
idna==3.10
jiter==0.10.0
multidict==6.6.4
mysql-connector-python==8.2.0
openai==1.99.9
passlib==1.7.4
propcache==0.3.2
protobuf==4.21.12
pyasn1==0.6.1
pycparser==2.22
pydantic==2.5.0
pydantic_core==2.14.1
PyJWT==2.10.1
python-dotenv==1.1.1
python-jose==3.5.0
python-multipart==0.0.6
PyYAML==6.0.2
qiniu==7.17.0
redis==6.4.0
requests==2.32.4
rsa==4.9.1
six==1.17.0
sniffio==1.3.1
starlette==0.27.0
tqdm==4.67.1
typing_extensions==4.14.1
urllib3==2.5.0
uvicorn==0.24.0
uvloop==0.21.0
watchfiles==1.1.0
websocket-client==1.8.0
websockets==15.0.1
yarl==1.20.1