Spaces:
Sleeping
Sleeping
| # Hugging Face Spaces - MrrrMe with Coqui XTTS v2 + MODULAR BACKEND | |
| # FIXED v2.4: Proper permissions and cache setup for user 1000 | |
| FROM nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu22.04 | |
| # Install system dependencies | |
| RUN apt-get update && apt-get install -y \ | |
| bash \ | |
| git \ | |
| git-lfs \ | |
| wget \ | |
| curl \ | |
| procps \ | |
| python3.11 \ | |
| python3-pip \ | |
| python3.11-dev \ | |
| libgl1-mesa-glx \ | |
| libglib2.0-0 \ | |
| ffmpeg \ | |
| portaudio19-dev \ | |
| libsndfile1 \ | |
| espeak-ng \ | |
| nginx \ | |
| gnupg \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # Install Node.js 20 | |
| RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \ | |
| apt-get install -y nodejs && \ | |
| rm -rf /var/lib/apt/lists/* | |
| # Set Python 3.11 as default | |
| RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.11 1 && \ | |
| update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1 | |
| WORKDIR /app | |
| # ============================================================ | |
| # CRITICAL: Create cache directories with correct ownership EARLY | |
| # ============================================================ | |
| RUN mkdir -p /data/modelscope /data/huggingface /home/user/.cache && \ | |
| chown -R 1000:1000 /data /home/user | |
| # ============================================================ | |
| # PERSISTENT STORAGE - Set as root user (before USER 1000 switch) | |
| # ============================================================ | |
| ENV MODELSCOPE_CACHE=/data/modelscope | |
| ENV MS_CACHE_HOME=/data/modelscope | |
| ENV HF_HOME=/data/huggingface | |
| ENV FUNASR_CACHE=/data/modelscope | |
| # Install PyTorch with CUDA 11.8 | |
| RUN python3.11 -m pip install --no-cache-dir \ | |
| torch==2.4.0 \ | |
| torchvision==0.19.0 \ | |
| torchaudio==2.4.0 \ | |
| --index-url https://download.pytorch.org/whl/cu118 | |
| ENV COQUI_TOS_AGREED=1 | |
| # Install Python dependencies | |
| COPY requirements_docker.txt ./ | |
| # CRITICAL: Install funasr with --no-deps to avoid gradio hell | |
| RUN python3.11 -m pip install --no-cache-dir -r requirements_docker.txt && \ | |
| python3.11 -m pip install --no-cache-dir funasr>=1.0.0 --no-deps | |
| # ============================================================ | |
| # BAKE MODELS INTO IMAGE (Optimized Build) | |
| # ============================================================ | |
| COPY download_models.py . | |
| RUN python3.11 download_models.py && \ | |
| rm download_models.py | |
| # Install avatar dependencies | |
| RUN python3.11 -m pip install --no-cache-dir \ | |
| fastapi uvicorn python-multipart pydub websockets onnxruntime | |
| # Copy application code | |
| COPY --link --chown=1000:1000 mrrrme/ ./mrrrme/ | |
| COPY --link --chown=1000:1000 model/ ./model/ | |
| COPY --link --chown=1000:1000 avatar/ ./avatar/ | |
| # Create directories | |
| RUN mkdir -p /app/weights /app/avatar/static | |
| # Fix openface bug | |
| RUN python3.11 -c "import os; fp='/usr/local/lib/python3.11/dist-packages/openface/multitask_model.py'; c=open(fp).read() if os.path.exists(fp) else ''; exec(\"if os.path.exists(fp) and 'import cv2' not in c:\\n open(fp,'w').write('import cv2\\\\n'+c)\\n print('Patched')\")" | |
| # Build frontend | |
| COPY avatar-frontend/package*.json ./frontend/ | |
| WORKDIR /app/frontend | |
| RUN npm ci | |
| COPY --link --chown=1000:1000 avatar-frontend/ ./ | |
| RUN npm run build | |
| # Copy static files | |
| RUN cp -r .next/static .next/standalone/.next/ && \ | |
| cp -r public .next/standalone/ 2>/dev/null || true | |
| WORKDIR /app | |
| # Copy nginx config | |
| COPY nginx.spaces.conf /etc/nginx/nginx.conf | |
| # Generate SSL certificates | |
| RUN mkdir -p /etc/nginx/certs && \ | |
| openssl req -x509 -newkey rsa:4096 -nodes \ | |
| -keyout /etc/nginx/certs/key.pem \ | |
| -out /etc/nginx/certs/cert.pem \ | |
| -days 365 \ | |
| -subj "/CN=mrrrme.hf.space" | |
| # ============================================================ | |
| # Startup script with proper environment | |
| # ============================================================ | |
| RUN printf '#!/bin/bash\nset -e\n\n# Set HOME for user 1000\nexport HOME=/home/user\n\n# Agree to TOS\nexport COQUI_TOS_AGREED=1\n\n# ============================================================\n# CACHE DIRECTORIES - Set for runtime user\n# ============================================================\nexport MODELSCOPE_CACHE=/data/modelscope\nexport MS_CACHE_HOME=/data/modelscope\nexport HF_HOME=/data/huggingface\nexport FUNASR_CACHE=/data/modelscope\n\necho "π Model cache: $MODELSCOPE_CACHE"\n\n# Ensure cache directories are writable\nmkdir -p $MODELSCOPE_CACHE $HF_HOME 2>/dev/null || true\n\n# Clean up old processes\npkill -f "backend_new.py" 2>/dev/null || true\npkill -f "speak_server.py" 2>/dev/null || true\npkill -f "node server.js" 2>/dev/null || true\npkill -f "nginx" 2>/dev/null || true\n\nsleep 2\n\necho "π Starting MrrrMe..."\necho "π¦ emotion2vec will load from /data (first run downloads ~2min, then instant)"\n\n# Start services\ncd /app && python3.11 mrrrme/backend_new.py &\ncd /app/avatar && python3.11 speak_server.py &\ncd /app/frontend/.next/standalone && HOSTNAME=0.0.0.0 PORT=3001 node server.js &\n\nsleep 10\nnginx -g "daemon off;" &\n\necho "β All services running!"\nwait\n' > /app/start.sh && chmod +x /app/start.sh | |
| # ============================================================ | |
| # FINAL: Set ownership of everything to user 1000 | |
| # ============================================================ | |
| RUN chown -R 1000:1000 /app /data /home/user | |
| USER 1000 | |
| ENV HOME=/home/user | |
| # Re-export cache variables for user 1000 | |
| ENV MODELSCOPE_CACHE=/data/modelscope | |
| ENV MS_CACHE_HOME=/data/modelscope | |
| ENV HF_HOME=/data/huggingface | |
| ENV FUNASR_CACHE=/data/modelscope | |
| EXPOSE 7860 | |
| CMD ["/app/start.sh"] |