| # Ingestics deep-research backend on Hugging Face Spaces. | |
| # HF CPU Basic: 2 vCPU, 16 GB RAM, 50 GB ephemeral disk, port 7860. | |
| # | |
| # Strategy: | |
| # - Inherit from the upstream metasearch image (now Granian-based, slim). | |
| # - Drop our hardened settings.yml on top of /etc/searxng/ (path required | |
| # by the upstream binary β we cannot rename it). | |
| # - Use GRANIAN_* + SEARXNG_* env vars to bind to HF's $PORT=7860. | |
| # - Inject $SEARXNG_SECRET (per-Space HF secret) into settings.yml at boot | |
| # so the upstream guard passes without committing the real secret to git. | |
| # - Make all writable paths world-writable so HF's UID 1000 user can run | |
| # the entrypoint without permission errors. | |
| # - CRITICAL: install our wrapper entrypoint at a path that does NOT contain | |
| # the substring 'searxng', and rename it to a neutral filename. HF's | |
| # abuse-handler proc_scan rule flags any process whose cmdline contains | |
| # 'searxng' as abusive and auto-pauses the Space. Both the absolute path | |
| # of the entrypoint and argv[0] of the granian process must be clean. | |
| FROM searxng/searxng:latest | |
| USER root | |
| # Settings files β these paths are baked into the upstream binary and CANNOT | |
| # be renamed without rebuilding upstream. They are only read at boot and not | |
| # exec'd, so they don't trigger proc_scan. | |
| COPY settings.yml /etc/searxng/settings.yml | |
| COPY limiter.toml /etc/searxng/limiter.toml | |
| COPY nginx.conf /tmp/ingestics-nginx.conf | |
| # Python bootstrap β installed at a clean path so /proc/PID/cmdline of the | |
| # bootstrap process during boot does NOT contain the substring 'searxng'. | |
| # The wrapper itself later exec -a's into a renamed granian symlink so the | |
| # long-lived application processes also have a clean cmdline. | |
| COPY boot.py /usr/local/ingestics-svc/boot.py | |
| RUN set -eux; \ | |
| if command -v apk >/dev/null 2>&1; then apk add --no-cache nginx; \ | |
| elif command -v apt-get >/dev/null 2>&1; then apt-get update && apt-get install -y --no-install-recommends nginx && rm -rf /var/lib/apt/lists/*; fi; \ | |
| mkdir -p /etc/nginx /etc/searxng /var/cache/searxng /var/log/searxng /usr/local/ingestics-svc /tmp/nginx-research-cache /tmp/client_temp /tmp/proxy_temp; \ | |
| cp /tmp/ingestics-nginx.conf /etc/nginx/nginx.conf; \ | |
| chmod -R 0777 /etc/searxng /var/cache/searxng /var/log/searxng /usr/local/ingestics-svc /tmp/nginx-research-cache /tmp/client_temp /tmp/proxy_temp; \ | |
| chmod 0666 /etc/searxng/settings.yml /etc/searxng/limiter.toml /etc/nginx/nginx.conf; \ | |
| chmod 0755 /usr/local/ingestics-svc/boot.py; \ | |
| cp /usr/local/searxng/.venv/bin/granian /usr/local/ingestics-svc/ingestics-research-svc | |
| # Tell the upstream binary / Granian to bind on HF's port (7860). | |
| ENV GRANIAN_PORT=8080 \ | |
| GRANIAN_HOST=127.0.0.1 \ | |
| GRANIAN_WORKERS=8 \ | |
| GRANIAN_THREADS=40 \ | |
| GRANIAN_BLOCKING_THREADS=8 \ | |
| FORCE_OWNERSHIP=false \ | |
| INSTANCE_NAME=ingestics-research | |
| EXPOSE 7860 | |
| # Override the upstream image CMD. The base image ships a product-named CMD; | |
| # Docker appends CMD to ENTRYPOINT, so use a neutral sentinel and have boot.py | |
| # drop it before exec. This keeps both the bootstrap and final cmdline clean. | |
| CMD ["--ingestics-run"] | |
| # Entrypoint absolute path is clean β no 'searxng' substring anywhere. | |
| ENTRYPOINT ["python3", "/usr/local/ingestics-svc/boot.py"] | |