Skip to content

06. Infra & Local Ops

Local topology

graph TD
  classDef default fill:#1e293b,stroke:#38bdf8,stroke-width:2px,color:#f8fafc
  classDef highlight fill:#065f46,stroke:#34d399,stroke-width:2px,color:#f0fdf4
  classDef warning fill:#78350f,stroke:#fbbf24,stroke-width:2px,color:#fffbeb

  FE["Vite :5173"]:::highlight
  API["Uvicorn :8000"]:::highlight
  W["Celery worker"]:::highlight
  PG["Postgres host :5433"]
  RD["Redis :6379"]
  MN["MinIO :9000 / :9001"]
  MS["Meilisearch"]:::warning
  QD["Qdrant"]:::warning

  FE --> API
  API --> PG
  API --> RD
  API --> MN
  W --> PG
  W --> RD
  W --> MN
  MS -.->|"compose-full only"| W
  QD -.->|"compose-full only"| W

  linkStyle default stroke:#64748b,stroke-width:2px

App processes run on the host via Makefile. Docker Compose provides data stores only (no app Dockerfiles in this checkout).

Compose services

File Services
infra/docker-compose.yml Postgres 17 (5433:5432), Redis 7, MinIO
infra/docker-compose-full.yml Above + Meilisearch + Qdrant

Volumes live under volumes/ (gitignored pattern in project docs).

Common Makefile targets

Typical flow (see root Makefile for exact names):

  • Bring up infra (make up / compose)
  • Start backend, Celery worker, frontend
  • make test, make lint
  • make docs-serve for in-repo MkDocs wiki

Logs are written under logs/ when using Makefile process wrappers.

Environment variables

Primary loader: backend/app/config.py with env_file="../.env".

Concern Settings fields .env.example names
Object store S3_ENDPOINT_URL, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_BUCKET_DOCS MINIO_ENDPOINT, MINIO_ACCESS_KEY, MINIO_SECRET_KEY, MINIO_BUCKET_DOCS
Database DATABASE_URL postgresql+asyncpg://...@localhost:5432/...
Compose Postgres host port 5433 example still 5432

Confirmed drift: copying .env.example alone does not populate S3_* fields the app reads. Host-run API likely needs localhost:5433 in DATABASE_URL.

Other important knobs: OCR_ENGINE, LLM keys/base URL, Sarvam/Paddle URLs, factsheet char limits, JWT_SECRET / OIDC placeholders.

Networking pitfalls

Issue Detail
Vite proxy Targets localhost:8888; Makefile API default 8000
CORS API allows * origins with credentials
Paddle layout OCR Expects external PADDLE_OCR_SERVICE_URL (often separate ocr-service)

Secrets handling

  • .env gitignored; .env.example committed with placeholders
  • No sealed-secrets / vault integration in repo
  • Default JWT_SECRET=change-me unsuitable for any shared environment

Observability

  • Structured-ish request logging via LoggingMiddleware
  • Job/chunk error strings in DB
  • No Prometheus/OpenTelemetry wiring found
  • In-repo MkDocs under docs/ for human ops/onboarding

Infra interview Q&A

Q: What do you Dockerize locally?
A: Postgres, Redis, MinIO (and optionally search). API, worker, and Vite run on the host for faster iteration.

Q: Why is search in compose-full if unused?
A: Forward-looking infra for UC3; keeps the full stack one command away without coupling the current pipeline to those services.