Files
ocr/Docker部署文档.md
2026-01-12 23:22:20 +08:00

769 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# OCR服务 Docker 部署文档
## 项目概述
这是一个基于FastAPI的OCR文字识别服务支持多种文件格式
- 图片格式JPG, PNG, BMP等
- PDF文档
- Excel文件.xlsx, .xls
- PowerPoint文件.pptx, .ppt
## 快速开始
### 1. 基础构建和启动
```bash
# 构建镜像
docker build -t my-ocr-service:v1.0 .
# 启动容器
docker run -d -p 9000:9000 --name ocr-server my-ocr-service:v1.0
# 或使用docker-compose推荐
docker-compose up -d --build
```
### 2. 验证服务
#### 基础健康检查
```bash
# 健康检查
curl http://localhost:9000/health
# 预期返回
{"status":"ok"}
```
#### 完整功能测试
```bash
# 测试PDF文件OCR使用项目测试文件
curl -X POST \
-F "file=@example/test_resume.pdf" \
http://localhost:9000/ocr
# 预期返回格式
{
"code": 200,
"data": "--- Page 1 ---\n识别出的文字内容...",
"cost_time_ms": 1234.56
}
```
#### 详细验证脚本
```bash
# 创建完整的验证脚本
cat > verify-service.sh << 'EOF'
#!/bin/bash
BASE_URL="http://localhost:9000"
TEST_FILE="example/test_resume.pdf"
echo "=== OCR服务验证测试 ==="
echo "服务地址: $BASE_URL"
echo "测试时间: $(date)"
echo
# 1. 健康检查
echo "1. 健康检查测试..."
HEALTH_RESPONSE=$(curl -s -w "%{http_code}" -o /tmp/health_response.json $BASE_URL/health)
HTTP_CODE=${HEALTH_RESPONSE: -3}
if [ "$HTTP_CODE" = "200" ]; then
echo "✅ 健康检查通过 (HTTP $HTTP_CODE)"
echo " 响应: $(cat /tmp/health_response.json)"
else
echo "❌ 健康检查失败 (HTTP $HTTP_CODE)"
exit 1
fi
echo
# 2. 检查测试文件
echo "2. 检查测试文件..."
if [ -f "$TEST_FILE" ]; then
echo "✅ 测试文件存在: $TEST_FILE"
echo " 文件大小: $(ls -lh $TEST_FILE | awk '{print $5}')"
else
echo "❌ 测试文件不存在: $TEST_FILE"
echo " 请确保example/test_resume.pdf文件存在"
exit 1
fi
echo
# 3. PDF OCR测试
echo "3. PDF OCR功能测试..."
START_TIME=$(date +%s.%N)
OCR_RESPONSE=$(curl -s -w "%{http_code}" \
-X POST \
-F "file=@$TEST_FILE" \
-o /tmp/ocr_response.json \
$BASE_URL/ocr)
END_TIME=$(date +%s.%N)
HTTP_CODE=${OCR_RESPONSE: -3}
DURATION=$(echo "$END_TIME - $START_TIME" | bc)
if [ "$HTTP_CODE" = "200" ]; then
echo "✅ OCR测试通过 (HTTP $HTTP_CODE)"
echo " 请求耗时: ${DURATION}s"
# 解析响应
CODE=$(cat /tmp/ocr_response.json | python3 -c "import sys, json; print(json.load(sys.stdin).get('code', 'N/A'))")
COST_TIME=$(cat /tmp/ocr_response.json | python3 -c "import sys, json; print(json.load(sys.stdin).get('cost_time_ms', 'N/A'))")
DATA_LENGTH=$(cat /tmp/ocr_response.json | python3 -c "import sys, json; print(len(json.load(sys.stdin).get('data', '')))")
echo " 响应码: $CODE"
echo " 服务耗时: ${COST_TIME}ms"
echo " 识别文本长度: ${DATA_LENGTH}字符"
if [ "$CODE" = "200" ] && [ "$DATA_LENGTH" -gt "0" ]; then
echo "✅ OCR识别成功提取到文本内容"
else
echo "⚠️ OCR响应异常请检查日志"
fi
else
echo "❌ OCR测试失败 (HTTP $HTTP_CODE)"
echo " 响应内容: $(cat /tmp/ocr_response.json)"
exit 1
fi
echo
# 4. URL OCR测试可选
echo "4. URL OCR功能测试可选..."
URL_TEST="https://httpbin.org/status/200"
echo " 跳过URL测试如需测试请提供有效的文档URL"
echo
# 5. 性能基准测试
echo "5. 性能基准测试..."
echo " 执行3次OCR测试计算平均耗时..."
TOTAL_TIME=0
SUCCESS_COUNT=0
for i in {1..3}; do
echo -n " 测试 $i/3: "
START_TIME=$(date +%s.%N)
RESPONSE=$(curl -s -w "%{http_code}" \
-X POST \
-F "file=@$TEST_FILE" \
-o /tmp/perf_test_$i.json \
$BASE_URL/ocr)
END_TIME=$(date +%s.%N)
HTTP_CODE=${RESPONSE: -3}
DURATION=$(echo "$END_TIME - $START_TIME" | bc)
if [ "$HTTP_CODE" = "200" ]; then
echo "${DURATION}s ✅"
TOTAL_TIME=$(echo "$TOTAL_TIME + $DURATION" | bc)
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
else
echo "失败 (HTTP $HTTP_CODE) ❌"
fi
done
if [ "$SUCCESS_COUNT" -gt "0" ]; then
AVG_TIME=$(echo "scale=3; $TOTAL_TIME / $SUCCESS_COUNT" | bc)
echo " 平均耗时: ${AVG_TIME}s"
echo " 成功率: $SUCCESS_COUNT/3"
fi
echo
# 清理临时文件
rm -f /tmp/health_response.json /tmp/ocr_response.json /tmp/perf_test_*.json
echo "=== 验证测试完成 ==="
echo "如果所有测试都通过,服务已正常运行!"
EOF
chmod +x verify-service.sh
./verify-service.sh
```
#### 快速验证命令
```bash
# 一键验证所有功能
curl -s http://localhost:9000/health && \
curl -X POST -F "file=@example/test_resume.pdf" http://localhost:9000/ocr | \
python3 -m json.tool
# 简化版验证
echo "健康检查:" && curl -s http://localhost:9000/health && echo
echo "OCR测试:" && curl -X POST -F "file=@example/test_resume.pdf" http://localhost:9000/ocr
```
#### 其他文件格式测试
```bash
# 如果有其他测试文件,可以测试更多格式
# 测试图片文件(需要准备测试图片)
curl -X POST -F "file=@test_image.jpg" http://localhost:9000/ocr
# 测试Excel文件需要准备测试文件
curl -X POST -F "file=@test_document.xlsx" http://localhost:9000/ocr
# 测试PowerPoint文件需要准备测试文件
curl -X POST -F "file=@test_presentation.pptx" http://localhost:9000/ocr
# 测试URL识别
curl -X POST \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/document.pdf"}' \
http://localhost:9000/ocr/url
```
## 详细部署指南
### 环境要求
- Docker 20.10+
- Docker Compose 2.0+
- 系统内存建议4GB以上
- 磁盘空间至少2GB可用空间
### 构建选项
#### 选项1Docker Compose推荐
```bash
# 停止旧服务
docker-compose down
# 构建并启动
docker-compose up -d --build
# 查看日志
docker-compose logs -f ocr-server
```
#### 选项2手动构建
```bash
# 构建镜像
docker build -t my-ocr-service:v1.0 .
# 启动容器
docker run -d \
--name ocr-server \
-p 9000:9000 \
--restart always \
-e TZ=Asia/Shanghai \
my-ocr-service:v1.0
```
### 多架构支持
#### AMD64平台x86_64
```bash
# 使用默认Dockerfile
docker build -t my-ocr-service:v1.0-amd64 .
```
#### ARM64平台Apple Silicon, ARM服务器
```bash
# 使用ARM优化版Dockerfile
docker build -f Dockerfile.arm -t my-ocr-service:v1.0-arm64 .
# 或使用ARM版docker-compose
docker-compose -f docker-compose.arm.yml up -d --build
```
#### 多架构构建(跨平台)
```bash
# 启用buildx
docker buildx create --name multiarch --use
# 构建多架构镜像
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t my-ocr-service:v1.0 \
--push .
# 或使用提供的脚本
chmod +x build-multiarch.sh
./build-multiarch.sh
```
## 配置说明
### 环境变量
| 变量名 | 默认值 | 说明 |
|--------|--------|------|
| TZ | Asia/Shanghai | 时区设置 |
| OMP_NUM_THREADS | 4 | OpenMP线程数ARM平台 |
| OPENBLAS_NUM_THREADS | 4 | OpenBLAS线程数ARM平台 |
### 端口配置
- 服务端口9000
- 健康检查GET /health
- OCR接口POST /ocr
- URL识别POST /ocr/url
### 资源限制
```yaml
# docker-compose.yml中的资源配置
deploy:
resources:
limits:
memory: 2G
cpus: '2.0'
reservations:
memory: 1G
cpus: '1.0'
```
## 镜像管理
### 架构检测和选择
#### 检测当前系统架构
```bash
# 查看系统架构
uname -m
# 输出示例:
# x86_64 -> AMD64架构
# aarch64 -> ARM64架构
# arm64 -> ARM64架构macOS
# 查看Docker支持的架构
docker version --format '{{.Server.Arch}}'
# 检查镜像支持的架构
docker buildx imagetools inspect my-ocr-service:v1.0
```
#### 自动选择合适的镜像
```bash
# 创建架构检测脚本
cat > select-image.sh << 'EOF'
#!/bin/bash
ARCH=$(uname -m)
IMAGE_NAME="my-ocr-service"
VERSION="v1.0"
case $ARCH in
x86_64)
DOCKER_ARCH="amd64"
;;
aarch64|arm64)
DOCKER_ARCH="arm64"
;;
*)
echo "不支持的架构: $ARCH"
exit 1
;;
esac
echo "检测到架构: $ARCH -> Docker架构: $DOCKER_ARCH"
echo "使用镜像: ${IMAGE_NAME}:${VERSION}-${DOCKER_ARCH}"
# 检查镜像是否存在
if docker image inspect ${IMAGE_NAME}:${VERSION}-${DOCKER_ARCH} >/dev/null 2>&1; then
echo "镜像已存在,启动容器..."
docker run -d -p 9000:9000 --name ocr-server ${IMAGE_NAME}:${VERSION}-${DOCKER_ARCH}
else
echo "镜像不存在,请先导入对应架构的镜像文件"
echo "AMD64: docker load -i ocr-server-${VERSION}-amd64.tar"
echo "ARM64: docker load -i ocr-server-${VERSION}-arm64.tar"
fi
EOF
chmod +x select-image.sh
./select-image.sh
```
### 导出镜像
#### AMD64架构导出
```bash
# 导出AMD64镜像为tar文件
docker save -o ocr-server-v1.0-amd64.tar my-ocr-service:v1.0-amd64
# 压缩导出AMD64镜像
docker save my-ocr-service:v1.0-amd64 | gzip > ocr-server-v1.0-amd64.tar.gz
# 查看导出文件大小
ls -lh ocr-server-v1.0-amd64.tar*
```
#### ARM64架构导出
```bash
# 导出ARM64镜像为tar文件
docker save -o ocr-server-v1.0-arm64.tar my-ocr-service:v1.0-arm64
# 压缩导出ARM64镜像
docker save my-ocr-service:v1.0-arm64 | gzip > ocr-server-v1.0-arm64.tar.gz
# 查看导出文件大小
ls -lh ocr-server-v1.0-arm64.tar*
```
#### 多架构镜像导出
```bash
# 导出包含多架构的镜像
docker save -o ocr-server-v1.0-multiarch.tar my-ocr-service:v1.0
# 批量导出所有架构版本
docker save -o ocr-server-v1.0-all.tar \
my-ocr-service:v1.0-amd64 \
my-ocr-service:v1.0-arm64
# 压缩多架构镜像
docker save my-ocr-service:v1.0-amd64 my-ocr-service:v1.0-arm64 | \
gzip > ocr-server-v1.0-multiarch.tar.gz
```
#### 自动化导出脚本
```bash
# 创建导出脚本
cat > export-images.sh << 'EOF'
#!/bin/bash
VERSION=${1:-v1.0}
IMAGE_NAME="my-ocr-service"
echo "导出镜像版本: $VERSION"
# 检查镜像是否存在
if docker image inspect ${IMAGE_NAME}:${VERSION}-amd64 >/dev/null 2>&1; then
echo "导出AMD64镜像..."
docker save -o ${IMAGE_NAME}-${VERSION}-amd64.tar ${IMAGE_NAME}:${VERSION}-amd64
gzip ${IMAGE_NAME}-${VERSION}-amd64.tar
fi
if docker image inspect ${IMAGE_NAME}:${VERSION}-arm64 >/dev/null 2>&1; then
echo "导出ARM64镜像..."
docker save -o ${IMAGE_NAME}-${VERSION}-arm64.tar ${IMAGE_NAME}:${VERSION}-arm64
gzip ${IMAGE_NAME}-${VERSION}-arm64.tar
fi
echo "导出完成!"
ls -lh ${IMAGE_NAME}-${VERSION}-*.tar.gz
EOF
chmod +x export-images.sh
./export-images.sh v1.0
```
### 导入镜像
#### AMD64架构x86_64
```bash
# 从tar文件导入AMD64镜像
docker load -i ocr-server-v1.0-amd64.tar
# 从压缩文件导入AMD64镜像
gunzip -c ocr-server-v1.0-amd64.tar.gz | docker load
# 验证导入的AMD64镜像
docker images | grep ocr-server
docker inspect my-ocr-service:v1.0-amd64 | grep Architecture
```
#### ARM64架构Apple Silicon, ARM服务器
```bash
# 从tar文件导入ARM64镜像
docker load -i ocr-server-v1.0-arm64.tar
# 从压缩文件导入ARM64镜像
gunzip -c ocr-server-v1.0-arm64.tar.gz | docker load
# 验证导入的ARM64镜像
docker images | grep ocr-server
docker inspect my-ocr-service:v1.0-arm64 | grep Architecture
```
#### 通用导入(自动检测架构)
```bash
# 导入通用镜像(包含多架构)
docker load -i ocr-server-v1.0.tar
# 查看支持的架构
docker buildx imagetools inspect my-ocr-service:v1.0
# Docker会自动选择匹配当前系统的架构
docker run --rm my-ocr-service:v1.0 uname -m
```
#### 跨架构导入和使用
```bash
# 在AMD64系统上导入ARM64镜像需要启用实验性功能
export DOCKER_CLI_EXPERIMENTAL=enabled
docker load -i ocr-server-v1.0-arm64.tar
# 在ARM64系统上导入AMD64镜像
docker load -i ocr-server-v1.0-amd64.tar
# 强制运行非原生架构镜像(性能会下降)
docker run --platform linux/arm64 my-ocr-service:v1.0-arm64
docker run --platform linux/amd64 my-ocr-service:v1.0-amd64
```
### 推送到仓库
#### 单架构推送
```bash
# 推送AMD64镜像
docker tag my-ocr-service:v1.0-amd64 your-registry.com/ocr-service:v1.0-amd64
docker push your-registry.com/ocr-service:v1.0-amd64
# 推送ARM64镜像
docker tag my-ocr-service:v1.0-arm64 your-registry.com/ocr-service:v1.0-arm64
docker push your-registry.com/ocr-service:v1.0-arm64
```
#### 多架构推送(推荐)
```bash
# 创建并推送多架构manifest
docker buildx create --name multiarch --use
# 构建并推送多架构镜像
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t your-registry.com/ocr-service:v1.0 \
--push .
# 验证多架构镜像
docker buildx imagetools inspect your-registry.com/ocr-service:v1.0
```
#### 从本地镜像创建多架构推送
```bash
# 推送各架构镜像
docker push your-registry.com/ocr-service:v1.0-amd64
docker push your-registry.com/ocr-service:v1.0-arm64
# 创建多架构manifest
docker manifest create your-registry.com/ocr-service:v1.0 \
your-registry.com/ocr-service:v1.0-amd64 \
your-registry.com/ocr-service:v1.0-arm64
# 设置架构信息
docker manifest annotate your-registry.com/ocr-service:v1.0 \
your-registry.com/ocr-service:v1.0-amd64 --arch amd64
docker manifest annotate your-registry.com/ocr-service:v1.0 \
your-registry.com/ocr-service:v1.0-arm64 --arch arm64
# 推送manifest
docker manifest push your-registry.com/ocr-service:v1.0
```
## 生产环境部署
### 1. 服务器部署
```bash
# 上传镜像到服务器
scp ocr-server-v1.0.tar root@your-server:/opt/docker-apps/
# 在服务器上导入
ssh root@your-server
cd /opt/docker-apps/
docker load -i ocr-server-v1.0.tar
# 启动服务
docker-compose up -d --force-recreate
```
### 2. 反向代理配置Nginx
```nginx
server {
listen 80;
server_name ocr.yourdomain.com;
location / {
proxy_pass http://localhost:9000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 文件上传大小限制
client_max_body_size 50M;
}
}
```
### 3. 监控和日志
```bash
# 查看容器状态
docker ps
docker stats ocr-server
# 查看日志
docker logs -f ocr-server
docker-compose logs -f
# 健康检查
curl -f http://localhost:9000/health
```
## 故障排除
### 常见问题
1. **内存不足**
```bash
# 增加内存限制
docker run --memory=4g my-ocr-service:v1.0
```
2. **端口冲突**
```bash
# 检查端口占用
netstat -tlnp | grep 9000
# 更换端口
docker run -p 9001:9000 my-ocr-service:v1.0
```
3. **ARM平台性能问题**
```bash
# 使用ARM优化版本
docker-compose -f docker-compose.arm.yml up -d
```
4. **依赖库问题**
```bash
# 重新构建镜像
docker build --no-cache -t my-ocr-service:v1.0 .
```
### 调试命令
```bash
# 进入容器调试
docker exec -it ocr-server bash
# 查看容器资源使用
docker stats ocr-server
# 查看镜像层信息
docker history my-ocr-service:v1.0
# 检查容器健康状态
docker inspect ocr-server | grep Health -A 10
```
## API使用示例
### 文件上传识别
```bash
# 上传PDF文件
curl -X POST \
-F "file=@document.pdf" \
http://localhost:9000/ocr
# 上传图片
curl -X POST \
-F "file=@image.jpg" \
http://localhost:9000/ocr
```
### URL识别
```bash
# 识别网络文件
curl -X POST \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/document.pdf"}' \
http://localhost:9000/ocr/url
```
## 性能优化
### 1. 镜像优化
- 使用多阶段构建减小镜像大小
- 清理不必要的依赖和缓存
- 使用.dockerignore排除无关文件
### 2. 运行时优化
```bash
# 设置合适的线程数
docker run -e OMP_NUM_THREADS=4 my-ocr-service:v1.0
# 使用内存映射
docker run --shm-size=1g my-ocr-service:v1.0
```
### 3. 集群部署
```yaml
# docker-compose.yml 扩展配置
services:
ocr-server:
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
```
## 版本管理
### 版本标记策略
```bash
# 开发版本
docker tag my-ocr-service:latest my-ocr-service:dev
# 测试版本
docker tag my-ocr-service:latest my-ocr-service:test
# 生产版本
docker tag my-ocr-service:latest my-ocr-service:v1.0
docker tag my-ocr-service:latest my-ocr-service:stable
```
### 回滚策略
```bash
# 保存当前版本
docker tag my-ocr-service:latest my-ocr-service:backup-$(date +%Y%m%d)
# 回滚到上一版本
docker-compose down
docker tag my-ocr-service:v0.9 my-ocr-service:latest
docker-compose up -d
```
---
## 联系支持
如遇到部署问题,请提供以下信息:
- 操作系统和架构
- Docker版本
- 错误日志
- 部署配置文件