FROM node:24-slim # git is needed for HF Dataset DB sync RUN apt-get update && apt-get install -y git poppler-utils \ && rm -rf /var/lib/apt/lists/* # Install pnpm RUN npm install -g pnpm@10 WORKDIR /app # ── Copy workspace manifests first (layer-cache friendly) ────────────────── COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./ COPY artifacts/api-server/package.json ./artifacts/api-server/ COPY artifacts/raqim/package.json ./artifacts/raqim/ COPY lib/db/package.json ./lib/db/ COPY lib/api-client-react/package.json ./lib/api-client-react/ COPY lib/api-spec/package.json ./lib/api-spec/ COPY lib/api-zod/package.json ./lib/api-zod/ COPY lib/integrations-openai-ai-server/package.json ./lib/integrations-openai-ai-server/ COPY lib/integrations-openai-ai-react/package.json ./lib/integrations-openai-ai-react/ COPY scripts/package.json ./scripts/ # ── Install all dependencies ─────────────────────────────────────────────── RUN pnpm install --frozen-lockfile # ── Copy full source ─────────────────────────────────────────────────────── COPY . . # ── Build frontend (BASE_PATH=/ for single-origin serving) ──────────────── RUN BASE_PATH=/ PORT=3000 NODE_ENV=production \ pnpm --filter @workspace/raqim run build # ── Build backend ────────────────────────────────────────────────────────── RUN pnpm --filter @workspace/api-server run build # ── Persistent data dirs ─────────────────────────────────────────────────── # /data is the HF Spaces persistent volume; /data/uploads stays across restarts. # /tmp/uploads is NOT used in production — /data/uploads is used instead. RUN mkdir -p /data /data/uploads # ── Git identity for HF Dataset sync ────────────────────────────────────── RUN git config --global user.email "sync@raqim.app" && \ git config --global user.name "RAQIM Sync" # ── Runtime config ──────────────────────────────────────────────────────── ENV PORT=7860 ENV NODE_ENV=production ENV FRONTEND_DIST=/app/artifacts/raqim/dist/public ENV DB_PATH=/data/raqim.db ENV MIGRATIONS_DIR=/app/lib/db/drizzle EXPOSE 7860 # Startup sequence: # 1. Pull DB backup from HF Dataset ONLY if /data/raqim.db is absent (first boot) # 2. Seed admin user (skips if already exists) # 3. Background loop pushes DB every 60 s (was 10 min) to minimise data loss # 4. Run server as PID 1 via exec (exit code propagates to container) # 5. On exit, push DB one final time CMD ["sh", "-c", "\ mkdir -p /data/uploads /data/tessdata ; \ node /app/scripts/db-hf-sync.mjs pull || true ; \ node /app/scripts/seed-admin.mjs || true ; \ trap 'node /app/scripts/db-hf-sync.mjs push || true' EXIT ; \ (while true; do sleep 60 && node /app/scripts/db-hf-sync.mjs push || true; done) & \ exec node --enable-source-maps /app/artifacts/api-server/dist/index.mjs \ "]