Spaces:
Sleeping
Sleeping
| FROM python:3.11-slim | |
| # Switch to root to install ALL system dependencies including Playwright browser libs | |
| USER root | |
| RUN apt-get update && apt-get install -y \ | |
| ffmpeg \ | |
| espeak-ng \ | |
| portaudio19-dev \ | |
| python3-dev \ | |
| build-essential \ | |
| # ββ Playwright / Chromium system dependencies ββββββββββββββββββββββββββββββ | |
| libnss3 \ | |
| libnspr4 \ | |
| libatk1.0-0 \ | |
| libatk-bridge2.0-0 \ | |
| libcups2 \ | |
| libdrm2 \ | |
| libdbus-1-3 \ | |
| libxkbcommon0 \ | |
| libxcomposite1 \ | |
| libxdamage1 \ | |
| libxfixes3 \ | |
| libxrandr2 \ | |
| libgbm1 \ | |
| libasound2 \ | |
| libpango-1.0-0 \ | |
| libcairo2 \ | |
| libatspi2.0-0 \ | |
| libwayland-client0 \ | |
| wget \ | |
| ca-certificates \ | |
| # ββ S4: headless Blender runtime links (no X server needed in --background) β | |
| curl \ | |
| xz-utils \ | |
| libgl1 \ | |
| libegl1 \ | |
| libx11-6 \ | |
| libxi6 \ | |
| libxxf86vm1 \ | |
| libxrender1 \ | |
| libgomp1 \ | |
| libsm6 \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # ββ S4: Blender 4.5 LTS headless (official Linux x64 tarball, URL verified 2026-07-17). | |
| # Geometry processing + GLB export only β no rendering β CPU hardware is sufficient. | |
| ARG BLENDER_VERSION=4.5.3 | |
| # BLENDER IS OPTIONAL AND MUST NOT BE ABLE TO TAKE THE BACKEND DOWN. | |
| # | |
| # This step used to be fatal. On 2026-08-08 download.blender.org began answering | |
| # HuggingFace's build IPs with 403 β the file is still published (verified 200 | |
| # with the same URL and the same curl User-Agent from a normal network), so this | |
| # is the CDN refusing the builder, not a bad version pin. The whole Space failed | |
| # to build and the API, the assistant and the PC relay all went offline because a | |
| # 377 MB download for the 3D geometry pipeline was refused by a third party. | |
| # | |
| # The core backend does not need Blender; only the model/GLB pipeline does. So | |
| # the download is now best-effort with a mirror fallback and a soft exit, and | |
| # blender_available() at runtime decides whether that one feature is offered. | |
| # An optional dependency of one subsystem should degrade that subsystem, never | |
| # the server. | |
| RUN mkdir -p /opt/blender && \ | |
| ( curl -fsSL --retry 3 --retry-delay 2 \ | |
| -A "Mozilla/5.0 (X11; Linux x86_64) omega-build" \ | |
| "https://download.blender.org/release/Blender4.5/blender-${BLENDER_VERSION}-linux-x64.tar.xz" \ | |
| -o /tmp/blender.tar.xz \ | |
| || curl -fsSL --retry 2 --retry-delay 2 \ | |
| -A "Mozilla/5.0 (X11; Linux x86_64) omega-build" \ | |
| "https://mirrors.ocf.berkeley.edu/blender/release/Blender4.5/blender-${BLENDER_VERSION}-linux-x64.tar.xz" \ | |
| -o /tmp/blender.tar.xz \ | |
| || echo "BLENDER DOWNLOAD UNAVAILABLE β continuing without it" ) && \ | |
| ( test -s /tmp/blender.tar.xz \ | |
| && tar -xJf /tmp/blender.tar.xz -C /opt/blender --strip-components=1 \ | |
| && rm -f /tmp/blender.tar.xz \ | |
| && /opt/blender/blender --version \ | |
| || echo "Blender not installed; 3D geometry features will report unavailable" ) && \ | |
| true | |
| # Set up a new user named "user" with user ID 1000 | |
| RUN useradd -m -u 1000 user | |
| # Switch to the "user" user | |
| USER user | |
| ENV HOME=/home/user \ | |
| PATH=/home/user/.local/bin:/opt/blender:$PATH \ | |
| CLOUD_ENV=true \ | |
| PLAYWRIGHT_BROWSERS_PATH=/home/user/.playwright \ | |
| BLENDER_PATH=/opt/blender/blender | |
| # Set the working directory to the user's home directory | |
| WORKDIR $HOME/app | |
| # Copy the requirements file and install dependencies | |
| COPY --chown=user backend/requirements.txt $HOME/app/backend/requirements.txt | |
| RUN awk '!/^#/ && NF' backend/requirements.txt | while read -r req; do \ | |
| req=$(echo "$req" | tr -d '\r'); \ | |
| echo "=== INSTALLING: $req ==="; \ | |
| pip install --no-cache-dir --upgrade "$req" || { echo "FAILED ON: $req"; exit 1; }; \ | |
| done | |
| # Install Playwright Chromium browser binaries (for social media automation) | |
| RUN playwright install chromium | |
| # Copy the rest of the backend source code | |
| COPY --chown=user backend/ $HOME/app/backend/ | |
| # Copy required root modules and config | |
| COPY --chown=user modules/ $HOME/app/modules/ | |
| COPY --chown=user config.py $HOME/app/config.py | |
| # S4: AR scene bus (started by backend.main at boot; /scene/ws proxies into it) | |
| COPY --chown=user phone/ $HOME/app/phone/ | |
| # Copy the centralized database. | |
| # | |
| # NOTE: memory.db is not only the credential vault β it also carries `memories`, | |
| # `conversations`, `skills`, the knowledge-graph `nodes`/`edges`, `apscheduler_jobs` | |
| # and `master_vault_ledger`. Removing it drops real user data, not just keys, and | |
| # also breaks this build step. Restored deliberately. | |
| # | |
| # The credentials inside it are additionally present as HF Space Secrets, and | |
| # get_secret() reads the environment first, so the vault is a fallback rather | |
| # than the primary source. | |
| COPY --chown=user memory.db $HOME/app/memory.db | |
| # ββ S4: ship the WebAR client β mobile AR loads straight from the Space at /webar/ | |
| COPY --chown=user webar/ $HOME/app/webar/ | |
| # ββ Part 36: ship the signed Guardian APK so the install path actually resolves. | |
| # backend/routes/distribution_routes.py serves dist/app-release.apk at /distribution/android, | |
| # and the manifest reports its size and SHA-256. Without this COPY the route answers 503 | |
| # "apk_not_staged" no matter what is uploaded to the Space repo, because the file would exist | |
| # in the repo and not in the image the container actually runs. The advertised download URL | |
| # returning 404 was the original defect; this is the line that closes it. | |
| COPY --chown=user dist/ $HOME/app/dist/ | |
| # ββ S4: writable pipeline dirs (container FS is ephemeral; durable copies are pushed | |
| # to the private OMEGA models dataset via huggingface_hub at runtime) | |
| RUN mkdir -p $HOME/app/storage/models3d $HOME/app/storage/forge_templates $HOME/app/storage/chroma_db | |
| # Expose the default port for Hugging Face Spaces | |
| EXPOSE 7860 | |
| # We use the Self-Healing Supervisor to boot the actual server | |
| CMD ["python", "-u", "backend/supervisor.py"] | |
| # S4 rebuild marker 2026-07-17 β Blender pipeline + WebAR serving | |
| # Part 18 (2026-07-22): repo copy reconciled with the deployed Space copy; this file | |
| # is now the single source of truth β deploy_hf_space.py stages it with a content guard. | |