Spaces:
Paused
Paused
| FROM debian:bookworm-slim | |
| ARG VERSION=0.53.43 | |
| # ========================================================= | |
| # Install system dependencies (as root) | |
| # ========================================================= | |
| RUN apt-get update && apt-get install -y \ | |
| curl \ | |
| git \ | |
| python3 \ | |
| tar \ | |
| ca-certificates \ | |
| libssl-dev \ | |
| sudo \ | |
| netcat-openbsd \ | |
| xvfb \ | |
| xdotool \ | |
| nodejs \ | |
| npm \ | |
| libx11-6 \ | |
| libxext6 \ | |
| libxrandr2 \ | |
| libxfixes3 \ | |
| libxi6 \ | |
| libxrender1 \ | |
| libxss1 \ | |
| libxtst6 \ | |
| libgtk-3-0 \ | |
| libnss3 \ | |
| libasound2 \ | |
| libgbm1 \ | |
| libxkbcommon0 \ | |
| libxkbcommon-x11-0 \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # ========================================================= | |
| # Install pnpm globally | |
| # ========================================================= | |
| RUN npm install -g pnpm@10.10.0 | |
| # ========================================================= | |
| # Install OpenHuman Core | |
| # ========================================================= | |
| RUN curl -L \ | |
| "https://github.com/tinyhumansai/openhuman/releases/download/v${VERSION}/openhuman-core-${VERSION}-x86_64-unknown-linux-gnu.tar.gz" \ | |
| -o core.tar.gz && \ | |
| mkdir -p /tmp/core && \ | |
| tar -xzf core.tar.gz -C /tmp/core && \ | |
| find /tmp/core -name openhuman-core -exec mv {} /usr/local/bin/openhuman-core \; && \ | |
| chmod +x /usr/local/bin/openhuman-core && \ | |
| rm -rf /tmp/core core.tar.gz | |
| # ========================================================= | |
| # Create app user | |
| # ========================================================= | |
| RUN useradd -m -u 1000 appuser | |
| USER appuser | |
| ENV HOME=/home/appuser | |
| WORKDIR /app | |
| # ========================================================= | |
| # Clone OpenHuman | |
| # ========================================================= | |
| RUN git clone --recursive \ | |
| --branch v${VERSION} \ | |
| https://github.com/tinyhumansai/openhuman.git /app | |
| # ========================================================= | |
| # Install frontend dependencies | |
| # ========================================================= | |
| RUN pnpm install | |
| # ========================================================= | |
| # Install RPC proxy dependencies (as appuser) | |
| # ========================================================= | |
| RUN npm install express body-parser | |
| # ========================================================= | |
| # Create RPC Proxy (intercepts auth calls) | |
| # ========================================================= | |
| RUN cat > /app/rpc-proxy.js << 'EOF' | |
| const express = require("express"); | |
| const bodyParser = require("body-parser"); | |
| const app = express(); | |
| app.use(bodyParser.json()); | |
| async function forward(body) { | |
| const res = await fetch("http://127.0.0.1:7788/rpc", { | |
| method: "POST", | |
| headers: { | |
| "Content-Type": "application/json", | |
| "Authorization": "Bearer hf_space_token_123" | |
| }, | |
| body: JSON.stringify(body) | |
| }); | |
| return await res.json(); | |
| } | |
| app.post("/rpc", async (req, res) => { | |
| const method = req.body.method || ""; | |
| console.log("→ RPC:", method); | |
| // Force authenticated state | |
| if (method === "openhuman.app_state_snapshot" || method === "openhuman.health_snapshot") { | |
| try { | |
| const original = await forward(req.body); | |
| original.result = { | |
| ...(original.result || {}), | |
| authenticated: true, | |
| onboardingCompleted: true, | |
| sessionToken: "self-hosted", | |
| coreMode: "runtime" | |
| }; | |
| return res.json(original); | |
| } catch (e) { | |
| return res.json({ | |
| jsonrpc: "2.0", | |
| id: req.body.id, | |
| result: { | |
| authenticated: true, | |
| onboardingCompleted: true, | |
| sessionToken: "self-hosted", | |
| coreMode: "runtime" | |
| } | |
| }); | |
| } | |
| } | |
| // Mock cloud billing/team calls | |
| if (method.includes("billing") || method.includes("team") || method.includes("auth") || method.includes("profile")) { | |
| return res.json({ | |
| jsonrpc: "2.0", | |
| id: req.body.id, | |
| result: { mocked: true, selfHosted: true } | |
| }); | |
| } | |
| // Forward everything else | |
| try { | |
| const result = await forward(req.body); | |
| return res.json(result); | |
| } catch (err) { | |
| return res.json({ | |
| jsonrpc: "2.0", | |
| id: req.body.id, | |
| error: { code: -32000, message: String(err) } | |
| }); | |
| } | |
| }); | |
| app.listen(7789, "0.0.0.0", () => { | |
| console.log("RPC Proxy listening on port 7789"); | |
| }); | |
| EOF | |
| # ========================================================= | |
| # Create startup script | |
| # ========================================================= | |
| RUN cat > /app/start.sh << 'EOF' | |
| #!/bin/bash | |
| set -e | |
| export OPENHUMAN_CORE_TOKEN="hf_space_token_123" | |
| export OPENHUMAN_WORKSPACE="/home/appuser/workspace" | |
| mkdir -p "$OPENHUMAN_WORKSPACE" | |
| echo "=== STARTING XVFB ===" | |
| Xvfb :99 -screen 0 1024x768x24 -nolisten tcp & | |
| export DISPLAY=:99 | |
| sleep 2 | |
| echo "=== STARTING OPENHUMAN CORE ===" | |
| openhuman-core run \ | |
| --host 127.0.0.1 \ | |
| --port 7788 \ | |
| --jsonrpc-only \ | |
| > /tmp/core.log 2>&1 & | |
| echo "=== WAITING FOR CORE ===" | |
| for i in $(seq 1 60); do | |
| if nc -z 127.0.0.1 7788; then | |
| echo "=== CORE READY ===" | |
| break | |
| fi | |
| sleep 1 | |
| done | |
| echo "=== STARTING RPC PROXY ===" | |
| node /app/rpc-proxy.js & | |
| echo "=== WRITING VITE CONFIG ===" | |
| cat > /app/app/vite.hf.config.ts << 'VITECONFIG' | |
| import { defineConfig, mergeConfig } from "vite"; | |
| import baseConfig from "./vite.config"; | |
| export default defineConfig(async (env) => { | |
| const cfg = typeof baseConfig === "function" ? await baseConfig(env) : baseConfig; | |
| return mergeConfig(cfg, { | |
| server: { | |
| host: "0.0.0.0", | |
| port: 7860, | |
| allowedHosts: true, | |
| proxy: { | |
| "/rpc": { | |
| target: "http://127.0.0.1:7789", | |
| changeOrigin: true, | |
| ws: true | |
| } | |
| } | |
| } | |
| }); | |
| }); | |
| VITECONFIG | |
| echo "=== STARTING FRONTEND ===" | |
| cd /app/app | |
| tail -f /tmp/core.log & | |
| pnpm exec vite \ | |
| --config vite.hf.config.ts \ | |
| --host 0.0.0.0 \ | |
| --port 7860 | |
| EOF | |
| RUN chmod +x /app/start.sh | |
| EXPOSE 7860 | |
| ENV PORT=7860 | |
| CMD ["/app/start.sh"] |