Architecture & Deployment

Discoverant Internal Documentation

Architecture Overview

                        ┌─────────────────────────┐
                        │      INTERNET            │
                        │   app.discoverant.com    │
                        └────────────┬────────────┘
                                     │ :443 TLS
                        ┌────────────▼────────────┐
                        │     Nginx  (Gateway)     │
                        │     adroit-nginx :80     │
                        └──┬─────────────────┬────┘
                           │                 │
                   /app/*  │                 │  /api/*
                           │                 │
              ┌────────────▼──┐    ┌────────▼──────────┐
              │   Frontend    │    │     Backend        │
              │   React/TS    │    │   FastAPI/Python   │
              │   :3100       │    │   :8000            │
              └───────────────┘    └──┬──────────┬─────┘
                                     │          │
                          ┌──────────▼──┐  ┌───▼───────┐
                          │  PgBouncer  │  │   Redis    │
                          │  :6432      │  │   :6379    │
                          └──────┬──────┘  └───────────┘
                                 │
                       ┌─────────▼──────────┐
                       │    PostgreSQL 16    │
                       │    + Bingo Cart.    │
                       │    :5432            │
                       │                    │
                       │  88 GB / 174M rows │
                       └────────────────────┘

Docker Containers

Container Image Port Role
adroit-nginx nginx:alpine :80 / :443 Reverse proxy, TLS termination, static assets, routing
adroit-frontend node:18 + nginx :3100 React SPA — chemistry UI, importers, dashboards
adroit-backend python:3.11 :8000 FastAPI application server — REST API, Indigo, RDKit
adroit-postgres postgres:16 + bingo :5432 Primary datastore — chemistry databases, Bingo cartridge
adroit-redis redis:alpine :6379 Session cache, task queue, temporary result storage
pgbouncer pgbouncer :6432 Connection pooling for PostgreSQL

Nginx Routing Rules

The gateway nginx instance handles all inbound traffic for app.discoverant.com:

Path Pattern Upstream Notes
/, /app/* frontend :3100 React SPA, client-side routing
/api/* backend :8000 All REST API endpoints
/api/docs backend :8000 Swagger/OpenAPI interactive docs
/ws/* backend :8000 WebSocket upgrade for live tasks

Proxy Configuration

resolver 127.0.0.11;          # Docker embedded DNS
set $backend http://backend:8000;  # Variable to avoid stale DNS caching
set $frontend http://frontend:3100;

location /api/ {
    proxy_pass $backend;       # No trailing URI — preserves original path
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

Important: The $backend variable approach with resolver directive prevents nginx from caching DNS at startup. Do NOT use literal hostnames or 172.17.0.1 (wrong Docker network).

Port Map

Port Service Exposure Description
:80 Nginx Public HTTP (redirects to :443)
:443 Nginx Public HTTPS — TLS termination
:3100 Frontend Internal React dev / nginx serving built assets
:8000 Backend Internal FastAPI (Uvicorn, WatchFiles reload)
:5432 PostgreSQL Internal Database (with Bingo cartridge)
:6432 PgBouncer Internal Connection pooler for PostgreSQL
:6379 Redis Internal Cache and task queue

Data Layer

PostgreSQL 16 + Bingo Cartridge

Primary datastore hosting 88 GB across 174M+ rows. The EPAM Bingo cartridge provides chemical-aware indexing for substructure and similarity search directly in SQL.

Redis

PgBouncer

Security Model

Authentication Flow

  1. User logs in via /api/v1/auth/login
  2. Backend validates credentials against local database
  3. JWT issued (HS256, signed with app secret)
  4. Frontend stores token in localStorage, sends as Authorization: Bearer
  5. Every API endpoint validates token via get_current_user dependency

Tenant Isolation

Filesystem Isolation

Deployment Process

Frontend

# Build and deploy (requires rebuild for changes)
docker compose build frontend
docker compose up -d frontend

Backend

The backend uses Uvicorn with WatchFiles — code changes are automatically detected and reloaded. No rebuild required for Python changes.

# Only needed for dependency changes
docker compose build backend
docker compose up -d backend

Database Migrations

# Copy SQL into container, then execute
docker cp migration.sql adroit-postgres:/tmp/
docker exec -i adroit-postgres psql -U adroit_user -d adroit_chemistry -f /tmp/migration.sql

Server Specification

Component Specification
ModelDell OptiPlex 7060
CPUIntel Core i7-8700 (6C/12T, 3.2 GHz base / 4.6 GHz turbo)
RAM32 GB DDR4
Storage2 TB SSD
OSUbuntu Linux
DockerDocker Compose (6 containers)