diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4a14bfe --- /dev/null +++ b/.dockerignore @@ -0,0 +1,20 @@ +.venv/ +__pycache__/ +*.pyc +.git/ +.gitignore +.claude/ +.playwright-mcp/ +.trae/ +node_modules/ +web/frontend/node_modules/ +data/ +docs/ +tests/ +*.md +!README.md +release/ +dist/ +build/ +*.spec +*.exe diff --git a/Dockerfile.backend b/Dockerfile.backend new file mode 100644 index 0000000..8968392 --- /dev/null +++ b/Dockerfile.backend @@ -0,0 +1,28 @@ +FROM python:3.11-slim + +WORKDIR /app + +# Install system dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + gcc \ + && rm -rf /var/lib/apt/lists/* + +# Install Python dependencies +COPY web/backend/requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# Copy project files +COPY app/ ./app/ +COPY config/ ./config/ +COPY config.ini ./ +COPY templates/ ./templates/ +COPY web/ ./web/ + +# Create data directories +RUN mkdir -p data/input data/output data/result data/temp + +# Expose port +EXPOSE 18889 + +# Run +CMD ["python", "-m", "uvicorn", "web.backend.main:app", "--host", "0.0.0.0", "--port", "18889"] diff --git a/Dockerfile.frontend b/Dockerfile.frontend new file mode 100644 index 0000000..940d4c8 --- /dev/null +++ b/Dockerfile.frontend @@ -0,0 +1,18 @@ +# Build stage +FROM node:20-alpine AS build + +WORKDIR /app +COPY web/frontend/package.json web/frontend/package-lock.json* ./ +RUN npm install +COPY web/frontend/ . +RUN npm run build + +# Production stage +FROM nginx:alpine + +COPY --from=build /app/dist /usr/share/nginx/html +COPY nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 18888 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/README.md b/README.md index 06c6f74..1afb6a5 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,29 @@ cd web && python -m uvicorn backend.main:app --host 0.0.0.0 --port 8000 **默认账号:** `admin` / `admin123`(首次登录后建议修改密码) +### Docker 部署 + +```bash +# 构建并启动 +docker-compose up -d --build + +# 访问 +# 前端: http://服务器IP:18888 +# 后端 API: http://服务器IP:18889 + +# 查看日志 +docker-compose logs -f + +# 停止 +docker-compose down +``` + +**端口说明:** +- `18888` — 前端 (Nginx) +- `18889` — 后端 API (FastAPI) + +**数据持久化:** `data/` 目录挂载到宿主机,数据库和上传文件不会丢失。 + ## 项目结构 ``` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..54c68e3 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,27 @@ +services: + backend: + build: + context: . + dockerfile: Dockerfile.backend + container_name: yixuan-backend + ports: + - "18889:18889" + volumes: + - ./data:/app/data + - ./config.ini:/app/config.ini:ro + - ./config:/app/config:ro + - ./templates:/app/templates:ro + env_file: + - .env + restart: unless-stopped + + frontend: + build: + context: . + dockerfile: Dockerfile.frontend + container_name: yixuan-frontend + ports: + - "18888:18888" + depends_on: + - backend + restart: unless-stopped diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..3cc8412 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,43 @@ +server { + listen 18888; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + # Gzip compression + gzip on; + gzip_types text/plain text/css application/json application/javascript text/xml; + gzip_min_length 1000; + + # API proxy to backend + location /api/ { + proxy_pass http://backend:18889; + 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; + } + + # WebSocket proxy to backend + location /ws/ { + proxy_pass http://backend:18889; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_read_timeout 86400; + } + + # Vue Router history mode - serve index.html for all routes + location / { + try_files $uri $uri/ /index.html; + } + + # Cache static assets + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 30d; + add_header Cache-Control "public, immutable"; + } +} diff --git a/web/__init__.py b/web/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web/backend/requirements.txt b/web/backend/requirements.txt new file mode 100644 index 0000000..281a3e5 --- /dev/null +++ b/web/backend/requirements.txt @@ -0,0 +1,19 @@ +# Web backend dependencies +fastapi>=0.104.0 +uvicorn[standard]>=0.24.0 +python-jose[cryptography]>=3.3.0 +bcrypt>=4.0.0 +python-multipart>=0.0.6 +httpx>=0.25.0 +werkzeug>=3.0.0 + +# Core app dependencies (needed by processing endpoints) +pandas>=1.3.0 +openpyxl>=3.0.0 +xlrd>=2.0.0,<2.1.0 +xlwt>=1.3.0 +xlutils>=2.0.0 +numpy>=1.19.0 +requests>=2.25.0 +python-dotenv>=1.0.0 +configparser>=5.0.0