# ============================================================================= # GenerAI + World Monitor — Consolidated single-container image (HF Space) # ============================================================================= # GenerAI (Python/FastAPI) and World Monitor (Node/nginx/Redis, AGPL-3.0, # https://github.com/koala73/worldmonitor) run side by side under supervisord. # nginx on :7860 is the single entrypoint HF Spaces expects: # /worldmonitor/* -> World Monitor's own internal nginx (:8080, unmodified) # everything else -> GenerAI's uvicorn (:8000) # ============================================================================= # ── Stage 1: World Monitor frontend/API builder ───────────────────────────── FROM node:24-bookworm-slim AS wm-builder WORKDIR /wm COPY worldmonitor/package.json worldmonitor/package-lock.json ./ RUN npm ci --ignore-scripts COPY worldmonitor/ . RUN node docker/build-handlers.mjs RUN npm run build:crawlable-corpus && npm run build:sitemap && npx tsc && npx vite build --base=/worldmonitor/ # ── Stage 2: World Monitor runtime deps (unbundled raw JS handlers) ───────── FROM node:24-bookworm-slim AS wm-runtime-deps WORKDIR /wm COPY worldmonitor/docker/runtime-package.json ./package.json COPY worldmonitor/docker/runtime-package-lock.json ./package-lock.json RUN npm ci --omit=dev --omit=optional --ignore-scripts # ── Stage 3: Redis REST proxy (Upstash-compatible, for World Monitor) ─────── FROM node:24-bookworm-slim AS redisrest-builder WORKDIR /redisrest RUN npm init -y && npm install redis@4 COPY worldmonitor/docker/redis-rest-proxy.mjs . # ── Stage 4: Final image ───────────────────────────────────────────────────── FROM python:3.11-slim AS final RUN apt-get update && apt-get install -y --no-install-recommends \ curl gnupg ca-certificates gettext nginx supervisor redis-server wget \ build-essential \ 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 libx11-6 libxext6 fonts-liberation \ && curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \ && apt-get install -y --no-install-recommends nodejs \ && rm -rf /var/lib/apt/lists/* # ── GenerAI (Python) ────────────────────────────────────────────────────────── WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt RUN python -m playwright install --with-deps chromium COPY app.py brain.py scraper.py crawler.py auth.py mega_sync.py knowledge_base.py \ errors.py worldmonitor_client.py logo.png LICENSE ./ RUN mkdir -p /app/database && chmod -R 777 /app # ── World Monitor (Node) ────────────────────────────────────────────────────── WORKDIR /wm COPY --from=wm-builder /wm/src-tauri/sidecar/local-api-server.mjs ./local-api-server.mjs COPY --from=wm-builder /wm/src-tauri/sidecar/package.json ./package.json COPY --from=wm-runtime-deps /wm/node_modules ./node_modules COPY --from=wm-builder /wm/api ./api COPY --from=wm-builder /wm/data ./data COPY --from=wm-builder /wm/dist /usr/share/nginx/html COPY --from=redisrest-builder /redisrest /redisrest # Full builder tree (incl. complete node_modules) — needed to run World # Monitor's data seed scripts (scripts/seed-*.mjs), which aren't part of the # slim runtime dependency set used by local-api-server.mjs above. COPY --from=wm-builder /wm /wm-seed # ── Supervisord / nginx / entrypoint (combined) ────────────────────────────── COPY worldmonitor/docker/nginx.conf /etc/nginx/wm-internal.conf.template COPY docker-combined/nginx-outer.conf.template /etc/nginx/wm-outer.conf.template COPY docker-combined/supervisord.conf /etc/supervisor/conf.d/combined.conf COPY docker-combined/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh && \ mkdir -p /tmp/nginx-client-body /tmp/nginx-proxy /tmp/nginx-fastcgi \ /tmp/nginx-uwsgi /tmp/nginx-scgi /var/log/supervisor && \ chmod -R 777 /tmp /var/log/supervisor /var/lib/nginx /var/log/nginx /wm /wm-seed WORKDIR /app EXPOSE 7860 ENV PYTHONUNBUFFERED=1 CMD ["/entrypoint.sh"]