| # Hugging Face Space 部署指南 |
|
|
| 本指南将详细介绍如何将 QSSS 应用部署到 Hugging Face Space。 |
|
|
| ## 1. Hugging Face Space 创建步骤 |
|
|
| 1. **登录 Hugging Face**: 访问 [Hugging Face 官网](https://huggingface.co/) 并登录您的账户。如果您没有账户,请先注册。 |
| 2. **创建新的 Space**: |
| * 点击页面右上角的个人头像,选择 "New Space"。 |
| * 填写 Space 名称 (例如: `your-username/qsss-app`)。 |
| * 选择一个许可证 (例如: `MIT License`)。 |
| * 选择 Space 类型: 推荐选择 `Docker`,因为我们将使用 Docker 容器进行部署。 |
| * 选择可见性: `Public` (公开) 或 `Private` (私有),根据您的需求选择。 |
| * 点击 "Create Space"。 |
| 3. **克隆 Space 仓库**: 创建 Space 后,您将看到一个页面,其中包含克隆仓库的 Git 命令。复制该命令并在本地终端执行,将 Space 仓库克隆到您的本地机器。 |
|
|
| ```bash |
| git clone https://huggingface.co/spaces/your-username/your-space-name |
| ``` |
| |
| ## 2. Docker 容器配置说明 (多阶段构建) |
|
|
| 为了优化镜像体积并整合前后端服务,我们采用了多阶段 Dockerfile 构建。这个 `Dockerfile` 将负责构建前端应用、后端应用,并最终将它们以及 Nginx 和 Supervisor 整合到一个轻量级的运行时镜像中。 |
|
|
| 以下是新的 `Dockerfile` 结构: |
|
|
| ```dockerfile |
| # 阶段1: Node镜像构建前端 (qsss-web) |
| FROM node:20-alpine AS frontend_builder |
| |
| WORKDIR /app/qsss-web |
| |
| # 复制前端依赖文件并安装 |
| COPY qsss-web/package.json qsss-web/package-lock.json ./ |
| RUN npm install --frozen-lockfile |
| |
| # 复制前端所有代码 |
| COPY qsss-web/ . |
| |
| # 构建前端应用 |
| RUN npm run build |
| |
| # 阶段2: Python镜像构建后端 |
| FROM python:3.9-slim-bookworm AS backend_builder |
| |
| WORKDIR /app |
| |
| # 安装系统依赖 |
| RUN apt-get update && apt-get install -y \ |
| build-essential \ |
| gcc \ |
| gfortran \ |
| wget \ |
| libssl-dev \ |
| ninja-build \ |
| libopenblas-dev \ |
| liblapack-dev \ |
| pkg-config \ |
| && apt-get clean \ |
| && rm -rf /var/lib/apt/lists/* |
| |
| # 安装TA-Lib |
| RUN mkdir -p /ta-lib-build && cd /ta-lib-build && \ |
| wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz && \ |
| tar -xzf ta-lib-0.4.0-src.tar.gz && \ |
| cd ta-lib/ && \ |
| ./configure --prefix=/usr && \ |
| make && \ |
| make install && \ |
| # 创建兼容性符号链接解决库名称问题 |
| ln -s /usr/lib/libta_lib.so /usr/lib/libta-lib.so && \ |
| ln -s /usr/lib/libta_lib.so.0 /usr/lib/libta-lib.so.0 && \ |
| ldconfig && \ |
| cd / && \ |
| rm -rf /ta-lib-build |
| |
| # 创建Python虚拟环境 |
| ENV VIRTUAL_ENV=/app/backend_venv |
| RUN python -m venv $VIRTUAL_ENV |
| ENV PATH="$VIRTUAL_ENV/bin:$PATH" |
| |
| # 复制后端依赖文件并安装 |
| COPY requirements.txt backend/requirements.txt ./ |
| RUN pip install --no-cache-dir --upgrade pip setuptools wheel && \ |
| pip install --no-cache-dir \ |
| Cython==0.29.36 \ |
| numpy==1.26.4 \ |
| pythran \ |
| pybind11 \ |
| versioneer \ |
| importlib-metadata==6.0.0 \ |
| zipp==3.15.0 && \ |
| pip install --no-cache-dir --no-build-isolation -r requirements.txt && \ |
| pip install --no-cache-dir --no-build-isolation -r backend/requirements.txt |
| |
| # 复制后端代码 |
| COPY backend/ backend/ |
| |
| # 阶段3: 运行时镜像整合前后端 |
| FROM debian:bookworm-slim AS final |
| |
| # 安装Nginx和Supervisor |
| RUN apt-get update && apt-get install -y \ |
| nginx \ |
| supervisor \ |
| ca-certificates \ |
| && apt-get clean \ |
| && rm -rf /var/lib/apt/lists/* |
| |
| # 创建必要的目录 |
| RUN mkdir -p /app/qsss-web/out \ |
| /app/backend \ |
| /app/backend_venv \ |
| /etc/nginx/sites-enabled \ |
| /var/log/supervisor |
| |
| # 从前端构建阶段复制前端静态文件 |
| COPY --from=frontend_builder /app/qsss-web/out /app/qsss-web/out |
| |
| # 从后端构建阶段复制Python虚拟环境 |
| COPY --from=backend_builder /app/backend_venv /app/backend_venv |
| |
| # 从后端构建阶段复制后端代码 |
| COPY --from=backend_builder /app/backend /app/backend |
| |
| # 复制Nginx配置 |
| COPY nginx.conf /etc/nginx/sites-enabled/default |
| |
| # 复制Supervisor配置 |
| COPY supervisord.conf /etc/supervisord.conf |
| |
| # 设置环境变量 |
| ENV DATABASE_URL=sqlite:///:memory: \ |
| REDIS_MODE=memory \ |
| SECRET_KEY=your_secret_key_here \ |
| ENVIRONMENT=production \ |
| MEMORY_MODE=true \ |
| PYTHONPATH=/app/backend:$PYTHONPATH |
| |
| # 暴露端口 |
| EXPOSE 7860 |
| |
| # 启动命令 |
| CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"] |
| ``` |
|
|
| **Nginx 配置 (`nginx.conf`)**: |
| Nginx 作为反向代理服务器,负责将外部请求路由到正确的前端或后端服务。 |
|
|
| ```nginx |
| events { |
| worker_connections 1024; |
| } |
| |
| http { |
| include mime.types; |
| default_type application/octet-stream; |
| sendfile on; |
| keepalive_timeout 65; |
| |
| server { |
| listen 80; |
| server_name localhost; |
| |
| # 前端服务 (Next.js 构建输出) |
| location / { |
| root /app/qsss-web/out; |
| try_files $uri $uri/ /index.html; |
| } |
| |
| # 后端API服务 |
| location /api/ { |
| proxy_pass http://127.0.0.1:7860/; |
| 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; |
| } |
| } |
| } |
| ``` |
|
|
| **Supervisor 配置 (`supervisord.conf`)**: |
| Supervisor 用于管理 Nginx、前端和后端服务的进程,确保它们在容器内同时运行并自动重启。 |
|
|
| ```ini |
| [supervisord] |
| nodaemon=true |
| |
| [program:nginx] |
| command=/usr/sbin/nginx -g "daemon off;" |
| autostart=true |
| autorestart=true |
| startretries=3 |
| stdout_logfile=/dev/stdout |
| stdout_logfile_maxbytes=0 |
| stderr_logfile=/dev/stderr |
| stderr_logfile_maxbytes=0 |
| |
| [program:backend] |
| command=/app/backend_venv/bin/uvicorn backend.app.main:app --host 0.0.0.0 --port 7860 |
| directory=/app/backend |
| autostart=true |
| autorestart=true |
| startretries=3 |
| stdout_logfile=/dev/stdout |
| stdout_logfile_maxbytes=0 |
| stderr_logfile=/dev/stderr |
| stderr_logfile_maxbytes=0 |
| |
| [program:frontend] |
| command=npm run start --prefix /app/qsss-web |
| directory=/app/qsss-web |
| autostart=true |
| autorestart=true |
| startretries=3 |
| stdout_logfile=/dev/stdout |
| stdout_logfile_maxbytes=0 |
| stderr_logfile=/dev/stderr |
| stderr_logfile_maxbytes=0 |
| ``` |
|
|
| **重要提示**: |
| * **端口暴露**: 容器内部的 Nginx 监听 80 端口,后端服务监听 7860 端口。Dockerfile 暴露 7860 端口,但 Hugging Face Space 会将外部请求路由到 80 端口,Nginx 会处理这些请求。 |
| * **Hugging Face Space 兼容性**: 这种单容器多服务部署方式兼容 Hugging Face Space 的单容器部署模型,同时实现了前后端和 Nginx 的整合。 |
|
|
| ## 3. 部署步骤 |
|
|
| 1. **更新项目文件**: |
| * 将上述新的 `Dockerfile` 替换您项目根目录下的旧文件。 |
| * 将 `nginx.conf` 和 `supervisord.conf` 文件放置在您的项目根目录。 |
| * 确保 `qsss-web/package.json` 中的 `start` 脚本配置正确 (通常为 `next start`)。 |
| 2. **提交并推送**: 将所有更改提交到您的 Git 仓库并推送到 Hugging Face Space 远程仓库。 |
|
|
| ```bash |
| git add . |
| git commit -m "feat: Update Dockerfile for multi-stage build with Nginx and Supervisor" |
| git push |
| ``` |
| 3. **Hugging Face Space 自动构建**: Hugging Face Space 会自动检测到您的仓库更新,并根据新的 `Dockerfile` 重新构建和部署您的应用。您可以在 Space 页面查看构建和运行日志。 |
| |
| ## 4. 环境变量设置建议 |
|
|
| 在 Hugging Face Space 中,您可以通过 "Settings" -> "Space secrets" 来设置环境变量。这些变量在您的 Docker 容器中是可用的。 |
|
|
| 建议设置的环境变量包括: |
|
|
| * `DATABASE_URL`: 数据库连接字符串 (如果使用外部数据库)。 |
| * `SECRET_KEY`: 用于 JWT 认证的密钥。 |
| * `HF_TOKEN`: 如果您的应用需要访问 Hugging Face Hub 上的私有模型或数据集,则需要设置此令牌。 |
| * 其他任何您的应用所需的配置参数。 |
|
|
| **示例**: |
|
|
| | 变量名 | 建议值 | 说明 | |
| | :------------- | :--------------------------------------- | :--------------------------------------- | |
| | `SECRET_KEY` | `your_super_secret_key_here` | 用于认证和加密,请生成一个强随机字符串。 | |
| | `DATABASE_URL` | `sqlite:///./sql_app.db` 或您的外部数据库连接 | 数据库连接字符串。 | |
| | `HF_TOKEN` | `hf_YOUR_TOKEN` | 访问 Hugging Face Hub 的令牌。 | |
|
|
| ## 5. 常见问题排查 |
|
|
| * **应用无法启动**: |
| * 检查 `Dockerfile` 中的路径是否正确。 |
| * 查看 Hugging Face Space 的日志 (Logs 选项卡),查找错误信息。 |
| * 确保所有依赖都已正确安装。 |
| * 检查端口是否正确暴露 (通常是 7860,由 Nginx 代理)。 |
| * **环境变量未生效**: |
| * 确保您在 Hugging Face Space 的 "Settings" -> "Space secrets" 中正确设置了环境变量。 |
| * 检查您的应用代码是否正确读取了这些环境变量。 |
| * **内存或 CPU 不足**: |
| * Hugging Face Space 提供不同大小的硬件配置。如果您的应用需要更多资源,请考虑升级 Space 的硬件。 |
| * 优化您的代码,减少内存和 CPU 使用。 |
| * **Git LFS 问题**: |
| * 如果您的仓库包含大文件 (例如模型权重),请确保您已正确配置 Git LFS。 |
| * 在克隆仓库后,运行 `git lfs pull` 来下载大文件。 |