Spaces:
Running
Running
| FROM oven/bun:1-slim | |
| ARG DEBIAN_FRONTEND=noninteractive | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| git ca-certificates curl sqlite3 rsync python3 \ | |
| && rm -rf /var/lib/apt/lists/* | |
| WORKDIR /app | |
| ARG LUMIVERSE_REPO=https://github.com/prolix-oc/Lumiverse.git | |
| ARG LUMIVERSE_REF=staging | |
| RUN git clone --branch "${LUMIVERSE_REF}" "${LUMIVERSE_REPO}" . \ | |
| && git remote set-head origin -a | |
| # Bake branch + commit into the image so runtime Git reads aren't needed | |
| RUN echo "LUMIVERSE_BRANCH=$(git rev-parse --abbrev-ref HEAD)" >> /app/.build-env \ | |
| && echo "LUMIVERSE_COMMIT=$(git rev-parse HEAD)" >> /app/.build-env \ | |
| && cat /app/.build-env | |
| # Patch BetterAuth for HF reverse proxy | |
| RUN sed -i \ | |
| 's/const host = c\.req\.header("host");/const host = c.req.header("x-forwarded-host") || c.req.header("host");\n const proto = c.req.header("x-forwarded-proto") || "http";/' \ | |
| src/app.ts \ | |
| && sed -i \ | |
| 's|new URL(url\.pathname + url\.search, `http://\${host}`)|new URL(url.pathname + url.search, `${proto}://${host}`)|' \ | |
| src/app.ts \ | |
| && grep -n "x-forwarded-proto" src/app.ts >/dev/null | |
| # Append the /api/hf-update endpoint to the Hono app | |
| RUN cat >> /app/src/app.ts <<'PATCH' | |
| // HF Spaces self-update endpoint | |
| if (process.env.HF_TOKEN && process.env.HF_SPACE) { | |
| app.get("/api/hf-update", async (c) => { | |
| const secret = c.req.query("secret"); | |
| if (process.env.UPDATE_SECRET && secret !== process.env.UPDATE_SECRET) { | |
| return c.json({ error: "Unauthorized" }, 401); | |
| } | |
| try { | |
| const res = await fetch( | |
| `https://huggingface.co/api/spaces/${process.env.HF_SPACE}/restart?factory=true`, | |
| { | |
| method: "POST", | |
| headers: { Authorization: `Bearer ${process.env.HF_TOKEN}` } | |
| } | |
| ); | |
| const body = await res.json(); | |
| return c.json({ | |
| ok: res.ok, | |
| message: res.ok | |
| ? "Rebuild triggered — Space will restart in ~3-5 min" | |
| : "HF API error", | |
| detail: body | |
| }, res.ok ? 200 : 502); | |
| } catch (err) { | |
| return c.json({ error: String(err) }, 500); | |
| } | |
| }); | |
| } | |
| PATCH | |
| RUN rm -f package-lock.json && bun install --production | |
| WORKDIR /app/frontend | |
| RUN rm -f package-lock.json && bun install && bun run build | |
| RUN printf "self.addEventListener('install',e=>self.skipWaiting());self.addEventListener('activate',e=>e.waitUntil(self.clients.claim()));\n" > /app/frontend/dist/sw.js | |
| RUN test -f /app/frontend/dist/index.html | |
| WORKDIR /app | |
| ENV NODE_ENV=production | |
| ENV PORT=7860 | |
| ENV DATA_DIR=/app/data | |
| ENV FRONTEND_DIR=/app/frontend/dist | |
| ENV TRUST_ANY_ORIGIN=true | |
| RUN cat > /app/start.sh <<'SH' | |
| #!/usr/bin/env sh | |
| set -eu | |
| export DATA_DIR="${DATA_DIR:-/app/data}" | |
| # Source baked-in build identity so runner sees branch/commit without needing git | |
| if [ -f /app/.build-env ]; then | |
| . /app/.build-env | |
| export LUMIVERSE_BRANCH LUMIVERSE_COMMIT | |
| fi | |
| exec bun run scripts/runner.ts | |
| SH | |
| RUN chmod +x /app/start.sh | |
| USER root | |
| RUN mkdir -p /app/data && chown -R bun:bun /app/data | |
| EXPOSE 7860 | |
| VOLUME /app/data | |
| USER bun | |
| CMD ["/app/start.sh"] |