适用场景

PaddleOCR 以 Docker 容器运行在 VPS 上(端口 9899 仅绑定 127.0.0.1),通过 Nginx 反向代理对外提供 HTTPS 服务。本文档说明如何在文档管理系统中正确配置该服务。

架构

浏览器 ──HTTPS──▶ doc.otwx.top (Cloudflare Worker)
                         │
                         │ fetch() 内部请求
                         ▼
                  Cloudflare 边缘代理
                         │
                    HTTPS (Full SSL)
                         │
                  VPS Nginx :443
                         │
                   proxy_pass
                         │
                  localhost:9899 (PaddleOCR Docker)

一、VPS 端:Nginx 配置

# HTTP → HTTPS 重定向
server {
    listen 80;
    server_name ocr1.otwx.top;
    return 301 https://$server_name$request_uri;
}

# HTTPS 反向代理到 PaddleOCR
server {
    listen 443 ssl http2;
    server_name ocr1.otwx.top;

    ssl_certificate     /path/to/fullchain.pem;   # acme.sh 申请的证书
    ssl_certificate_key /path/to/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:9899;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 120s;   # OCR 识别较慢,延长超时
    }
}

关键点

  • 9899 端口不要对外暴露(Docker 绑定 127.0.0.1)
  • 证书使用 acme.sh / Let's Encrypt 自动续期即可
  • proxy_read_timeout 设大一些,大 PDF 识别可能需要数分钟

二、Cloudflare 端:DNS 设置

设置项 说明
DNS 记录类型 A 记录 指向 VPS IP
代理状态 橙云(已代理) 必须! Cloudflare Workers 无法直连 IP
SSL/TLS 加密模式 完全(Full) 必须! 自动/Flexible 会导致重定向死循环

为什么必须橙云?

Cloudflare Workers 发起的 fetch() 请求无法直接连接 IP 地址(报错 Direct IP access not allowed)。橙云代理后,Worker 通过 Cloudflare 边缘网络访问源站,这是 Workers 出网的唯一方式。

为什么必须 Full SSL?

模式 CF → 源站 问题
自动 / Flexible HTTP Nginx 收到 HTTP 请求后 301 跳转 HTTPS → 死循环
Full HTTPS 正常 ✓
Full (strict) HTTPS(验证证书) 正常(Let's Encrypt 证书可通过验证)

建议用 Full(接受自签名/Let's Encrypt 证书,验证较宽松)。

三、系统设置:OCR 服务配置

字段 说明
名称 ocr1(自定义)
类型 PaddleOCR 不是 OCR.space!
服务地址 https://ocr1.otwx.top 完整的 HTTPS URL
API Key XXXX(如有) PaddleOCR 实例的 API Key
启用
设为默认 可选

常见错误:类型选错

如果类型选成 OCR.space,系统会走 OCR.space 的 API 调用逻辑,把请求发到 PaddleOCR 服务器上拿到 401/400 等错误。

四、验证

  1. VPS 上 curl 测试:

    curl https://ocr1.otwx.top/health
    # 应返回 {"status":"ok","timestamp":...}
    
  2. 系统设置页点击对应服务的"测试"按钮,应显示"PaddleOCR 服务连接正常"

  3. 对 PDF 文档执行 OCR 识别,应成功提取文字

五、故障排查

现象 原因 解决
测试"Too many redirects" DNS 灰云或 SSL 模式为 Flexible 改为橙云 + Full SSL
测试"Direct IP access not allowed" (403) DNS 灰云 改为橙云
测试"timeout" 橙云 + Flexible SSL 改为 Full SSL
测试"HTTP 401" 类型选成了 OCR.space 改为 PaddleOCR
OCR 无文字 图片质量或 OCR 服务问题 检查 PaddleOCR 容器日志

六、多服务说明

系统支持配置多个 OCR 服务(OCR.space + PaddleOCR),可设默认服务。PaddleOCR 仅支持图片识别——上传 PDF 时,前端会用 pdfjs 自动将 PDF 逐页渲染为 JPEG 图片再提交。

为什么 PaddleOCR 需要 PDF→图片?

PaddleOCR 的 /general/base64 端点仅接受单张图片的 base64 编码,不支持直接上传 PDF 文件。系统在前端用 pdfjs 逐页渲染,每页生成 JPEG 图片后提交后端,后端再逐页调用 PaddleOCR。