Files
rengine/api/Dockerfile
T
Yogesh OjhaandClaude Opus 5 e38ec4acc6 feat(toolbox): one-off lookups behind the wrench in the top bar
reNgine 2 had a Tools section; 3.0 lost it, so a hunter left the product
for a whois or a dns lookup even though every capability was already here
inside a scan.

`toolbox/` is a top-level package mounted into api and worker, and a tool
is one file under `toolbox/tools/` — auto-discovered exactly like stages,
report sections and MCP tools, with a pydantic `Input` whose flattened
schema IS the form the UI renders. Six ship: WHOIS, DNS records, subdomain
finder, HTTP probe, IP address and CVE.

Where a tool runs is a declaration the registry enforces. The api image
carries no tool binaries, so `INLINE` answers from RDAP, the offline range
tables or the threat feeds on the request's AsyncSession, and `QUEUED`
shells out on the worker; `_validate` rejects a class whose `run` is async
or sync the wrong way round, so the two cannot drift.

A run is a question rather than inventory, so it lives in Redis with a
seven-day TTL and no migration, keyed by user id. A queued run nobody
collects fails after two minutes instead of spinning for ever.

A tool answers in blocks — facts, table, tags, code, note — so one
frontend renderer serves every tool and a new one costs no frontend work.
An empty block with nothing to say about being empty is dropped.
`require_public` refuses loopback, private and link-local before the HTTP
probe sends anything, because an authenticated user typing 169.254.169.254
is an SSRF.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CtRcxFCPSYxW5sXam3SUWB
2026-09-09 12:02:59 +05:30

50 lines
1.2 KiB
Docker

FROM python:3.13-slim as base
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PYTHONPATH=/app
WORKDIR /app
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
##################################################################
# Development
##################################################################
FROM base AS development
# Copy shared directory inside the app
COPY shared /app/shared
COPY tools /app/tools
COPY stages /app/stages
COPY reports /app/reports
COPY interest /app/interest
COPY mcp /app/mcp
COPY connectors /app/connectors
COPY toolbox /app/toolbox
COPY api/pyproject.toml api/uv.lock* ./
RUN uv sync --no-install-project
# Expose port
EXPOSE 8000
CMD ["uv", "run", "uvicorn", "app.main:app", \
"--host", "0.0.0.0", \
"--port", "8000", \
"--reload", \
"--reload-dir", "/app/app", \
"--reload-dir", "/app/shared", \
"--reload-dir", "/app/tools", \
"--reload-dir", "/app/stages", \
"--reload-dir", "/app/reports", \
"--reload-dir", "/app/toolbox", \
"--timeout-graceful-shutdown", "2"]
##################################################################
# TODO: Production
##################################################################