Compare commits
8 Commits
2f47193059
...
7555de2275
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7555de2275 | ||
|
|
344d8c1770 | ||
|
|
8892511f10 | ||
|
|
973ce53bf3 | ||
|
|
9c916195c6 | ||
|
|
20905b72cc | ||
|
|
e110067840 | ||
|
|
879247c8e9 |
@@ -43,9 +43,18 @@ RUN pip install --upgrade pip && \
|
||||
# 复制应用代码
|
||||
COPY app/ ./app/
|
||||
|
||||
# 复制启动脚本
|
||||
COPY start.sh ./start.sh
|
||||
RUN chmod +x ./start.sh
|
||||
|
||||
# 创建上传目录和日志目录
|
||||
RUN mkdir -p uploads logs
|
||||
|
||||
# 默认环境变量(可通过docker-compose或环境变量覆盖)
|
||||
ENV WORKERS=4 \
|
||||
RELOAD=false \
|
||||
TIMEOUT_KEEP_ALIVE=600
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 8000
|
||||
|
||||
@@ -53,5 +62,5 @@ EXPOSE 8000
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD curl -f http://localhost:8000/health || exit 1
|
||||
|
||||
# 启动命令(生产模式,无热重载)
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4", "--timeout-keep-alive", "600"]
|
||||
# 使用启动脚本
|
||||
CMD ["./start.sh"]
|
||||
@@ -87,6 +87,14 @@ class GrowthPathNode(BaseModel, SoftDeleteMixin):
|
||||
Integer, default=7, nullable=False, comment="预计学习天数"
|
||||
)
|
||||
|
||||
# 画布位置(用于可视化编辑器)
|
||||
position_x: Mapped[Optional[int]] = mapped_column(
|
||||
Integer, nullable=True, default=0, comment="画布X坐标"
|
||||
)
|
||||
position_y: Mapped[Optional[int]] = mapped_column(
|
||||
Integer, nullable=True, default=0, comment="画布Y坐标"
|
||||
)
|
||||
|
||||
# 关联关系
|
||||
growth_path: Mapped["GrowthPath"] = relationship( # noqa: F821
|
||||
"GrowthPath", back_populates="nodes"
|
||||
|
||||
@@ -28,6 +28,8 @@ class NodeBase(BaseModel):
|
||||
is_required: bool = Field(True, description="是否必修")
|
||||
prerequisites: Optional[List[int]] = Field(None, description="前置节点IDs")
|
||||
estimated_days: int = Field(7, description="预计学习天数")
|
||||
position_x: Optional[int] = Field(0, description="画布X坐标")
|
||||
position_y: Optional[int] = Field(0, description="画布Y坐标")
|
||||
|
||||
|
||||
# =====================================================
|
||||
|
||||
@@ -95,6 +95,8 @@ class GrowthPathService:
|
||||
is_required=node_data.is_required,
|
||||
prerequisites=node_data.prerequisites,
|
||||
estimated_days=node_data.estimated_days,
|
||||
position_x=node_data.position_x,
|
||||
position_y=node_data.position_y,
|
||||
)
|
||||
db.add(node)
|
||||
|
||||
@@ -147,6 +149,8 @@ class GrowthPathService:
|
||||
is_required=node_data.is_required,
|
||||
prerequisites=node_data.prerequisites,
|
||||
estimated_days=node_data.estimated_days,
|
||||
position_x=node_data.position_x,
|
||||
position_y=node_data.position_y,
|
||||
)
|
||||
db.add(node)
|
||||
|
||||
@@ -222,6 +226,8 @@ class GrowthPathService:
|
||||
"is_required": node.is_required,
|
||||
"prerequisites": node.prerequisites,
|
||||
"estimated_days": node.estimated_days,
|
||||
"position_x": node.position_x,
|
||||
"position_y": node.position_y,
|
||||
"created_at": node.created_at,
|
||||
"updated_at": node.updated_at,
|
||||
})
|
||||
|
||||
@@ -1,64 +1,38 @@
|
||||
#!/bin/bash
|
||||
# 统一启动脚本 - 根据环境变量自动配置
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
# 默认配置
|
||||
HOST=${HOST:-0.0.0.0}
|
||||
PORT=${PORT:-8000}
|
||||
WORKERS=${WORKERS:-1}
|
||||
RELOAD=${RELOAD:-false}
|
||||
TIMEOUT_KEEP_ALIVE=${TIMEOUT_KEEP_ALIVE:-600}
|
||||
|
||||
echo -e "${GREEN}考培练系统后端启动脚本${NC}"
|
||||
echo "================================"
|
||||
echo "=============================================="
|
||||
echo " KaoPeiLian Backend Starting..."
|
||||
echo "=============================================="
|
||||
echo " HOST: $HOST"
|
||||
echo " PORT: $PORT"
|
||||
echo " WORKERS: $WORKERS"
|
||||
echo " RELOAD: $RELOAD"
|
||||
echo " TIMEOUT_KEEP_ALIVE: $TIMEOUT_KEEP_ALIVE"
|
||||
echo "=============================================="
|
||||
|
||||
# 检查Python版本
|
||||
echo -e "${YELLOW}检查Python版本...${NC}"
|
||||
python_version=$(python3 --version 2>&1)
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo -e "${GREEN}✓ $python_version${NC}"
|
||||
# 构建启动命令
|
||||
CMD="uvicorn app.main:app --host $HOST --port $PORT --timeout-keep-alive $TIMEOUT_KEEP_ALIVE"
|
||||
|
||||
if [ "$RELOAD" = "true" ]; then
|
||||
# 开发模式:启用热重载(不支持多workers)
|
||||
CMD="$CMD --reload --reload-dir /app/app"
|
||||
echo "Mode: Development (hot reload enabled)"
|
||||
else
|
||||
echo -e "${RED}✗ Python3未安装${NC}"
|
||||
exit 1
|
||||
# 生产模式:多workers
|
||||
CMD="$CMD --workers $WORKERS"
|
||||
echo "Mode: Production ($WORKERS workers)"
|
||||
fi
|
||||
|
||||
# 检查虚拟环境
|
||||
if [ ! -d "venv" ]; then
|
||||
echo -e "${YELLOW}创建虚拟环境...${NC}"
|
||||
python3 -m venv venv
|
||||
fi
|
||||
echo ""
|
||||
echo "Executing: $CMD"
|
||||
echo ""
|
||||
|
||||
# 激活虚拟环境
|
||||
echo -e "${YELLOW}激活虚拟环境...${NC}"
|
||||
source venv/bin/activate
|
||||
|
||||
# 安装依赖
|
||||
echo -e "${YELLOW}安装依赖...${NC}"
|
||||
pip install -q -r requirements/base.txt
|
||||
|
||||
# 检查.env文件
|
||||
if [ ! -f ".env" ]; then
|
||||
echo -e "${YELLOW}创建.env文件...${NC}"
|
||||
cp .env.example .env
|
||||
echo -e "${GREEN}✓ 已创建.env文件,请根据需要修改配置${NC}"
|
||||
fi
|
||||
|
||||
# 检查数据库连接
|
||||
echo -e "${YELLOW}检查数据库连接...${NC}"
|
||||
python -c "
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
db_url = os.getenv('DATABASE_URL', '')
|
||||
if 'mysql' in db_url:
|
||||
print('✓ 数据库配置已设置')
|
||||
else:
|
||||
print('⚠ 请检查数据库配置')
|
||||
" 2>/dev/null
|
||||
|
||||
# 启动服务
|
||||
echo -e "${GREEN}启动开发服务器...${NC}"
|
||||
echo "================================"
|
||||
echo -e "API文档: ${GREEN}http://localhost:8000/api/docs${NC}"
|
||||
echo -e "健康检查: ${GREEN}http://localhost:8000/health${NC}"
|
||||
echo "================================"
|
||||
|
||||
# 启动uvicorn
|
||||
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
||||
exec $CMD
|
||||
|
||||
@@ -78,16 +78,17 @@ services:
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- PYTHONPATH=/app
|
||||
- WORKERS=4 # 生产环境4个workers
|
||||
- RELOAD=false # 生产环境关闭热重载
|
||||
ports:
|
||||
- "8010:8000"
|
||||
volumes:
|
||||
- ./kaopeilian-backend/app:/app/app # 代码热重载
|
||||
- ./kaopeilian-backend/app:/app/app
|
||||
- /data/prod-envs/uploads-hua:/app/uploads
|
||||
- /data/prod-envs/logs-hua:/app/logs
|
||||
- /data/prod-envs/secrets:/app/secrets:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
||||
networks:
|
||||
- prod-network
|
||||
- kaopeilian-network
|
||||
@@ -164,16 +165,17 @@ services:
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- PYTHONPATH=/app
|
||||
- WORKERS=4
|
||||
- RELOAD=false
|
||||
ports:
|
||||
- "8011:8000"
|
||||
volumes:
|
||||
- ./kaopeilian-backend/app:/app/app # 代码热重载
|
||||
- ./kaopeilian-backend/app:/app/app
|
||||
- /data/prod-envs/uploads-yy:/app/uploads
|
||||
- /data/prod-envs/logs-yy:/app/logs
|
||||
- /data/prod-envs/secrets:/app/secrets:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
||||
networks:
|
||||
- prod-network
|
||||
- kaopeilian-network
|
||||
@@ -250,16 +252,17 @@ services:
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- PYTHONPATH=/app
|
||||
- WORKERS=4
|
||||
- RELOAD=false
|
||||
ports:
|
||||
- "8012:8000"
|
||||
volumes:
|
||||
- ./kaopeilian-backend/app:/app/app # 代码热重载
|
||||
- ./kaopeilian-backend/app:/app/app
|
||||
- /data/prod-envs/uploads-hl:/app/uploads
|
||||
- /data/prod-envs/logs-hl:/app/logs
|
||||
- /data/prod-envs/secrets:/app/secrets:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
||||
networks:
|
||||
- prod-network
|
||||
- kaopeilian-network
|
||||
@@ -336,16 +339,17 @@ services:
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- PYTHONPATH=/app
|
||||
- WORKERS=4
|
||||
- RELOAD=false
|
||||
ports:
|
||||
- "8013:8000"
|
||||
volumes:
|
||||
- ./kaopeilian-backend/app:/app/app # 代码热重载
|
||||
- ./kaopeilian-backend/app:/app/app
|
||||
- /data/prod-envs/uploads-xy:/app/uploads
|
||||
- /data/prod-envs/logs-xy:/app/logs
|
||||
- /data/prod-envs/secrets:/app/secrets:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
||||
networks:
|
||||
- prod-network
|
||||
- kaopeilian-network
|
||||
@@ -423,16 +427,17 @@ services:
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- PYTHONPATH=/app
|
||||
- WORKERS=4
|
||||
- RELOAD=false
|
||||
ports:
|
||||
- "8014:8000"
|
||||
volumes:
|
||||
- ./kaopeilian-backend/app:/app/app # 代码热重载
|
||||
- ./kaopeilian-backend/app:/app/app
|
||||
- /data/prod-envs/uploads-fw:/app/uploads
|
||||
- /data/prod-envs/logs-fw:/app/logs
|
||||
- /data/prod-envs/secrets:/app/secrets:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
||||
networks:
|
||||
- prod-network
|
||||
- kaopeilian-network
|
||||
@@ -508,6 +513,8 @@ services:
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- PYTHONPATH=/app
|
||||
- WORKERS=4
|
||||
- RELOAD=false
|
||||
ports:
|
||||
- "8016:8000"
|
||||
volumes:
|
||||
@@ -517,7 +524,6 @@ services:
|
||||
- /data/prod-envs/secrets:/app/secrets:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
||||
networks:
|
||||
- prod-network
|
||||
- kaopeilian-network
|
||||
|
||||
100
docs/测试环境配置.md
100
docs/测试环境配置.md
@@ -1,6 +1,6 @@
|
||||
# 考培练系统 - 环境配置与部署指南
|
||||
|
||||
> 最后更新:2026-01-28
|
||||
> 最后更新:2026-02-03
|
||||
|
||||
## 一、环境总览
|
||||
|
||||
@@ -156,7 +156,94 @@ npm run build
|
||||
|
||||
---
|
||||
|
||||
## 六、容器管理
|
||||
## 六、对象存储(MinIO)
|
||||
|
||||
> 2026-02-03 新增,用于统一管理所有租户的文件存储
|
||||
|
||||
### 6.1 服务信息
|
||||
|
||||
| 项目 | 值 |
|
||||
|------|-----|
|
||||
| **容器名** | kaopeilian-minio |
|
||||
| **API端口** | 9000 |
|
||||
| **管理界面端口** | 9001 |
|
||||
| **数据目录** | /data/minio/data |
|
||||
| **网络** | prod-network |
|
||||
|
||||
### 6.2 访问方式
|
||||
|
||||
- **管理界面**: http://120.79.247.16:9001
|
||||
- **API端点**: http://kaopeilian-minio:9000(容器内)
|
||||
- **用户名**: `kaopeilian_admin`
|
||||
- **密码**: `KplMinio2026!@#`
|
||||
|
||||
### 6.3 Bucket列表
|
||||
|
||||
| Bucket名称 | 租户 | 说明 |
|
||||
|-----------|------|------|
|
||||
| kpl-ex | 恩喜成都总院 | 生产环境 |
|
||||
| kpl-hua | 华尔倍丽 | 生产环境 |
|
||||
| kpl-yy | 杨扬宠物 | 生产环境 |
|
||||
| kpl-hl | 武汉禾丽 | 生产环境 |
|
||||
| kpl-xy | 芯颜定制 | 生产环境 |
|
||||
| kpl-fw | 飞沃 | 生产环境 |
|
||||
| kpl-cxw | 崔曦文 | 生产环境 |
|
||||
| kpl-demo | 演示环境 | 预生产 |
|
||||
| kpl-kpl | KPL测试 | 测试环境 |
|
||||
| kpl-peilian | 陪练项目 | 其他项目 |
|
||||
|
||||
### 6.4 后端配置
|
||||
|
||||
在 `.env` 或环境变量中设置:
|
||||
|
||||
```bash
|
||||
# MinIO配置
|
||||
MINIO_ENABLED=true
|
||||
MINIO_ENDPOINT=kaopeilian-minio:9000
|
||||
MINIO_ACCESS_KEY=kaopeilian_admin
|
||||
MINIO_SECRET_KEY=KplMinio2026!@#
|
||||
MINIO_SECURE=false
|
||||
```
|
||||
|
||||
### 6.5 常用命令
|
||||
|
||||
```bash
|
||||
# SSH登录服务器后
|
||||
|
||||
# 查看MinIO状态
|
||||
docker ps | grep minio
|
||||
|
||||
# 查看MinIO日志
|
||||
docker logs kaopeilian-minio --tail 50
|
||||
|
||||
# 使用mc客户端操作
|
||||
mc ls kpl/ # 列出所有bucket
|
||||
mc ls kpl/kpl-ex/ # 列出ex租户文件
|
||||
mc cp file.pdf kpl/kpl-ex/ # 上传文件
|
||||
mc rm kpl/kpl-ex/file.pdf # 删除文件
|
||||
```
|
||||
|
||||
### 6.6 架构说明
|
||||
|
||||
```
|
||||
用户上传文件
|
||||
↓
|
||||
后端 storage_service
|
||||
↓
|
||||
MinIO对象存储(持久化)+ 本地缓存(加速预览)
|
||||
↓
|
||||
Nginx代理 → 用户下载
|
||||
```
|
||||
|
||||
**特性**:
|
||||
- 自动降级:MinIO不可用时自动使用本地存储
|
||||
- URL兼容:保持 `/static/uploads/` 格式,前端无需改动
|
||||
- 智能缓存:文件自动下载到本地缓存用于预览/分析
|
||||
- 多租户隔离:每个租户独立Bucket
|
||||
|
||||
---
|
||||
|
||||
## 七、容器管理
|
||||
|
||||
### 当前运行容器统计
|
||||
|
||||
@@ -166,8 +253,9 @@ npm run build
|
||||
| 后端容器 | 11 |
|
||||
| Redis | 10 |
|
||||
| MySQL | 4 |
|
||||
| MinIO | 1 |
|
||||
| Nginx | 1 |
|
||||
| **总计** | **37** |
|
||||
| **总计** | **38** |
|
||||
|
||||
### 查看所有容器
|
||||
|
||||
@@ -177,7 +265,7 @@ docker ps --format 'table {{.Names}}\t{{.Status}}'
|
||||
|
||||
---
|
||||
|
||||
## 七、测试账户
|
||||
## 八、测试账户
|
||||
|
||||
| 角色 | 用户名 | 密码 |
|
||||
|------|--------|------|
|
||||
@@ -187,7 +275,7 @@ docker ps --format 'table {{.Names}}\t{{.Status}}'
|
||||
|
||||
---
|
||||
|
||||
## 八、注意事项
|
||||
## 九、注意事项
|
||||
|
||||
1. **前端共享**:所有生产租户共享同一套前端代码,编译一次全部更新
|
||||
2. **后端独立**:每个租户有独立的后端容器和数据库
|
||||
@@ -198,7 +286,7 @@ docker ps --format 'table {{.Names}}\t{{.Status}}'
|
||||
|
||||
---
|
||||
|
||||
## 九、Git 仓库配置
|
||||
## 十、Git 仓库配置
|
||||
|
||||
```bash
|
||||
# 查看远程仓库
|
||||
|
||||
@@ -167,6 +167,8 @@ export interface CreateGrowthPathNode {
|
||||
is_required: boolean
|
||||
prerequisites?: number[]
|
||||
estimated_days: number
|
||||
position_x?: number // 画布X坐标
|
||||
position_y?: number // 画布Y坐标
|
||||
}
|
||||
|
||||
// 创建成长路径请求
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user