feat: consolidate env config and add deployment files
- Add debug_font_path, demo_docs_dir, e2e_api_base_url to config.py - Fix hardcoded paths in pp_structure_debug.py, create_demo_images.py - Fix hardcoded paths in test files - Update .env.example with new configuration options - Update .gitignore to exclude AI development files (.claude/, openspec/, AGENTS.md, CLAUDE.md) - Add production startup script (start-prod.sh) - Add README.md with project documentation - Add 1panel Docker deployment files (docker-compose.yml, Dockerfiles, nginx.conf) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
24
deploy/1panel/.env.example
Normal file
24
deploy/1panel/.env.example
Normal file
@@ -0,0 +1,24 @@
|
||||
# Tool_OCR - 1Panel Docker Deployment Configuration
|
||||
# Copy this file to .env and fill in your values
|
||||
|
||||
# ===== Service Ports =====
|
||||
BACKEND_PORT=8000
|
||||
FRONTEND_PORT=12010
|
||||
|
||||
# ===== Database Configuration =====
|
||||
MYSQL_HOST=your-mysql-host
|
||||
MYSQL_PORT=3306
|
||||
MYSQL_USER=your-username
|
||||
MYSQL_PASSWORD=your-password
|
||||
MYSQL_DATABASE=your-database
|
||||
|
||||
# ===== Security =====
|
||||
# Generate a random string for production: openssl rand -hex 32
|
||||
SECRET_KEY=your-secret-key-change-this
|
||||
|
||||
# ===== Translation API (DIFY) =====
|
||||
DIFY_BASE_URL=https://your-dify-instance.example.com/v1
|
||||
DIFY_API_KEY=your-dify-api-key
|
||||
|
||||
# ===== Logging =====
|
||||
LOG_LEVEL=INFO
|
||||
67
deploy/1panel/Dockerfile.backend
Normal file
67
deploy/1panel/Dockerfile.backend
Normal file
@@ -0,0 +1,67 @@
|
||||
# Tool_OCR Backend Dockerfile
|
||||
# Multi-stage build for optimized image size
|
||||
|
||||
# Stage 1: Build environment
|
||||
FROM python:3.12-slim as builder
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
# Install build dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy requirements and install dependencies
|
||||
COPY backend/requirements.txt .
|
||||
RUN pip install --no-cache-dir --user -r requirements.txt
|
||||
|
||||
# Stage 2: Runtime environment
|
||||
FROM python:3.12-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install runtime dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
libgl1-mesa-glx \
|
||||
libglib2.0-0 \
|
||||
libsm6 \
|
||||
libxext6 \
|
||||
libxrender1 \
|
||||
libgomp1 \
|
||||
pandoc \
|
||||
poppler-utils \
|
||||
fonts-dejavu-core \
|
||||
fonts-noto-cjk \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy Python packages from builder
|
||||
COPY --from=builder /root/.local /root/.local
|
||||
ENV PATH=/root/.local/bin:$PATH
|
||||
|
||||
# Copy application code
|
||||
COPY backend/ /app/backend/
|
||||
|
||||
# Create necessary directories
|
||||
RUN mkdir -p /app/backend/uploads/{temp,processed,images} \
|
||||
&& mkdir -p /app/backend/storage/{markdown,json,exports,results} \
|
||||
&& mkdir -p /app/backend/models/paddleocr \
|
||||
&& mkdir -p /app/backend/logs
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app/backend
|
||||
|
||||
# Environment variables
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8000
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
CMD curl -f http://localhost:8000/health || exit 1
|
||||
|
||||
# Run application
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
|
||||
38
deploy/1panel/Dockerfile.frontend
Normal file
38
deploy/1panel/Dockerfile.frontend
Normal file
@@ -0,0 +1,38 @@
|
||||
# Tool_OCR Frontend Dockerfile
|
||||
# Multi-stage build for optimized image size
|
||||
|
||||
# Stage 1: Build
|
||||
FROM node:20-alpine as builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY frontend/package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm ci
|
||||
|
||||
# Copy source code
|
||||
COPY frontend/ ./
|
||||
|
||||
# Build application
|
||||
RUN npm run build
|
||||
|
||||
# Stage 2: Production
|
||||
FROM nginx:alpine
|
||||
|
||||
# Copy built files
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
# Copy nginx configuration
|
||||
COPY deploy/1panel/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# Expose port
|
||||
EXPOSE 80
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
|
||||
CMD curl -f http://localhost:80 || exit 1
|
||||
|
||||
# Run nginx
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
125
deploy/1panel/README.md
Normal file
125
deploy/1panel/README.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# Tool_OCR - 1Panel Docker 佈署指南
|
||||
|
||||
本目錄包含 1Panel 平台的 Docker 佈署配置。
|
||||
|
||||
## 前置需求
|
||||
|
||||
- Docker 20.10+
|
||||
- Docker Compose 2.0+
|
||||
- NVIDIA Container Toolkit(GPU 加速)
|
||||
- MySQL 8.0+(外部資料庫)
|
||||
|
||||
## 佈署步驟
|
||||
|
||||
### 1. 配置環境變數
|
||||
|
||||
```bash
|
||||
# 複製環境變數範本
|
||||
cp .env.example .env
|
||||
|
||||
# 編輯配置
|
||||
nano .env
|
||||
```
|
||||
|
||||
必要配置項:
|
||||
- `MYSQL_*` - 資料庫連線設定
|
||||
- `SECRET_KEY` - JWT 簽名金鑰(使用 `openssl rand -hex 32` 生成)
|
||||
- `DIFY_*` - 翻譯 API 設定
|
||||
|
||||
### 2. 建置映像
|
||||
|
||||
```bash
|
||||
# 建置所有服務
|
||||
docker-compose build
|
||||
|
||||
# 或分別建置
|
||||
docker-compose build backend
|
||||
docker-compose build frontend
|
||||
```
|
||||
|
||||
### 3. 啟動服務
|
||||
|
||||
```bash
|
||||
# 啟動所有服務
|
||||
docker-compose up -d
|
||||
|
||||
# 查看日誌
|
||||
docker-compose logs -f
|
||||
|
||||
# 查看狀態
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
### 4. 存取服務
|
||||
|
||||
- 前端介面:http://your-server:12010
|
||||
- API 文件:http://your-server:8000/docs
|
||||
- 健康檢查:http://your-server:8000/health
|
||||
|
||||
## 服務管理
|
||||
|
||||
```bash
|
||||
# 停止服務
|
||||
docker-compose down
|
||||
|
||||
# 重啟服務
|
||||
docker-compose restart
|
||||
|
||||
# 更新服務
|
||||
docker-compose pull
|
||||
docker-compose up -d --build
|
||||
|
||||
# 查看資源使用
|
||||
docker stats
|
||||
```
|
||||
|
||||
## 資料持久化
|
||||
|
||||
以下 Docker volumes 會自動建立:
|
||||
|
||||
| Volume | 用途 |
|
||||
|--------|------|
|
||||
| `tool_ocr_uploads` | 上傳檔案 |
|
||||
| `tool_ocr_storage` | 處理結果 |
|
||||
| `tool_ocr_logs` | 應用日誌 |
|
||||
| `tool_ocr_models` | OCR 模型快取 |
|
||||
|
||||
## GPU 加速
|
||||
|
||||
預設配置會使用 NVIDIA GPU。如果不需要 GPU 加速,請修改 `docker-compose.yml`,移除 `deploy.resources.reservations` 區塊。
|
||||
|
||||
## 常見問題
|
||||
|
||||
### Q: 服務啟動失敗?
|
||||
|
||||
檢查日誌:
|
||||
```bash
|
||||
docker-compose logs backend
|
||||
docker-compose logs frontend
|
||||
```
|
||||
|
||||
### Q: 資料庫連線失敗?
|
||||
|
||||
確認:
|
||||
1. MySQL 服務正在運行
|
||||
2. 防火牆允許連接
|
||||
3. 使用者權限正確
|
||||
|
||||
### Q: GPU 不可用?
|
||||
|
||||
確認 NVIDIA Container Toolkit 已安裝:
|
||||
```bash
|
||||
nvidia-smi
|
||||
docker run --rm --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi
|
||||
```
|
||||
|
||||
## 1Panel 整合
|
||||
|
||||
在 1Panel 中:
|
||||
|
||||
1. 進入「應用商店」→「自訂應用」
|
||||
2. 上傳此目錄的所有檔案
|
||||
3. 配置環境變數
|
||||
4. 點擊「安裝」
|
||||
|
||||
或使用 1Panel 的「容器」功能直接導入 `docker-compose.yml`。
|
||||
68
deploy/1panel/docker-compose.yml
Normal file
68
deploy/1panel/docker-compose.yml
Normal file
@@ -0,0 +1,68 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/1panel/Dockerfile.backend
|
||||
container_name: tool_ocr_backend
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${BACKEND_PORT:-8000}:8000"
|
||||
environment:
|
||||
- MYSQL_HOST=${MYSQL_HOST}
|
||||
- MYSQL_PORT=${MYSQL_PORT}
|
||||
- MYSQL_USER=${MYSQL_USER}
|
||||
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
|
||||
- MYSQL_DATABASE=${MYSQL_DATABASE}
|
||||
- SECRET_KEY=${SECRET_KEY}
|
||||
- DIFY_BASE_URL=${DIFY_BASE_URL}
|
||||
- DIFY_API_KEY=${DIFY_API_KEY}
|
||||
- CORS_ORIGINS=http://localhost:${FRONTEND_PORT:-12010}
|
||||
- LOG_LEVEL=${LOG_LEVEL:-INFO}
|
||||
volumes:
|
||||
- tool_ocr_uploads:/app/backend/uploads
|
||||
- tool_ocr_storage:/app/backend/storage
|
||||
- tool_ocr_logs:/app/backend/logs
|
||||
- tool_ocr_models:/app/backend/models
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
deploy:
|
||||
resources:
|
||||
reservations:
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: 1
|
||||
capabilities: [gpu]
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/1panel/Dockerfile.frontend
|
||||
container_name: tool_ocr_frontend
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${FRONTEND_PORT:-12010}:80"
|
||||
environment:
|
||||
- VITE_API_BASE_URL=http://localhost:${BACKEND_PORT:-8000}
|
||||
depends_on:
|
||||
- backend
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:80"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
volumes:
|
||||
tool_ocr_uploads:
|
||||
tool_ocr_storage:
|
||||
tool_ocr_logs:
|
||||
tool_ocr_models:
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: tool_ocr_network
|
||||
37
deploy/1panel/nginx.conf
Normal file
37
deploy/1panel/nginx.conf
Normal file
@@ -0,0 +1,37 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# Gzip compression
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_proxied expired no-cache no-store private auth;
|
||||
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml application/javascript;
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
|
||||
# SPA routing - all routes go to index.html
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# Static assets caching
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# Health check endpoint
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "healthy\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user