4.7 KiB
4.7 KiB
Docker 部署问题排查指南
问题描述
在 Docker 环境中部署工作流时,出现以下错误:
S3对象不存在: <!DOCTYPE HTML><html><head>...<title>404 Not Found</title>...
诊断步骤
1. 运行 URL 诊断脚本
在 Docker 容器内运行:
python scripts/test_urls.py
预期结果:所有 URL 应该显示 ✅ 有效
如果显示 ❌ 无效:
- 检查 Docker 容器网络配置
- 检查 DNS 解析
- 检查防火墙规则
2. 检查 Docker 网络配置
# 检查容器是否可以访问外网
docker exec <container_id> ping -c 3 8.8.8.8
# 检查 DNS 解析
docker exec <container_id> nslookup dpcclass.oss-cn-beijing.aliyuncs.com
# 检查是否能访问 OSS
docker exec <container_id> curl -I https://dpcclass.oss-cn-beijing.aliyuncs.com
3. 检查 LLM 服务网络
LLM 服务可能在隔离的网络环境中运行,无法直接访问外部 URL。
验证方法:
- 查看 LLM 服务的网络配置
- 确认 LLM 服务可以访问外部 URL
- 联系 LLM 服务提供商确认网络策略
解决方案
方案 1:配置 Docker 网络使用宿主机网络
docker run --network host ...
优点:
- 容器使用宿主机的网络栈
- 可以直接访问宿主机的网络资源
缺点:
- 端口可能冲突
- 安全性降低
方案 2:配置 DNS 解析
在 Dockerfile 中:
RUN echo "nameserver 8.8.8.8" > /etc/resolv.conf
或在 docker-compose.yml 中:
services:
app:
dns:
- 8.8.8.8
- 114.114.114.114
方案 3:添加 HTTP 代理
如果需要通过代理访问外网:
# 在容器内设置环境变量
export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080
或在 Dockerfile 中:
ENV HTTP_PROXY=http://proxy.example.com:8080
ENV HTTPS_PROXY=http://proxy.example.com:8080
方案 4:下载图片到本地(推荐)
如果 LLM 服务无法访问外部 URL,可以在预处理阶段下载图片:
import requests
import tempfile
import os
from pathlib import Path
def download_image_to_local(image_url: str) -> str:
"""
下载图片到本地临时目录
返回本地文件路径
"""
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
response = requests.get(image_url, headers=headers, timeout=30)
response.raise_for_status()
# 保存到临时目录
tmp_dir = Path("/tmp/homework_images")
tmp_dir.mkdir(parents=True, exist_ok=True)
# 生成文件名
import hashlib
filename = hashlib.md5(image_url.encode()).hexdigest() + ".jpg"
local_path = tmp_dir / filename
# 写入文件
with open(local_path, "wb") as f:
f.write(response.content)
return str(local_path)
方案 5:使用内网 OSS(最佳)
如果有内网 OSS,可以:
- 将图片从公网 OSS 复制到内网 OSS
- 使用内网 OSS URL
- 配置内网 OSS 访问权限
代码改进
我已经增强了 URL 验证逻辑:
1. 改进的图片 URL 验证(recognize_and_correct_node.py)
# 检查 HTTP 状态码(只接受 200 和 206)
if status_code not in (200, 206):
raise ValueError(f"HTTP status code: {status_code}")
# 检查 Content-Type
content_type = response.headers.get('Content-Type', '')
if not content_type.startswith('image/'):
logger.warning(f"Unexpected Content-Type: {content_type}")
# 检查是否为 HTML 错误页面
if b'<html' in preview_lower:
# 提取具体错误信息(404/403/500)
raise ValueError(f"URL returned HTML page ({error_msg})")
2. 改进的 Word 文档下载验证(doc_extract_node.py)
# 验证 URL 格式
if not url.startswith(('http://', 'https://')):
raise ValueError(f"Invalid URL format")
# 检查 HTTP 状态码
if status_code != 200:
raise ValueError(f"HTTP Error {status_code}: {url}")
# 检查是否为有效的 docx
if not response.content.startswith(b'PK'):
raise ValueError("Not a valid docx file")
临时解决方案
如果遇到无法解决的访问问题,可以:
1. 使用本地图片测试
{
"student_homework": [
{
"student_id": 1,
"student_name": "测试",
"homework_images": ["file:///tmp/test_image.jpg"]
}
],
"answer_doc_url": ""
}
2. 禁用答案文档
{
"answer_doc_url": "",
...
}
系统会自动切换到"专业老师批改模式",不依赖标准答案。
联系支持
如果以上方案都无法解决问题,请提供:
- Docker 容器网络配置
python scripts/test_urls.py的输出- Docker 容器日志
- LLM 服务网络配置