This commit is contained in:
parent
b2ad58e30c
commit
22ee4fbaaa
|
|
@ -0,0 +1,308 @@
|
||||||
|
# Docker 部署指南(硬编码 KEY 版本)
|
||||||
|
|
||||||
|
## 📋 配置说明
|
||||||
|
|
||||||
|
本 Dockerfile 已经将所有 API 配置和密钥硬编码在镜像中:
|
||||||
|
|
||||||
|
### 已硬编码的配置
|
||||||
|
|
||||||
|
| 配置项 | 值 |
|
||||||
|
|--------|-----|
|
||||||
|
| API 端点 | `https://api.coze.cn/v1` ✅(包含 /v1 前缀) |
|
||||||
|
| COZE_API_KEY | `Bearer eyJhbGci...` ✅ |
|
||||||
|
| LLM_API_KEY | `Bearer eyJhbGci...` ✅ |
|
||||||
|
| COZE_WORKSPACE_ID | `7622238752642957347` ✅ |
|
||||||
|
| LLM_MODEL_NAME | `doubao-seed-2-0-pro-260215` ✅ |
|
||||||
|
|
||||||
|
### Workspace ID 来源
|
||||||
|
|
||||||
|
从 JWT Token 的 `sub` 字段提取:
|
||||||
|
```
|
||||||
|
spiffe://api.coze.cn/workload_identity/id:7622238752642957347
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 快速部署
|
||||||
|
|
||||||
|
### 步骤 1:构建镜像
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 进入项目根目录
|
||||||
|
cd /workspace/projects
|
||||||
|
|
||||||
|
# 构建镜像
|
||||||
|
docker build -t math-grading:latest .
|
||||||
|
```
|
||||||
|
|
||||||
|
### 步骤 2:运行容器
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 运行容器(简单方式)
|
||||||
|
docker run -d \
|
||||||
|
--name math-grading \
|
||||||
|
-p 8000:8000 \
|
||||||
|
--restart unless-stopped \
|
||||||
|
math-grading:latest
|
||||||
|
|
||||||
|
# 运行容器(完整方式,挂载日志和缓存)
|
||||||
|
docker run -d \
|
||||||
|
--name math-grading \
|
||||||
|
-p 8000:8000 \
|
||||||
|
-v $(pwd)/logs:/app/work/logs \
|
||||||
|
-v $(pwd)/cache:/tmp/homework_cache \
|
||||||
|
--restart unless-stopped \
|
||||||
|
math-grading:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### 步骤 3:验证服务
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看容器状态
|
||||||
|
docker ps | grep math-grading
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
docker logs -f math-grading
|
||||||
|
|
||||||
|
# 检查健康状态
|
||||||
|
curl http://localhost:8000/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧪 测试接口
|
||||||
|
|
||||||
|
### 测试 LLM 调用
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:8000/stream_run \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"student_homework": [
|
||||||
|
{
|
||||||
|
"student_id": 1,
|
||||||
|
"student_name": "测试学生",
|
||||||
|
"homework_images": [
|
||||||
|
"https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/18/69baa4f5-4826-4901-00e1-c6e66f02947f.jpg?x-oss-process=image/resize,w_1000"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"answer_doc_url": "",
|
||||||
|
"comment_max_length": 50,
|
||||||
|
"max_concurrent": 1
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 测试多图片批改
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:8000/stream_run \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"student_homework": [
|
||||||
|
{
|
||||||
|
"student_id": 1,
|
||||||
|
"student_name": "张三",
|
||||||
|
"homework_images": [
|
||||||
|
"https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/18/69baa4f5-4826-4901-00e1-c6e66f02947f.jpg?x-oss-process=image/resize,w_1000",
|
||||||
|
"https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/25/69c344ba-4826-4901-00e1-c6ff235a12b2.jpg?x-oss-process=image/resize,w_1000"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"answer_doc_url": "https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/25/69c353d0-4826-4901-00e1-c7081bcab988.docx",
|
||||||
|
"comment_max_length": 50,
|
||||||
|
"max_concurrent": 2
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 常用命令
|
||||||
|
|
||||||
|
### 容器管理
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 停止容器
|
||||||
|
docker stop math-grading
|
||||||
|
|
||||||
|
# 启动容器
|
||||||
|
docker start math-grading
|
||||||
|
|
||||||
|
# 重启容器
|
||||||
|
docker restart math-grading
|
||||||
|
|
||||||
|
# 删除容器
|
||||||
|
docker rm -f math-grading
|
||||||
|
|
||||||
|
# 删除镜像
|
||||||
|
docker rmi math-grading:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### 日志查看
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看实时日志
|
||||||
|
docker logs -f math-grading
|
||||||
|
|
||||||
|
# 查看最近 100 行日志
|
||||||
|
docker logs --tail 100 math-grading
|
||||||
|
|
||||||
|
# 查看错误日志
|
||||||
|
docker logs math-grading 2>&1 | grep ERROR
|
||||||
|
```
|
||||||
|
|
||||||
|
### 进入容器
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 进入容器 shell
|
||||||
|
docker exec -it math-grading /bin/bash
|
||||||
|
|
||||||
|
# 查看环境变量
|
||||||
|
docker exec math-grading env | grep COZE
|
||||||
|
|
||||||
|
# 运行 Python 脚本
|
||||||
|
docker exec math-grading python assets/check_env.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 验证配置成功
|
||||||
|
|
||||||
|
### 成功标志
|
||||||
|
|
||||||
|
1. **容器启动成功**
|
||||||
|
```bash
|
||||||
|
docker ps | grep math-grading
|
||||||
|
# 应该显示容器运行中(Up status)
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **日志无错误**
|
||||||
|
```bash
|
||||||
|
docker logs math-grading | grep ERROR
|
||||||
|
# 不应该有认证错误(401)或端点错误(404)
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **健康检查通过**
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8000/health
|
||||||
|
# 应该返回 200 OK
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **LLM 调用成功**
|
||||||
|
```bash
|
||||||
|
# 运行测试请求,日志应该显示:
|
||||||
|
# ✅ HTTP Request: POST https://api.coze.cn/v1/chat/completions "HTTP/1.1 200 OK"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 错误排查
|
||||||
|
|
||||||
|
#### 错误 1:容器无法启动
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看详细日志
|
||||||
|
docker logs math-grading
|
||||||
|
|
||||||
|
# 检查端口是否被占用
|
||||||
|
netstat -tuln | grep 8000
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 错误 2:LLM 调用 401 错误
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查环境变量是否正确设置
|
||||||
|
docker exec math-grading env | grep COZE_API_KEY
|
||||||
|
|
||||||
|
# 应该看到:
|
||||||
|
# COZE_API_KEY=Bearer eyJhbGci...
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 错误 3:LLM 调用 404 错误
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查 API 端点配置
|
||||||
|
docker exec math-grading env | grep BASE_URL
|
||||||
|
|
||||||
|
# 应该看到:
|
||||||
|
# COZE_INTEGRATION_BASE_URL=https://api.coze.cn/v1
|
||||||
|
# 注意要有 /v1 前缀
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔐 安全说明
|
||||||
|
|
||||||
|
### ⚠️ 密钥已硬编码
|
||||||
|
|
||||||
|
当前 Dockerfile 将 API Key 硬编码在镜像中:
|
||||||
|
- ✅ 优点:部署简单,无需额外配置
|
||||||
|
- ❌ 缺点:密钥会暴露在镜像中,存在安全风险
|
||||||
|
|
||||||
|
### 安全建议
|
||||||
|
|
||||||
|
1. **私有仓库**
|
||||||
|
- 使用私有 Docker Registry(如阿里云容器镜像服务)
|
||||||
|
- 不要将镜像推送到公共仓库
|
||||||
|
|
||||||
|
2. **访问控制**
|
||||||
|
- 限制镜像访问权限
|
||||||
|
- 使用 RBAC 控制镜像拉取
|
||||||
|
|
||||||
|
3. **定期更换密钥**
|
||||||
|
- 定期在 Coze 平台更换 API Key
|
||||||
|
- 重新构建镜像
|
||||||
|
|
||||||
|
4. **生产环境建议**
|
||||||
|
- 使用环境变量方式(推荐)
|
||||||
|
- 参考 `assets/docker-compose.yml`
|
||||||
|
|
||||||
|
## 📝 配置说明
|
||||||
|
|
||||||
|
### 环境变量列表
|
||||||
|
|
||||||
|
| 变量名 | 说明 | 值 |
|
||||||
|
|--------|------|-----|
|
||||||
|
| `COZE_API_KEY` | Coze API 认证密钥 | Bearer eyJhbGci... |
|
||||||
|
| `LLM_API_KEY` | LLM API 认证密钥 | Bearer eyJhbGci... |
|
||||||
|
| `COZE_WORKSPACE_ID` | 工作区 ID | 7622238752642957347 |
|
||||||
|
| `COZE_INTEGRATION_BASE_URL` | API 基础 URL | https://api.coze.cn/v1 |
|
||||||
|
| `COZE_INTEGRATION_MODEL_BASE_URL` | 模型 API 基础 URL | https://api.coze.cn/v1 |
|
||||||
|
| `LLM_BASE_URL` | LLM API 基础 URL | https://api.coze.cn/v1 |
|
||||||
|
| `LLM_MODEL_NAME` | LLM 模型名称 | doubao-seed-2-0-pro-260215 |
|
||||||
|
| `COZE_INTEGRATION_API_KEY` | 集成 API 密钥 | Bearer eyJhbGci... |
|
||||||
|
|
||||||
|
### 端口说明
|
||||||
|
|
||||||
|
| 端口 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| 8000 | HTTP 服务端口 |
|
||||||
|
|
||||||
|
### 目录说明
|
||||||
|
|
||||||
|
| 目录 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| /app | 应用工作目录 |
|
||||||
|
| /app/work/logs/bypass | 日志目录 |
|
||||||
|
| /tmp/homework_cache | 缓存目录 |
|
||||||
|
|
||||||
|
## 🎯 总结
|
||||||
|
|
||||||
|
### 一键部署命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 构建并运行
|
||||||
|
docker build -t math-grading:latest .
|
||||||
|
docker run -d --name math-grading -p 8000:8000 --restart unless-stopped math-grading:latest
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
docker logs -f math-grading
|
||||||
|
|
||||||
|
# 测试接口
|
||||||
|
curl -X POST http://localhost:8000/stream_run \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"student_homework": [{"student_id": 1, "homework_images": ["https://example.com/image.jpg"]}]}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 预期结果
|
||||||
|
|
||||||
|
- ✅ 容器正常运行
|
||||||
|
- ✅ 日志显示服务启动成功
|
||||||
|
- ✅ LLM 调用返回 200 OK
|
||||||
|
- ✅ 批改功能正常工作
|
||||||
|
|
||||||
|
### 关键修复点
|
||||||
|
|
||||||
|
1. ✅ API 端点包含 `/v1/` 前缀
|
||||||
|
2. ✅ COZE_WORKSPACE_ID 已配置
|
||||||
|
3. ✅ API Key 已硬编码
|
||||||
|
4. ✅ 健康检查已添加
|
||||||
|
5. ✅ 日志和缓存目录已创建
|
||||||
45
Dockerfile
45
Dockerfile
|
|
@ -6,50 +6,40 @@ WORKDIR /app
|
||||||
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources 2>/dev/null || \
|
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources 2>/dev/null || \
|
||||||
sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list
|
sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list
|
||||||
|
|
||||||
# 安装完整的系统依赖(包含所有 PyGObject 需要的库)
|
# 安装系统依赖
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
# 编译工具
|
|
||||||
gcc \
|
gcc \
|
||||||
g++ \
|
g++ \
|
||||||
make \
|
make \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
cmake \
|
cmake \
|
||||||
# D-Bus 相关
|
|
||||||
dbus \
|
|
||||||
dbus-x11 \
|
|
||||||
libdbus-1-dev \
|
|
||||||
libdbus-glib-1-dev \
|
|
||||||
# GLib 和 GObject 相关
|
|
||||||
libglib2.0-dev \
|
libglib2.0-dev \
|
||||||
libgirepository1.0-dev \
|
|
||||||
gobject-introspection \
|
|
||||||
# Cairo 图形库
|
|
||||||
libcairo2-dev \
|
libcairo2-dev \
|
||||||
libcairo-gobject2 \
|
|
||||||
# GTK 相关(如果需要)
|
|
||||||
libgtk-3-dev \
|
|
||||||
# 其他常用库
|
|
||||||
libffi-dev \
|
|
||||||
libxml2-dev \
|
libxml2-dev \
|
||||||
libxslt1-dev \
|
libxslt1-dev \
|
||||||
|
curl \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||||
|
|
||||||
# 设置 pip 国内镜像源
|
# 设置 pip 国内镜像源和 API 配置(硬编码 KEY)
|
||||||
ENV PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/ \
|
ENV PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/ \
|
||||||
PIP_TRUSTED_HOST=mirrors.aliyun.com \
|
PIP_TRUSTED_HOST=mirrors.aliyun.com \
|
||||||
|
# API 端点配置(包含 /v1 前缀)
|
||||||
COZE_INTEGRATION_BASE_URL=https://api.coze.cn/v1 \
|
COZE_INTEGRATION_BASE_URL=https://api.coze.cn/v1 \
|
||||||
COZE_INTEGRATION_MODEL_BASE_URL=https://api.coze.cn/v1 \
|
COZE_INTEGRATION_MODEL_BASE_URL=https://api.coze.cn/v1 \
|
||||||
COZE_WORKLOAD_IDENTITY_API_KEY="Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImRmZmU2NmYxLTg0MDMtNDc5Ni05ZmRhLTViMmJjZWExM2ViOCJ9.eyJpc3MiOiJodHRwczovL2FwaS5jb3plLmNuIiwiYXVkIjpbIkZVS1kzOVR0dFlSdmlNaldGVmNjaUg0NWFPblp2TGxpIl0sImV4cCI6ODIxMDI2Njg3Njc5OSwiaWF0IjoxNzc0NjkyOTc0LCJzdWIiOiJzcGlmZmU6Ly9hcGkuY296ZS5jbi93b3JrbG9hZF9pZGVudGl0eS9pZDo3NjIyMjM4NzUyNjQyOTU3MzQ3Iiwic3JjIjoiaW5ib3VuZF9hdXRoX2FjY2Vzc190b2tlbl9pZDo3NjIyMjQ4Mjg1OTMxMDQ0ODkxIn0.XSJaTryHWYzQaHxd9g9rOX2Y3YRY8kGAlvSFH9UkWR9EFDfZESG1GFEdWDelYeoHBqtdiQhxTcYdGPA87_PweMfh0wJXTdCEzTDHAOlUUupJEKTpkUAMEoEZpYBrwKQxjzGglkMHUoXqM5I0tQsARaqZ-j-JOW9Y6fHot56squm8GSt7WZkVSj6ZC2Us4cpO_RIgsN_pBU0CFSlUpOU5AdQQ8LvHzp60-DGaXVU0mFIYKhnXKbTf3PSXpJlH-W78FULh2FcdOTxMIcNkL5nuIHGakoNNDxs-k5Ucp06kFEMcbvec4iB1njbkHrsilYeJOFRoqkXJpQujDngZxKecLA" \
|
COZE_INTEGRATION_CHAT_BASE_URL=https://api.coze.cn/v1 \
|
||||||
LLM_API_KEY="Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImRmZmU2NmYxLTg0MDMtNDc5Ni05ZmRhLTViMmJjZWExM2ViOCJ9.eyJpc3MiOiJodHRwczovL2FwaS5jb3plLmNuIiwiYXVkIjpbIkZVS1kzOVR0dFlSdmlNaldGVmNjaUg0NWFPblp2TGxpIl0sImV4cCI6ODIxMDI2Njg3Njc5OSwiaWF0IjoxNzc0NjkyOTc0LCJzdWIiOiJzcGlmZmU6Ly9hcGkuY296ZS5jbi93b3JrbG9hZF9pZGVudGl0eS9pZDo3NjIyMjM4NzUyNjQyOTU3MzQ3Iiwic3JjIjoiaW5ib3VuZF9hdXRoX2FjY2Vzc190b2tlbl9pZDo3NjIyMjQ4Mjg1OTMxMDQ0ODkxIn0.XSJaTryHWYzQaHxd9g9rOX2Y3YRY8kGAlvSFH9UkWR9EFDfZESG1GFEdWDelYeoHBqtdiQhxTcYdGPA87_PweMfh0wJXTdCEzTDHAOlUUupJEKTpkUAMEoEZpYBrwKQxjzGglkMHUoXqM5I0tQsARaqZ-j-JOW9Y6fHot56squm8GSt7WZkVSj6ZC2Us4cpO_RIgsN_pBU0CFSlUpOU5AdQQ8LvHzp60-DGaXVU0mFIYKhnXKbTf3PSXpJlH-W78FULh2FcdOTxMIcNkL5nuIHGakoNNDxs-k5Ucp06kFEMcbvec4iB1njbkHrsilYeJOFRoqkXJpQujDngZxKecLA" \
|
|
||||||
LLM_BASE_URL=https://api.coze.cn/v1 \
|
LLM_BASE_URL=https://api.coze.cn/v1 \
|
||||||
LLM_MODEL_NAME=doubao-seed-2-0-pro-260215 \
|
# API Key 配置(硬编码)
|
||||||
COZE_API_KEY="Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImRmZmU2NmYxLTg0MDMtNDc5Ni05ZmRhLTViMmJjZWExM2ViOCJ9.eyJpc3MiOiJodHRwczovL2FwaS5jb3plLmNuIiwiYXVkIjpbIkZVS1kzOVR0dFlSdmlNaldGVmNjaUg0NWFPblp2TGxpIl0sImV4cCI6ODIxMDI2Njg3Njc5OSwiaWF0IjoxNzc0NjkyOTc0LCJzdWIiOiJzcGlmZmU6Ly9hcGkuY296ZS5jbi93b3JrbG9hZF9pZGVudGl0eS9pZDo3NjIyMjM4NzUyNjQyOTU3MzQ3Iiwic3JjIjoiaW5ib3VuZF9hdXRoX2FjY2Vzc190b2tlbl9pZDo3NjIyMjQ4Mjg1OTMxMDQ0ODkxIn0.XSJaTryHWYzQaHxd9g9rOX2Y3YRY8kGAlvSFH9UkWR9EFDfZESG1GFEdWDelYeoHBqtdiQhxTcYdGPA87_PweMfh0wJXTdCEzTDHAOlUUupJEKTpkUAMEoEZpYBrwKQxjzGglkMHUoXqM5I0tQsARaqZ-j-JOW9Y6fHot56squm8GSt7WZkVSj6ZC2Us4cpO_RIgsN_pBU0CFSlUpOU5AdQQ8LvHzp60-DGaXVU0mFIYKhnXKbTf3PSXpJlH-W78FULh2FcdOTxMIcNkL5nuIHGakoNNDxs-k5Ucp06kFEMcbvec4iB1njbkHrsilYeJOFRoqkXJpQujDngZxKecLA" \
|
COZE_API_KEY="Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImRmZmU2NmYxLTg0MDMtNDc5Ni05ZmRhLTViMmJjZWExM2ViOCJ9.eyJpc3MiOiJodHRwczovL2FwaS5jb3plLmNuIiwiYXVkIjpbIkZVS1kzOVR0dFlSdmlNaldGVmNjaUg0NWFPblp2TGxpIl0sImV4cCI6ODIxMDI2Njg3Njc5OSwiaWF0IjoxNzc0NjkyOTc0LCJzdWIiOiJzcGlmZmU6Ly9hcGkuY296ZS5jbi93b3JrbG9hZF9pZGVudGl0eS9pZDo3NjIyMjM4NzUyNjQyOTU3MzQ3Iiwic3JjIjoiaW5ib3VuZF9hdXRoX2FjY2Vzc190b2tlbl9pZDo3NjIyMjQ4Mjg1OTMxMDQ0ODkxIn0.XSJaTryHWYzQaHxd9g9rOX2Y3YRY8kGAlvSFH9UkWR9EFDfZESG1GFEdWDelYeoHBqtdiQhxTcYdGPA87_PweMfh0wJXTdCEzTDHAOlUUupJEKTpkUAMEoEZpYBrwKQxjzGglkMHUoXqM5I0tQsARaqZ-j-JOW9Y6fHot56squm8GSt7WZkVSj6ZC2Us4cpO_RIgsN_pBU0CFSlUpOU5AdQQ8LvHzp60-DGaXVU0mFIYKhnXKbTf3PSXpJlH-W78FULh2FcdOTxMIcNkL5nuIHGakoNNDxs-k5Ucp06kFEMcbvec4iB1njbkHrsilYeJOFRoqkXJpQujDngZxKecLA" \
|
||||||
COZE_INTEGRATION_API_KEY="Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImRmZmU2NmYxLTg0MDMtNDc5Ni05ZmRhLTViMmJjZWExM2ViOCJ9.eyJpc3MiOiJodHRwczovL2FwaS5jb3plLmNuIiwiYXVkIjpbIkZVS1kzOVR0dFlSdmlNaldGVmNjaUg0NWFPblp2TGxpIl0sImV4cCI6ODIxMDI2Njg3Njc5OSwiaWF0IjoxNzc0NjkyOTc0LCJzdWIiOiJzcGlmZmU6Ly9hcGkuY296ZS5jbi93b3JrbG9hZF9pZGVudGl0eS9pZDo3NjIyMjM4NzUyNjQyOTU3MzQ3Iiwic3JjIjoiaW5ib3VuZF9hdXRoX2FjY2Vzc190b2tlbl9pZDo3NjIyMjQ4Mjg1OTMxMDQ0ODkxIn0.XSJaTryHWYzQaHxd9g9rOX2Y3YRY8kGAlvSFH9UkWR9EFDfZESG1GFEdWDelYeoHBqtdiQhxTcYdGPA87_PweMfh0wJXTdCEzTDHAOlUUupJEKTpkUAMEoEZpYBrwKQxjzGglkMHUoXqM5I0tQsARaqZ-j-JOW9Y6fHot56squm8GSt7WZkVSj6ZC2Us4cpO_RIgsN_pBU0CFSlUpOU5AdQQ8LvHzp60-DGaXVU0mFIYKhnXKbTf3PSXpJlH-W78FULh2FcdOTxMIcNkL5nuIHGakoNNDxs-k5Ucp06kFEMcbvec4iB1njbkHrsilYeJOFRoqkXJpQujDngZxKecLA" \
|
LLM_API_KEY="Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImRmZmU2NmYxLTg0MDMtNDc5Ni05ZmRhLTViMmJjZWExM2ViOCJ9.eyJpc3MiOiJodHRwczovL2FwaS5jb3plLmNuIiwiYXVkIjpbIkZVS1kzOVR0dFlSdmlNaldGVmNjaUg0NWFPblp2TGxpIl0sImV4cCI6ODIxMDI2Njg3Njc5OSwiaWF0IjoxNzc0NjkyOTc0LCJzdWIiOiJzcGlmZmU6Ly9hcGkuY296ZS5jbi93b3JrbG9hZF9pZGVudGl0eS9pZDo3NjIyMjM4NzUyNjQyOTU3MzQ3Iiwic3JjIjoiaW5ib3VuZF9hdXRoX2FjY2Vzc190b2tlbl9pZDo3NjIyMjQ4Mjg1OTMxMDQ0ODkxIn0.XSJaTryHWYzQaHxd9g9rOX2Y3YRY8kGAlvSFH9UkWR9EFDfZESG1GFEdWDelYeoHBqtdiQhxTcYdGPA87_PweMfh0wJXTdCEzTDHAOlUUupJEKTpkUAMEoEZpYBrwKQxjzGglkMHUoXqM5I0tQsARaqZ-j-JOW9Y6fHot56squm8GSt7WZkVSj6ZC2Us4cpO_RIgsN_pBU0CFSlUpOU5AdQQ8LvHzp60-DGaXVU0mFIYKhnXKbTf3PSXpJlH-W78FULh2FcdOTxMIcNkL5nuIHGakoNNDxs-k5Ucp06kFEMcbvec4iB1njbkHrsilYeJOFRoqkXJpQujDngZxKecLA" \
|
||||||
COZE_WORKSPACE_ID=7622238752642957347
|
# Workspace ID 配置(硬编码,从 JWT Token 提取)
|
||||||
|
COZE_WORKSPACE_ID=7622238752642957347 \
|
||||||
|
# LLM 模型配置
|
||||||
|
LLM_MODEL_NAME=doubao-seed-2-0-pro-260215 \
|
||||||
|
COZE_INTEGRATION_API_KEY="Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImRmZmU2NmYxLTg0MDMtNDc5Ni05ZmRhLTViMmJjZWExM2ViOCJ9.eyJpc3MiOiJodHRwczovL2FwaS5jb3plLmNuIiwiYXVkIjpbIkZVS1kzOVR0dFlSdmlNaldGVmNjaUg0NWFPblp2TGxpIl0sImV4cCI6ODIxMDI2Njg3Njc5OSwiaWF0IjoxNzc0NjkyOTc0LCJzdWIiOiJzcGlmZmU6Ly9hcGkuY296ZS5jbi93b3JrbG9hZF9pZGVudGl0eS9pZDo3NjIyMjM4NzUyNjQyOTU3MzQ3Iiwic3JjIjoiaW5ib3VuZF9hdXRoX2FjY2Vzc190b2tlbl9pZDo3NjIyMjQ4Mjg1OTMxMDQ0ODkxIn0.XSJaTryHWYzQaHxd9g9rOX2Y3YRY8kGAlvSFH9UkWR9EFDfZESG1GFEdWDelYeoHBqtdiQhxTcYdGPA87_PweMfh0wJXTdCEzTDHAOlUUupJEKTpkUAMEoEZpYBrwKQxjzGglkMHUoXqM5I0tQsARaqZ-j-JOW9Y6fHot56squm8GSt7WZkVSj6ZC2Us4cpO_RIgsN_pBU0CFSlUpOU5AdQQ8LvHzp60-DGaXVU0mFIYKhnXKbTf3PSXpJlH-W78FULh2FcdOTxMIcNkL5nuIHGakoNNDxs-k5Ucp06kFEMcbvec4iB1njbkHrsilYeJOFRoqkXJpQujDngZxKecLA"
|
||||||
|
|
||||||
# 升级 pip 和构建工具
|
# 升级 pip 和构建工具
|
||||||
RUN pip install --no-cache-dir --upgrade pip setuptools wheel meson ninja
|
RUN pip install --no-cache-dir --upgrade pip setuptools wheel
|
||||||
|
|
||||||
# 复制并安装依赖
|
# 复制并安装依赖
|
||||||
COPY requirements.txt .
|
COPY requirements.txt .
|
||||||
|
|
@ -58,5 +48,12 @@ RUN pip install --no-cache-dir -r requirements.txt
|
||||||
# 复制项目文件
|
# 复制项目文件
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
# 创建必要的目录
|
||||||
|
RUN mkdir -p /app/work/logs/bypass /tmp/homework_cache
|
||||||
|
|
||||||
|
# 添加健康检查
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:8000/health || exit 1
|
||||||
|
|
||||||
EXPOSE 8000
|
EXPOSE 8000
|
||||||
CMD ["python", "src/main.py", "-m", "http", "-p", "8000"]
|
CMD ["python", "src/main.py", "-m", "http", "-p", "8000"]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,202 @@
|
||||||
|
# 数学作业批改系统 - Docker 部署
|
||||||
|
|
||||||
|
## 📦 快速开始
|
||||||
|
|
||||||
|
### 一键部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 运行部署脚本
|
||||||
|
./deploy.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 手动部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 构建镜像
|
||||||
|
docker build -t math-grading:latest .
|
||||||
|
|
||||||
|
# 启动容器
|
||||||
|
docker run -d \
|
||||||
|
--name math-grading \
|
||||||
|
-p 8000:8000 \
|
||||||
|
-v $(pwd)/logs:/app/work/logs \
|
||||||
|
-v $(pwd)/cache:/tmp/homework_cache \
|
||||||
|
--restart unless-stopped \
|
||||||
|
math-grading:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧪 测试验证
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 运行测试脚本
|
||||||
|
./test.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 配置说明
|
||||||
|
|
||||||
|
### 已硬编码的配置
|
||||||
|
|
||||||
|
| 配置项 | 值 | 说明 |
|
||||||
|
|--------|-----|------|
|
||||||
|
| API 端点 | `https://api.coze.cn/v1` | 包含 /v1 前缀 |
|
||||||
|
| COZE_API_KEY | `Bearer eyJhbGci...` | Coze API 认证密钥 |
|
||||||
|
| COZE_WORKSPACE_ID | `7622238752642957347` | 工作区 ID |
|
||||||
|
| LLM_MODEL_NAME | `doubao-seed-2-0-pro-260215` | LLM 模型名称 |
|
||||||
|
|
||||||
|
### 配置来源
|
||||||
|
|
||||||
|
- **API Key**: 从原始 Dockerfile 中提取
|
||||||
|
- **Workspace ID**: 从 JWT Token 的 `sub` 字段提取
|
||||||
|
```
|
||||||
|
spiffe://api.coze.cn/workload_identity/id:7622238752642957347
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 常用命令
|
||||||
|
|
||||||
|
### 容器管理
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看状态
|
||||||
|
docker ps | grep math-grading
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
docker logs -f math-grading
|
||||||
|
|
||||||
|
# 停止服务
|
||||||
|
docker stop math-grading
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
docker start math-grading
|
||||||
|
|
||||||
|
# 重启服务
|
||||||
|
docker restart math-grading
|
||||||
|
|
||||||
|
# 进入容器
|
||||||
|
docker exec -it math-grading /bin/bash
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 API 接口
|
||||||
|
|
||||||
|
### 批改接口
|
||||||
|
|
||||||
|
**请求**:
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:8000/stream_run \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"student_homework": [
|
||||||
|
{
|
||||||
|
"student_id": 1,
|
||||||
|
"student_name": "张三",
|
||||||
|
"homework_images": [
|
||||||
|
"https://example.com/image1.jpg",
|
||||||
|
"https://example.com/image2.jpg"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"answer_doc_url": "https://example.com/answers.docx",
|
||||||
|
"comment_max_length": 50,
|
||||||
|
"max_concurrent": 5
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**参数说明**:
|
||||||
|
- `student_homework`: 学生作业列表
|
||||||
|
- `answer_doc_url`: 答案文档 URL(可选)
|
||||||
|
- `comment_max_length`: 评语最大字数(默认 50)
|
||||||
|
- `max_concurrent`: 并发批改数量(默认 5)
|
||||||
|
|
||||||
|
## 📁 目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
├── Dockerfile # Docker 镜像配置(硬编码 KEY)
|
||||||
|
├── deploy.sh # 一键部署脚本
|
||||||
|
├── test.sh # 快速测试脚本
|
||||||
|
├── DOCKER_DEPLOY.md # 详细部署文档
|
||||||
|
├── logs/ # 日志目录
|
||||||
|
├── cache/ # 缓存目录
|
||||||
|
└── src/ # 源代码
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 故障排查
|
||||||
|
|
||||||
|
### 问题 1: 容器无法启动
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看详细日志
|
||||||
|
docker logs math-grading
|
||||||
|
|
||||||
|
# 检查端口占用
|
||||||
|
netstat -tuln | grep 8000
|
||||||
|
```
|
||||||
|
|
||||||
|
### 问题 2: LLM 调用失败
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查环境变量
|
||||||
|
docker exec math-grading env | grep COZE
|
||||||
|
|
||||||
|
# 应该看到:
|
||||||
|
# COZE_API_KEY=Bearer eyJhbGci...
|
||||||
|
# COZE_WORKSPACE_ID=7622238752642957347
|
||||||
|
# COZE_INTEGRATION_BASE_URL=https://api.coze.cn/v1
|
||||||
|
```
|
||||||
|
|
||||||
|
### 问题 3: 认证错误 (401)
|
||||||
|
|
||||||
|
- 确认 COZE_API_KEY 和 COZE_WORKSPACE_ID 都已设置
|
||||||
|
- 检查 Token 是否有效
|
||||||
|
|
||||||
|
### 问题 4: 端点错误 (404)
|
||||||
|
|
||||||
|
- 确认 API 端点包含 /v1 前缀
|
||||||
|
- 检查 COZE_INTEGRATION_BASE_URL 配置
|
||||||
|
|
||||||
|
## 📚 详细文档
|
||||||
|
|
||||||
|
- [完整部署指南](DOCKER_DEPLOY.md)
|
||||||
|
- [项目文档](AGENTS.md)
|
||||||
|
- [Docker 404 错误修复](assets/fix_docker_404.md)
|
||||||
|
|
||||||
|
## ⚠️ 安全提示
|
||||||
|
|
||||||
|
当前 Dockerfile 将 API Key 硬编码在镜像中:
|
||||||
|
- ✅ 优点:部署简单,无需额外配置
|
||||||
|
- ❌ 缺点:密钥会暴露在镜像中
|
||||||
|
|
||||||
|
### 安全建议
|
||||||
|
|
||||||
|
1. **使用私有仓库**:不要推送到公共 Docker Registry
|
||||||
|
2. **访问控制**:限制镜像拉取权限
|
||||||
|
3. **定期更换密钥**:在 Coze 平台定期更换 API Key
|
||||||
|
4. **生产环境**:考虑使用环境变量方式(参考 docker-compose.yml)
|
||||||
|
|
||||||
|
## 🎯 验证成功标志
|
||||||
|
|
||||||
|
部署成功后,应该看到:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 容器运行中
|
||||||
|
docker ps | grep math-grading
|
||||||
|
# Up 5 minutes
|
||||||
|
|
||||||
|
# 2. 健康检查通过
|
||||||
|
curl http://localhost:8000/health
|
||||||
|
# 200 OK
|
||||||
|
|
||||||
|
# 3. 日志无错误
|
||||||
|
docker logs math-grading | grep ERROR
|
||||||
|
# (无输出)
|
||||||
|
|
||||||
|
# 4. LLM 调用成功
|
||||||
|
# 日志显示:
|
||||||
|
# HTTP Request: POST https://api.coze.cn/v1/chat/completions "HTTP/1.1 200 OK"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📞 支持
|
||||||
|
|
||||||
|
如遇问题,请:
|
||||||
|
1. 查看日志: `docker logs -f math-grading`
|
||||||
|
2. 运行测试: `./test.sh`
|
||||||
|
3. 参考文档: `DOCKER_DEPLOY.md`
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
从 JWT Token 中提取 Workspace ID
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import base64
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def extract_workspace_id(token):
|
||||||
|
"""
|
||||||
|
从 JWT Token 中提取 Workspace ID
|
||||||
|
|
||||||
|
Args:
|
||||||
|
token: JWT Token(带或不带 "Bearer " 前缀)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
workspace_id: 工作区 ID
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 移除 "Bearer " 前缀
|
||||||
|
if token.startswith("Bearer "):
|
||||||
|
token = token[7:]
|
||||||
|
|
||||||
|
# 分割 JWT
|
||||||
|
parts = token.split(".")
|
||||||
|
if len(parts) != 3:
|
||||||
|
print("❌ Token 格式错误:应该是 JWT 格式(header.payload.signature)")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# 解码 payload
|
||||||
|
payload_b64 = parts[1]
|
||||||
|
# 添加 padding
|
||||||
|
padding = 4 - len(payload_b64) % 4
|
||||||
|
if padding != 4:
|
||||||
|
payload_b64 += "=" * padding
|
||||||
|
|
||||||
|
payload = json.loads(base64.b64decode(payload_b64))
|
||||||
|
|
||||||
|
# 显示 Token 信息
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
print("JWT Token 信息")
|
||||||
|
print("=" * 80)
|
||||||
|
print(f"Issuer (iss): {payload.get('iss')}")
|
||||||
|
print(f"Audience (aud): {payload.get('aud')}")
|
||||||
|
print(f"Subject (sub): {payload.get('sub')}")
|
||||||
|
print(f"Expires (exp): {payload.get('exp')}")
|
||||||
|
print(f"Issued At (iat): {payload.get('iat')}")
|
||||||
|
print(f"Source (src): {payload.get('src')}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 提取 workspace_id
|
||||||
|
sub = payload.get('sub', '')
|
||||||
|
|
||||||
|
# 尝试不同的格式
|
||||||
|
if 'workload_identity/id:' in sub:
|
||||||
|
workspace_id = sub.split('workload_identity/id:')[-1]
|
||||||
|
print(f"✅ 格式 1: workload_identity/id:{workspace_id}")
|
||||||
|
elif 'workspace/id:' in sub:
|
||||||
|
workspace_id = sub.split('workspace/id:')[-1]
|
||||||
|
print(f"✅ 格式 2: workspace/id:{workspace_id}")
|
||||||
|
else:
|
||||||
|
# 尝试直接使用 sub
|
||||||
|
workspace_id = sub
|
||||||
|
print(f"⚠️ 格式 3: 直接使用 sub: {workspace_id}")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("=" * 80)
|
||||||
|
print(f"🔑 提取的 Workspace ID: {workspace_id}")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
return workspace_id
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 解析 Token 失败: {str(e)}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print()
|
||||||
|
print("=" * 80)
|
||||||
|
print("Workspace ID 提取工具")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 方式 1:从环境变量读取
|
||||||
|
token = None
|
||||||
|
|
||||||
|
# 1. 尝试从命令行参数读取
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
token = sys.argv[1]
|
||||||
|
# 2. 尝试从环境变量读取
|
||||||
|
else:
|
||||||
|
token = __import__('os').environ.get('COZE_API_KEY')
|
||||||
|
|
||||||
|
if not token:
|
||||||
|
print("❌ 未找到 Token")
|
||||||
|
print()
|
||||||
|
print("使用方法:")
|
||||||
|
print(" 方式 1: python extract_workspace_id.py 'Bearer eyJhbGci...'")
|
||||||
|
print(" 方式 2: COZE_API_KEY='Bearer eyJhbGci...' python extract_workspace_id.py")
|
||||||
|
print()
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# 提取 workspace_id
|
||||||
|
workspace_id = extract_workspace_id(token)
|
||||||
|
|
||||||
|
if workspace_id:
|
||||||
|
print()
|
||||||
|
print("✅ 提取成功!")
|
||||||
|
print()
|
||||||
|
print("下一步:")
|
||||||
|
print(f"1. 在 docker-compose.yml 中设置:")
|
||||||
|
print(f" COZE_WORKSPACE_ID={workspace_id}")
|
||||||
|
print()
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
print()
|
||||||
|
print("❌ 提取失败,请检查 Token 格式")
|
||||||
|
print()
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Docker 快速部署脚本
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo "数学作业批改系统 - Docker 部署脚本"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 检查 Docker 是否安装
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
echo "❌ Docker 未安装,请先安装 Docker"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Docker 已安装"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 检查旧容器
|
||||||
|
if docker ps -a | grep -q math-grading; then
|
||||||
|
echo "⚠️ 检测到旧容器 math-grading"
|
||||||
|
read -p "是否删除旧容器? (y/n) " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "🗑️ 删除旧容器..."
|
||||||
|
docker rm -f math-grading
|
||||||
|
else
|
||||||
|
echo "❌ 取消部署"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "🏗️ 开始构建镜像..."
|
||||||
|
docker build -t math-grading:latest .
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "✅ 镜像构建成功"
|
||||||
|
else
|
||||||
|
echo "❌ 镜像构建失败"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🚀 启动容器..."
|
||||||
|
|
||||||
|
# 创建日志和缓存目录
|
||||||
|
mkdir -p logs cache
|
||||||
|
|
||||||
|
# 启动容器
|
||||||
|
docker run -d \
|
||||||
|
--name math-grading \
|
||||||
|
-p 8000:8000 \
|
||||||
|
-v $(pwd)/logs:/app/work/logs \
|
||||||
|
-v $(pwd)/cache:/tmp/homework_cache \
|
||||||
|
--restart unless-stopped \
|
||||||
|
math-grading:latest
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "✅ 容器启动成功"
|
||||||
|
else
|
||||||
|
echo "❌ 容器启动失败"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "⏳ 等待服务启动..."
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=========================================="
|
||||||
|
echo "部署完成!"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
|
echo "服务地址: http://localhost:8000"
|
||||||
|
echo ""
|
||||||
|
echo "常用命令:"
|
||||||
|
echo " 查看日志: docker logs -f math-grading"
|
||||||
|
echo " 停止服务: docker stop math-grading"
|
||||||
|
echo " 启动服务: docker start math-grading"
|
||||||
|
echo " 重启服务: docker restart math-grading"
|
||||||
|
echo ""
|
||||||
|
echo "测试接口:"
|
||||||
|
echo " curl -X POST http://localhost:8000/stream_run \\"
|
||||||
|
echo " -H 'Content-Type: application/json' \\"
|
||||||
|
echo " -d '{\"student_homework\": [{\"student_id\": 1, \"homework_images\": [\"https://example.com/image.jpg\"]}]}'"
|
||||||
|
echo ""
|
||||||
|
echo "详细文档: DOCKER_DEPLOY.md"
|
||||||
|
echo ""
|
||||||
|
|
@ -0,0 +1,125 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# 快速测试脚本
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo "数学作业批改系统 - 快速测试"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 检查容器是否运行
|
||||||
|
if ! docker ps | grep -q math-grading; then
|
||||||
|
echo "❌ 容器未运行,请先启动容器"
|
||||||
|
echo "运行: docker start math-grading"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ 容器正在运行"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 测试 1: 健康检查
|
||||||
|
echo "测试 1: 健康检查"
|
||||||
|
echo "----------------------------------------"
|
||||||
|
response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/health)
|
||||||
|
if [ "$response" = "200" ]; then
|
||||||
|
echo "✅ 健康检查通过 (200 OK)"
|
||||||
|
else
|
||||||
|
echo "❌ 健康检查失败 (HTTP $response)"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 测试 2: 环境变量检查
|
||||||
|
echo "测试 2: 环境变量检查"
|
||||||
|
echo "----------------------------------------"
|
||||||
|
echo "检查关键环境变量..."
|
||||||
|
|
||||||
|
# COZE_API_KEY
|
||||||
|
if docker exec math-grading env | grep -q "COZE_API_KEY=Bearer"; then
|
||||||
|
echo "✅ COZE_API_KEY 已设置"
|
||||||
|
else
|
||||||
|
echo "❌ COZE_API_KEY 未设置"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# COZE_WORKSPACE_ID
|
||||||
|
if docker exec math-grading env | grep -q "COZE_WORKSPACE_ID=7622238752642957347"; then
|
||||||
|
echo "✅ COZE_WORKSPACE_ID 已设置 (7622238752642957347)"
|
||||||
|
else
|
||||||
|
echo "❌ COZE_WORKSPACE_ID 未设置或值不正确"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# API 端点
|
||||||
|
if docker exec math-grading env | grep -q "COZE_INTEGRATION_BASE_URL=https://api.coze.cn/v1"; then
|
||||||
|
echo "✅ API 端点已配置 (https://api.coze.cn/v1)"
|
||||||
|
else
|
||||||
|
echo "❌ API 端点未配置或缺少 /v1 前缀"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# LLM 模型
|
||||||
|
if docker exec math-grading env | grep -q "LLM_MODEL_NAME=doubao-seed-2-0-pro-260215"; then
|
||||||
|
echo "✅ LLM 模型已配置 (doubao-seed-2-0-pro-260215)"
|
||||||
|
else
|
||||||
|
echo "❌ LLM 模型未配置"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 测试 3: LLM 调用测试
|
||||||
|
echo "测试 3: LLM 调用测试"
|
||||||
|
echo "----------------------------------------"
|
||||||
|
echo "发送测试请求..."
|
||||||
|
|
||||||
|
response=$(curl -s -X POST http://localhost:8000/stream_run \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"student_homework": [
|
||||||
|
{
|
||||||
|
"student_id": 1,
|
||||||
|
"student_name": "测试学生",
|
||||||
|
"homework_images": [
|
||||||
|
"https://dpcclass.oss-cn-beijing.aliyuncs.com/umsupload/2026/03/18/69baa4f5-4826-4901-00e1-c6e66f02947f.jpg?x-oss-process=image/resize,w_1000"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"answer_doc_url": "",
|
||||||
|
"comment_max_length": 50,
|
||||||
|
"max_concurrent": 1
|
||||||
|
}' \
|
||||||
|
--max-time 120)
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "✅ 请求发送成功"
|
||||||
|
echo ""
|
||||||
|
echo "响应预览:"
|
||||||
|
echo "$response" | head -c 500
|
||||||
|
echo "..."
|
||||||
|
else
|
||||||
|
echo "❌ 请求失败"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 测试 4: 日志检查
|
||||||
|
echo "测试 4: 日志检查"
|
||||||
|
echo "----------------------------------------"
|
||||||
|
echo "检查最近日志中的错误..."
|
||||||
|
|
||||||
|
errors=$(docker logs --tail 100 math-grading 2>&1 | grep -i "401\|404\|authentication is invalid" | wc -l)
|
||||||
|
|
||||||
|
if [ "$errors" -eq 0 ]; then
|
||||||
|
echo "✅ 未发现认证错误或端点错误"
|
||||||
|
else
|
||||||
|
echo "❌ 发现 $errors 个错误"
|
||||||
|
echo "最近的错误:"
|
||||||
|
docker logs --tail 50 math-grading 2>&1 | grep -i "401\|404\|authentication is invalid" | tail -5
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 总结
|
||||||
|
echo "=========================================="
|
||||||
|
echo "测试总结"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
|
echo "如果所有测试都通过,说明部署成功!"
|
||||||
|
echo ""
|
||||||
|
echo "下一步:"
|
||||||
|
echo " 1. 查看详细日志: docker logs -f math-grading"
|
||||||
|
echo " 2. 测试完整功能: 使用上面的测试请求"
|
||||||
|
echo " 3. 部署到生产环境: 参考 DOCKER_DEPLOY.md"
|
||||||
|
echo ""
|
||||||
Loading…
Reference in New Issue