Spaces:
Paused
Paused
| FROM python:3.10-slim | |
| # 创建用户(HF Spaces 要求 UID=1000) | |
| RUN useradd -m -u 1000 user | |
| USER root | |
| # 安装系统依赖(Blender + 完整的无头渲染支持) | |
| RUN apt-get update && apt-get install -y \ | |
| blender \ | |
| xvfb \ | |
| xorg \ | |
| libgl1 \ | |
| libglib2.0-0 \ | |
| libsm6 \ | |
| libxrender1 \ | |
| libxext6 \ | |
| libxi6 \ | |
| libxkbcommon-x11-0 \ | |
| libgomp1 \ | |
| libxxf86vm1 \ | |
| libxfixes3 \ | |
| wget \ | |
| unzip \ | |
| git \ | |
| && apt-get clean \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # 下载完整 LDraw 库(官方 + 非官方零件) | |
| RUN echo "📦 Downloading complete LDraw library..." && \ | |
| # 官方零件库 (~18MB → ~70MB) | |
| wget -q --retry-connrefused --waitretry=5 --tries=3 \ | |
| https://library.ldraw.org/library/updates/complete.zip \ | |
| -O /tmp/ldraw.zip && \ | |
| echo "📂 Extracting official LDraw library..." && \ | |
| unzip -q /tmp/ldraw.zip -d /home/user/ && \ | |
| rm /tmp/ldraw.zip && \ | |
| # 非官方零件库 (~12MB → ~50MB) | |
| echo "📦 Downloading unofficial LDraw parts..." && \ | |
| wget -q --retry-connrefused --waitretry=5 --tries=3 \ | |
| https://library.ldraw.org/library/unofficial/ldrawunf.zip \ | |
| -O /tmp/ldrawunf.zip && \ | |
| mkdir -p /home/user/ldraw/unofficial && \ | |
| echo "📂 Extracting unofficial parts..." && \ | |
| unzip -q /tmp/ldrawunf.zip -d /home/user/ldraw/unofficial/ && \ | |
| rm /tmp/ldrawunf.zip && \ | |
| chown -R user:user /home/user/ldraw && \ | |
| echo "✅ Complete LDraw library installed" | |
| # 验证 LDraw 库完整性(增强版 - 详细输出) | |
| RUN test -d /home/user/ldraw/parts && \ | |
| test -d /home/user/ldraw/unofficial/parts && \ | |
| echo "📊 Official parts: $(find /home/user/ldraw/parts -name '*.dat' | wc -l)" && \ | |
| echo "📊 Unofficial parts: $(find /home/user/ldraw/unofficial/parts -name '*.dat' | wc -l)" && \ | |
| echo "📦 Sample official parts:" && \ | |
| ls /home/user/ldraw/parts/*.dat 2>/dev/null | head -10 | xargs -n 1 basename && \ | |
| echo "📦 Sample unofficial parts:" && \ | |
| ls /home/user/ldraw/unofficial/parts/*.dat 2>/dev/null | head -10 | xargs -n 1 basename && \ | |
| echo "🔍 Checking critical parts from GPT outputs..." && \ | |
| for part in 4081.dat 60470.dat 2431.dat 92583.dat 92593.dat 18892.dat 15068.dat 2412.dat 61678.dat 3666.dat; do \ | |
| if find /home/user/ldraw -name "$part" | grep -q .; then \ | |
| echo " ✓ Found $part"; \ | |
| else \ | |
| echo " ✗ Missing $part (will check if it's a subpart)"; \ | |
| fi; \ | |
| done && \ | |
| echo "✓ LDraw installation verified" || \ | |
| (echo "✗ LDraw installation failed" && exit 1) | |
| # 以 root 身份预创建 X11 socket 目录(解决 Xvfb 权限问题) | |
| RUN mkdir -p /tmp/.X11-unix && \ | |
| chmod 1777 /tmp/.X11-unix && \ | |
| chown root:root /tmp/.X11-unix && \ | |
| echo "✓ X11 socket directory created" | |
| # 切换到普通用户 | |
| USER user | |
| ENV HOME=/home/user \ | |
| PATH=/home/user/.local/bin:$PATH \ | |
| LDRAW_LIBRARY_PATH=/home/user/ldraw \ | |
| HF_HOME=/home/user/.cache/huggingface \ | |
| HF_HUB_CACHE=/home/user/.cache/huggingface/hub \ | |
| TRANSFORMERS_CACHE=/home/user/.cache/huggingface/transformers \ | |
| HF_HUB_DISABLE_XET=1 \ | |
| DISPLAY=:99 \ | |
| LIBGL_ALWAYS_SOFTWARE=1 | |
| WORKDIR $HOME/app | |
| # 复制项目文件 | |
| COPY --chown=user . $HOME/app | |
| # 验证 ImportLDraw 插件,若不存在则下载 | |
| RUN if [ ! -d "$HOME/app/code/ImportLDraw" ] || [ ! -f "$HOME/app/code/ImportLDraw/__init__.py" ]; then \ | |
| echo "⚠️ ImportLDraw not found in repo, downloading..."; \ | |
| wget -q https://github.com/TobyLobster/ImportLDraw/archive/refs/tags/v1.2.1.zip -O /tmp/importldraw.zip && \ | |
| unzip -q /tmp/importldraw.zip -d /tmp/ && \ | |
| mv /tmp/ImportLDraw-1.2.1 $HOME/app/code/ImportLDraw && \ | |
| rm /tmp/importldraw.zip && \ | |
| echo "✅ ImportLDraw downloaded successfully"; \ | |
| else \ | |
| echo "✅ ImportLDraw found in repo"; \ | |
| fi | |
| # 验证插件已正确部署 | |
| RUN ls -la $HOME/app/code/ImportLDraw/__init__.py || \ | |
| (echo "❌ ImportLDraw deployment failed" && exit 1) | |
| # 安装 Python 依赖 | |
| RUN pip install --no-cache-dir --upgrade pip && \ | |
| pip install --no-cache-dir -r requirements.txt | |
| # 注意:模型通过 README.md 的 preload_from_hub 自动下载(HF Spaces 官方推荐方式) | |
| # 下载到 ~/.cache/huggingface/hub/ 并在运行时通过 HF_HUB_CACHE 环境变量访问 | |
| # 创建启动脚本(先启动 Xvfb,再运行应用) | |
| RUN echo '#!/bin/bash\n\ | |
| echo "🖥️ 启动虚拟显示服务器 Xvfb..."\n\ | |
| Xvfb :99 -screen 0 1024x768x24 -ac +extension GLX +extension RENDER +render -noreset -nolisten tcp -nolisten unix &\n\ | |
| sleep 2\n\ | |
| echo "✅ Xvfb 已启动 (DISPLAY=:99, 无 Unix socket)"\n\ | |
| echo "🚀 启动应用..."\n\ | |
| exec python code/demo.py' > /home/user/start.sh && \ | |
| chmod +x /home/user/start.sh | |
| # 暴露端口(Gradio 默认) | |
| EXPOSE 7860 | |
| # 启动命令(使用启动脚本) | |
| CMD ["/home/user/start.sh"] | |