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"]