# Docker 部署问题排查指南 ## 问题描述 在 Docker 环境中部署工作流时,出现以下错误: ``` S3对象不存在: ...404 Not Found... ``` ## 诊断步骤 ### 1. 运行 URL 诊断脚本 在 Docker 容器内运行: ```bash python scripts/test_urls.py ``` **预期结果**:所有 URL 应该显示 `✅ 有效` **如果显示 `❌ 无效`**: - 检查 Docker 容器网络配置 - 检查 DNS 解析 - 检查防火墙规则 ### 2. 检查 Docker 网络配置 ```bash # 检查容器是否可以访问外网 docker exec ping -c 3 8.8.8.8 # 检查 DNS 解析 docker exec nslookup dpcclass.oss-cn-beijing.aliyuncs.com # 检查是否能访问 OSS docker exec curl -I https://dpcclass.oss-cn-beijing.aliyuncs.com ``` ### 3. 检查 LLM 服务网络 LLM 服务可能在隔离的网络环境中运行,无法直接访问外部 URL。 **验证方法**: - 查看 LLM 服务的网络配置 - 确认 LLM 服务可以访问外部 URL - 联系 LLM 服务提供商确认网络策略 ## 解决方案 ### 方案 1:配置 Docker 网络使用宿主机网络 ```bash docker run --network host ... ``` **优点**: - 容器使用宿主机的网络栈 - 可以直接访问宿主机的网络资源 **缺点**: - 端口可能冲突 - 安全性降低 ### 方案 2:配置 DNS 解析 在 Dockerfile 中: ```dockerfile RUN echo "nameserver 8.8.8.8" > /etc/resolv.conf ``` 或在 docker-compose.yml 中: ```yaml services: app: dns: - 8.8.8.8 - 114.114.114.114 ``` ### 方案 3:添加 HTTP 代理 如果需要通过代理访问外网: ```bash # 在容器内设置环境变量 export HTTP_PROXY=http://proxy.example.com:8080 export HTTPS_PROXY=http://proxy.example.com:8080 ``` 或在 Dockerfile 中: ```dockerfile ENV HTTP_PROXY=http://proxy.example.com:8080 ENV HTTPS_PROXY=http://proxy.example.com:8080 ``` ### 方案 4:下载图片到本地(推荐) 如果 LLM 服务无法访问外部 URL,可以在预处理阶段下载图片: ```python 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,可以: 1. 将图片从公网 OSS 复制到内网 OSS 2. 使用内网 OSS URL 3. 配置内网 OSS 访问权限 ## 代码改进 我已经增强了 URL 验证逻辑: ### 1. 改进的图片 URL 验证(`recognize_and_correct_node.py`) ```python # 检查 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'