Objective
Make builds reproducible and local development one-command. Today there is no Dockerfile or docker-compose anywhere in the repo — Render builds implicitly from source, and every contributor assembles Python + Postgres + env vars by hand.
Current state
- No
Dockerfile, no docker-compose.yml, no .dockerignore
startup.sh runs the background worker as a subshell inside the same container as Gunicorn
- A single
requirements.txt mixes runtime, AI, and test dependencies — chromadb + sentence-transformers pull PyTorch (~2 GB) into the API image, inflating cold starts and memory on Render free tier
Scope
Out of scope
Acceptance criteria
Category
Infrastructure
Objective
Make builds reproducible and local development one-command. Today there is no Dockerfile or docker-compose anywhere in the repo — Render builds implicitly from source, and every contributor assembles Python + Postgres + env vars by hand.
Current state
Dockerfile, nodocker-compose.yml, no.dockerignorestartup.shruns the background worker as a subshell inside the same container as Gunicornrequirements.txtmixes runtime, AI, and test dependencies —chromadb+sentence-transformerspull PyTorch (~2 GB) into the API image, inflating cold starts and memory on Render free tierScope
Dockerfile(python:3.11-slim) building the API imagepython -m scanner.worker)docker-compose.yml:postgres:16+api+worker, with healthchecks and a.env.examplerequirements/base.txt,ai.txt(chromadb, sentence-transformers),dev.txt(pytest) — AI deps become optional for the API image.dockerignore(frontend/, website/, tests/, pycache, .env)docker compose upOut of scope
Acceptance criteria
docker compose upgives a working API on :5000 with migrations applied and worker pollingCategory
Infrastructure