Overview
Full on-premises deployment runs all Navigara components in your infrastructure. Source code, analysis results, and all metadata stay within your network.
Architecture
A full deployment consists of three infrastructure components:
- Linux VM — runs the Navigara application (backend, frontend, collector) via Docker Compose
- Managed PostgreSQL — stores all application data including vector embeddings (requires pgvector extension)
- LLM API endpoint — OpenAI-compatible API for AI-powered commit analysis
Prerequisites
Linux VM
The VM runs all Navigara application containers via Docker Compose.
Operating system: Ubuntu 24.04 LTS or Debian 13+ (other systemd-based Linux distributions may work but are not officially supported)
Required software:
- Docker Engine 24+
- Docker Compose v2+
Managed PostgreSQL
A managed PostgreSQL instance with the pgvector extension enabled. All major cloud providers support this:
- AWS: Amazon RDS for PostgreSQL with pgvector
- GCP: Cloud SQL for PostgreSQL with pgvector
- Azure: Azure Database for PostgreSQL with pgvector
- Self-managed: PostgreSQL 18+ with pgvector extension installed
PostgreSQL version: 18 (required for native UUIDv7 support via uuidv7())
Required extension: pgvector — vector similarity search for knowledge graph analysis
LLM API Endpoint
Navigara requires an OpenAI-compatible API endpoint for AI-powered commit analysis. Supported providers:
| Provider | Model | Notes |
|---|
| Google Vertex AI | Gemini 2.5 Flash | Recommended — best cost/performance ratio |
| Anthropic | Claude Sonnet 4.6 | High quality analysis |
| OpenAI | GPT-5.4 | Widely available |
The endpoint must be reachable from the VM. For air-gapped environments, a locally hosted model with an OpenAI-compatible API (e.g. vLLM, Ollama) can be used — contact support for guidance.
Network Requirements
The VM must have outbound access to the following services. Ensure your firewall rules allow these connections:
| Service | Purpose | Example endpoints |
|---|
| Git provider | Repository cloning and commit fetching | github.com, gitlab.com, or your self-hosted instance |
| Task management | Alignment scoring via issue/task data | api.linear.app, *.atlassian.net, or your self-hosted instance |
| LLM API | AI-powered commit analysis | api.openai.com, api.anthropic.com, or Vertex AI endpoints |
If any of these services are unreachable, the corresponding Navigara features will not function. Git provider access is required for core functionality.
Hardware Requirements
Small (up to 500K commits)
Medium (up to 5M commits)
Large (up to 50M commits)
Suitable for small to mid-size engineering teams.| Component | CPU | Memory | Disk |
|---|
| Linux VM | 8 vCPU | 16 GB | 500 GB SSD |
| PostgreSQL | 8 vCPU | 32 GB | 500 GB SSD |
Suitable for larger organizations with multiple teams and repositories.| Component | CPU | Memory | Disk |
|---|
| Linux VM | 12 vCPU | 24 GB | 1 TB SSD |
| PostgreSQL | 16 vCPU | 64 GB | 1 TB SSD |
Suitable for enterprises with extensive Git history across many repositories.| Component | CPU | Memory | Disk |
|---|
| Linux VM | 24 vCPU | 48 GB | 2 TB SSD |
| PostgreSQL | 32 vCPU | 128 GB | 2 TB SSD |
Disk requirements are primarily driven by knowledge graph data and vector embeddings. SSD storage is required for acceptable query performance.
Installation
1. Prepare the VM
# Install Docker
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# Install Docker Compose plugin (if not included)
sudo apt-get install docker-compose-plugin
# Verify
docker compose version
2. Authenticate with the container registry
Navigara images are hosted on Google Artifact Registry. During onboarding, you will receive a service account key file (navigara-registry-key.json) that grants read access to the container images.
# Install gcloud CLI (if not already installed)
curl https://sdk.cloud.google.com | bash
exec -l $SHELL
# Authenticate with the service account
gcloud auth activate-service-account --key-file=navigara-registry-key.json
# Configure Docker to use gcloud credentials for Artifact Registry
gcloud auth configure-docker europe-west1-docker.pkg.dev --quiet
Verify you can pull images:
docker pull europe-west1-docker.pkg.dev/navigara-images/prod/vision-be:<version>
Replace <version> with the version provided to you during onboarding.
If your organization mirrors images to an internal registry, pull the three Navigara images and push them to your registry, then override the image paths via BACKEND_IMAGE, COLLECTOR_IMAGE, and FRONTEND_IMAGE in your .env file.
Create the deployment directory structure:
mkdir -p /opt/navigara/deployment/caddy && cd /opt/navigara
Create docker-compose.yml:
services:
backend:
image: ${BACKEND_IMAGE:-europe-west1-docker.pkg.dev/navigara-images/prod/vision-be:${NAVIGARA_VERSION}}
container_name: navigara-backend
init: true
env_file:
- .env
environment:
DATABASE_MAX_CONNS: ${DATABASE_MAX_CONNS:-10}
DATABASE_MIN_CONNS: ${DATABASE_MIN_CONNS:-2}
GRPC_PORT: ${GRPC_PORT:-9090}
HTTP_PORT: ${HTTP_PORT:-8080}
LOG_LEVEL: ${LOG_LEVEL:-INFO}
LLM_PROVIDER: ${LLM_PROVIDER:-openai}
LLM_MODEL: ${LLM_MODEL:-gpt-5.4}
LLM_MAX_TOKENS: ${LLM_MAX_TOKENS:-8192}
MIGRATIONS_PATH: ${MIGRATIONS_PATH:-db/migrations}
COLLECTOR_API_KEY: ${COLLECTOR_API_KEY:-navigara-collector-key}
FRONTEND_URL: ${FRONTEND_URL:-http://frontend:3000}
ports:
- "127.0.0.1:8080:8080"
- "127.0.0.1:9090:9090"
restart: unless-stopped
networks:
- navigara-network
collector:
image: ${COLLECTOR_IMAGE:-europe-west1-docker.pkg.dev/navigara-images/prod/vision-collector:${NAVIGARA_VERSION}}
container_name: navigara-collector
init: true
env_file:
- .env
environment:
SERVER_ADDR: backend:9090
COLLECTOR_ID: ${COLLECTOR_ID:-collector-1}
COLLECTOR_API_KEY: ${COLLECTOR_API_KEY:-navigara-collector-key}
MAX_WORKERS: ${COLLECTOR_MAX_WORKERS:-10}
LLM_PROVIDER: ${LLM_PROVIDER:-openai}
LLM_MODEL: ${LLM_MODEL:-gpt-5.4}
WORK_DIR: /tmp/git-analysis
depends_on:
backend:
condition: service_started
restart: unless-stopped
networks:
- navigara-network
frontend:
image: ${FRONTEND_IMAGE:-europe-west1-docker.pkg.dev/navigara-images/prod/vision-fe:${NAVIGARA_VERSION}}
container_name: navigara-frontend
env_file:
- .env
environment:
BACKEND_API_URL: ${BACKEND_API_URL:-http://backend:8080}
NODE_ENV: ${NODE_ENV:-production}
ports:
- "127.0.0.1:3000:3000"
depends_on:
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3000"]
interval: 15s
timeout: 5s
retries: 3
start_period: 15s
networks:
- navigara-network
caddy:
image: caddy:2-alpine
container_name: navigara-caddy
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./deployment/caddy/Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
- frontend
restart: unless-stopped
networks:
- navigara-network
volumes:
caddy_data:
name: navigara-caddy-data
caddy_config:
name: navigara-caddy-config
networks:
navigara-network:
name: navigara-network
driver: bridge
Create a .env file with your configuration:
# Version
NAVIGARA_VERSION=1.0.0
# Container images (override to use your own registry)
# BACKEND_IMAGE=your-registry.example.com/navigara/vision-be:${NAVIGARA_VERSION}
# COLLECTOR_IMAGE=your-registry.example.com/navigara/vision-collector:${NAVIGARA_VERSION}
# FRONTEND_IMAGE=your-registry.example.com/navigara/vision-fe:${NAVIGARA_VERSION}
# Database
DATABASE_URL=postgresql://navigara:<password>@<postgres-host>:5432/navigara?sslmode=require
# LLM Configuration
LLM_PROVIDER=openai # openai | genai | anthropic
LLM_MODEL=gpt-5.4 # Model name for your provider
LLM_API_KEY=<your-api-key> # API key for the LLM provider
LLM_API_URL= # Custom endpoint URL (optional, for self-hosted models)
# Application
DOMAIN=navigara.yourcompany.com
# Collector
COLLECTOR_API_KEY=<generate-a-random-key>
4. Configure PostgreSQL
Connect to your PostgreSQL instance as a superuser and run the following:
-- Create database and application user
CREATE DATABASE navigara;
CREATE USER navigara WITH PASSWORD '<strong-password>';
-- Connect to the navigara database
\c navigara
-- Enable required extensions
CREATE EXTENSION IF NOT EXISTS vector;
-- Grant permissions to the application user
GRANT CONNECT, CREATE, TEMPORARY ON DATABASE navigara TO navigara;
GRANT CREATE, USAGE ON SCHEMA public TO navigara;
GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES, TRIGGER, TRUNCATE ON ALL TABLES IN SCHEMA public TO navigara;
GRANT SELECT, UPDATE, USAGE ON ALL SEQUENCES IN SCHEMA public TO navigara;
ALTER DEFAULT PRIVILEGES FOR ROLE navigara IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES, TRIGGER, TRUNCATE ON TABLES TO navigara;
ALTER DEFAULT PRIVILEGES FOR ROLE navigara IN SCHEMA public GRANT SELECT, UPDATE, USAGE ON SEQUENCES TO navigara;
Then set DATABASE_URL in your .env to use the navigara user:
DATABASE_URL=postgresql://navigara:<password>@<postgres-host>:5432/navigara?sslmode=require
Navigara runs database migrations automatically on startup — no manual schema setup is needed.
5. Start Navigara
# Pull the latest images
docker compose pull
# Start all services
docker compose up -d
Verify all services are running:
6. Access the application
Open https://navigara.yourcompany.com in your browser. The first user to sign up becomes the organization owner.
Reverse Proxy (Caddy)
Navigara ships with Caddy as the reverse proxy. Caddy handles TLS termination, automatic certificate provisioning via Let’s Encrypt, and routing between frontend, backend API, and gRPC services.
Create the Caddyfile at deployment/caddy/Caddyfile:
navigara.yourcompany.com {
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Frame-Options "SAMEORIGIN"
X-Content-Type-Options "nosniff"
X-XSS-Protection "1; mode=block"
Referrer-Policy "strict-origin-when-cross-origin"
}
handle_path /api/* {
encode gzip
header {
Access-Control-Allow-Origin "https://navigara.yourcompany.com"
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Access-Control-Allow-Headers "Authorization, Content-Type, X-Api-Key"
Access-Control-Max-Age "86400"
}
@options method OPTIONS
respond @options 204
reverse_proxy backend:8080
}
handle {
encode gzip
reverse_proxy frontend:3000
}
log {
output stdout
format json
}
}
Caddy automatically provisions and renews TLS certificates via Let’s Encrypt. No manual certificate management is required.
Backup and Restore
Database backup
Back up your PostgreSQL database regularly using pg_dump:
pg_dump -h <postgres-host> -U navigara -d navigara -Fc > navigara_backup_$(date +%Y%m%d).dump
Database restore
pg_restore -h <postgres-host> -U navigara -d navigara --clean navigara_backup.dump
The database contains all application state. Ensure backups are stored securely and tested regularly.
Monitoring and Health Checks
The backend exposes a health check endpoint on the HTTP port:
| Endpoint | Description |
|---|
GET /health | Application and database health (returns gRPC health status) |
The frontend container also has a built-in health check via wget on port 3000.
Use these with your monitoring system (Prometheus, Datadog, etc.) to track service availability.
Upgrades
To upgrade Navigara:
cd /opt/navigara
# Pull the latest images
docker compose pull
# Restart with new images
docker compose up -d
Database migrations run automatically on startup. Always back up your database before upgrading.
Troubleshooting
| Issue | Solution |
|---|
| Database connection refused | Verify DATABASE_URL and that the PostgreSQL instance allows connections from the VM’s IP |
| pgvector extension missing | Run CREATE EXTENSION IF NOT EXISTS vector; as a superuser on the database |
| LLM analysis failing | Verify LLM_API_KEY and that the VM can reach the LLM API endpoint |
| High disk usage | Check knowledge graph data growth; consider scaling to a larger instance tier |
| Migrations stuck | Run the migration lock cleanup script: docker compose exec backend /app/scripts/clear-migration-locks.sh |