Skip to main content

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:
  1. Linux VM — runs the Navigara application (backend, frontend, collector) via Docker Compose
  2. Managed PostgreSQL — stores all application data including vector embeddings (requires pgvector extension)
  3. 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:
ProviderModelNotes
Google Vertex AIGemini 2.5 FlashRecommended — best cost/performance ratio
AnthropicClaude Sonnet 4.6High quality analysis
OpenAIGPT-5.4Widely 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:
ServicePurposeExample endpoints
Git providerRepository cloning and commit fetchinggithub.com, gitlab.com, or your self-hosted instance
Task managementAlignment scoring via issue/task dataapi.linear.app, *.atlassian.net, or your self-hosted instance
LLM APIAI-powered commit analysisapi.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

Suitable for small to mid-size engineering teams.
ComponentCPUMemoryDisk
Linux VM8 vCPU16 GB500 GB SSD
PostgreSQL8 vCPU32 GB500 GB 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.

3. Configure the deployment

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:
docker compose ps

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:
EndpointDescription
GET /healthApplication 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

IssueSolution
Database connection refusedVerify DATABASE_URL and that the PostgreSQL instance allows connections from the VM’s IP
pgvector extension missingRun CREATE EXTENSION IF NOT EXISTS vector; as a superuser on the database
LLM analysis failingVerify LLM_API_KEY and that the VM can reach the LLM API endpoint
High disk usageCheck knowledge graph data growth; consider scaling to a larger instance tier
Migrations stuckRun the migration lock cleanup script: docker compose exec backend /app/scripts/clear-migration-locks.sh