QANATIX
Deployment

Air-Gapped Deployment

Deploy QANATIX in classified or air-gapped environments with no internet.

Air-Gapped Deployment

QANATIX runs fully offline. No telemetry, no external API calls, no internet required. Designed for classified environments, defence, and regulated industries.

Requirements

  • Docker and Docker Compose v2
  • 8 GB RAM minimum (16 GB recommended)
  • GPU: NVIDIA T4 (16 GB VRAM) or better for embedding at scale
  • All Docker images pre-pulled to an internal registry

Setup

1. Pre-pull images

On a machine with internet access, pull and save all images:

# Pull images
docker pull qanatix/api:latest
docker pull qanatix/worker:latest
docker pull postgres:17
docker pull redis:7-alpine
docker pull qdrant/qdrant:v1.12.0

# Save to tarball
docker save qanatix/api qanatix/worker postgres:17 redis:7-alpine qdrant/qdrant:v1.12.0 \
  | gzip > qanatix-images.tar.gz

2. Pre-download BGE-M3 model

On an internet-connected machine:

from huggingface_hub import snapshot_download
snapshot_download("BAAI/bge-m3", local_dir="./bge-m3-weights")

Transfer the bge-m3-weights/ directory along with the Docker images.

3. Transfer to air-gapped network

Move qanatix-images.tar.gz, bge-m3-weights/, and the docker-compose.yml via approved media (USB, secure transfer).

4. Load images

docker load < qanatix-images.tar.gz

5. Configure for offline operation

# .env
DEPLOYMENT_MODE=self_hosted
EMBEDDING_MODEL=BAAI/bge-m3
EMBEDDING_DIMENSIONS=1024

API_KEY_SALT=your-random-32-char-string
CONNECTOR_ENCRYPTION_KEY=your-fernet-key
CORS_ORIGINS=https://internal.mil.gov

6. Start

docker compose up -d

What works offline

Everything:

  • Data ingestion (all formats)
  • Hybrid search (dense + sparse + ColBERT)
  • Cross-encoder reranking
  • MCP server
  • API authentication and rate limiting
  • Admin and export endpoints
  • Schema validation

What doesn't work offline

  • Stripe billing (disabled in self-hosted mode)
  • EU Cloud features

Security considerations

  • Set CORS_ORIGINS to your specific internal domains
  • Change API_KEY_SALT from the default
  • Set CONNECTOR_ENCRYPTION_KEY for database credential encryption
  • All data stays on your network — no external calls whatsoever
  • Rate limiting still works (Redis is local)

On this page