Skip to content

Deployment

Nick edited this page Mar 10, 2026 · 5 revisions

Deployment Guide

Complete guide for deploying PATAS Core in production environments.


Table of Contents

  1. Prerequisites
  2. Installation Methods
  3. Configuration
  4. Production Deployment
  5. Docker Deployment
  6. On-Premise Setup
  7. Monitoring and Observability
  8. Scaling and Performance
  9. Security Hardening
  10. Troubleshooting

Prerequisites

System Requirements

  • OS: Linux (Debian 12+, Ubuntu 20.04+), macOS, or Windows with WSL2
  • Python: 3.10 or higher
  • Memory: Minimum 4GB RAM (8GB+ recommended for production)
  • Storage: 10GB+ free space (depends on data volume)
  • CPU: 2+ cores recommended

Software Dependencies

  • Database: SQLite (default) or PostgreSQL 12+
  • Optional: Redis (for caching, if enabled)
  • Optional: Prometheus (for metrics, if enabled)

Network Requirements

  • Outbound HTTPS: Required for OpenAI API (if using OpenAI embeddings)
  • Inbound HTTP/HTTPS: Required for API server (default port 8000)
  • Database access: Local or network access to database

Installation Methods

Method 1: Poetry (Recommended for Development)

# Clone repository
git clone https://github.com/KikuAI-Lab/PATAS.git
cd PATAS

# Install dependencies
poetry install

# Activate virtual environment
poetry shell

Method 2: pip (Simple Installation)

# Clone repository
git clone https://github.com/KikuAI-Lab/PATAS.git
cd PATAS

# Install dependencies
pip install -e .

Method 3: Docker (Recommended for Production)

See Docker Deployment section below.


Configuration

Environment Variables

Create .env file from .env.example:

cp .env.example .env

Key configuration variables:

# Database
DATABASE_URL=sqlite:///./data/patas.db
# Or PostgreSQL:
# DATABASE_URL=postgresql+asyncpg://user:password@localhost/patas

# Safety Profile
AGGRESSIVENESS_PROFILE=conservative
SAFETY_MODE=CONSERVATIVE

# Privacy Mode
PRIVACY_MODE=STRICT

# Embedding Provider (required for semantic mining)
EMBEDDING_PROVIDER=openai
EMBEDDING_MODEL=text-embedding-3-small
OPENAI_API_KEY=your-key-here

# LLM (optional)
LLM_PROVIDER=none
# Or if using LLM:
# LLM_PROVIDER=openai
# OPENAI_API_KEY=your-key-here

# API Server
API_HOST=0.0.0.0
API_PORT=8000

# Logging
LOG_LEVEL=INFO

YAML Configuration

For advanced configuration, use config.yaml:

# Database
database:
  url: "sqlite:///./data/patas.db"
  pool_size: 10
  max_overflow: 20

# Safety
safety:
  aggressiveness_profile: conservative
  safety_mode: CONSERVATIVE
  min_precision: 0.98
  max_ham_rate: 0.01

# Privacy
privacy:
  mode: STRICT
  redact_pii: true
  redact_email: true
  redact_phone: true
  redact_credit_card: true

# Embeddings (required for semantic mining)
embeddings:
  provider: openai
  model: text-embedding-3-small
  api_key: "${OPENAI_API_KEY}"

# LLM (optional)
llm:
  provider: none
  # Or if using LLM:
  # provider: openai
  # model: gpt-4
  # api_key: "${OPENAI_API_KEY}"

# API
api:
  host: "0.0.0.0"
  port: 8000
  workers: 4

# Logging
logging:
  level: INFO
  format: json

See Configuration for complete configuration reference.


Production Deployment

Step 1: Pre-Deployment Checklist

  • Database configured and accessible
  • Environment variables set
  • API keys configured (if using OpenAI)
  • Safety profile set to conservative
  • Privacy mode set to STRICT
  • Firewall rules configured
  • Monitoring configured

Step 2: Database Setup

SQLite (Default, Development Only)

# SQLite is automatically created
mkdir -p data
# Database will be created at: data/patas.db

Note: SQLite is not recommended for production. Use PostgreSQL.

PostgreSQL (Production)

# Create database
createdb patas

# Or using psql
psql -U postgres
CREATE DATABASE patas;
CREATE USER patas_user WITH PASSWORD 'secure_password';
GRANT ALL PRIVILEGES ON DATABASE patas TO patas_user;

Update DATABASE_URL:

DATABASE_URL=postgresql+asyncpg://patas_user:secure_password@localhost/patas

Step 3: Initialize Database

# Run database migrations (if any)
patas init-db

# Or via API
curl -X POST http://localhost:8000/api/v1/health

Step 4: Run Safety Evaluation

CRITICAL: Always run safety evaluation before production deployment:

patas safety-eval --profile=conservative

Do not deploy if safety evaluation fails.

Step 5: Start API Server

Using uvicorn (Recommended)

# Development
uvicorn app.api.main:app --host 0.0.0.0 --port 8000 --reload

# Production (with workers)
uvicorn app.api.main:app \
  --host 0.0.0.0 \
  --port 8000 \
  --workers 4 \
  --log-level info

Using gunicorn (Alternative)

gunicorn app.api.main:app \
  --workers 4 \
  --worker-class uvicorn.workers.UvicornWorker \
  --bind 0.0.0.0:8000 \
  --log-level info

Using systemd (Linux)

Create /etc/systemd/system/patas.service:

[Unit]
Description=PATAS Core API
After=network.target postgresql.service

[Service]
Type=simple
User=patas
WorkingDirectory=/opt/patas-core
Environment="PATH=/opt/patas-core/.venv/bin"
ExecStart=/opt/patas-core/.venv/bin/uvicorn app.api.main:app \
  --host 0.0.0.0 \
  --port 8000 \
  --workers 4
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl enable patas
sudo systemctl start patas
sudo systemctl status patas

Step 6: Verify Deployment

# Health check
curl http://localhost:8000/api/v1/health

# Expected response:
# {"status":"ok","version":"2.0.0","core_ready":true}

Docker Deployment

Dockerfile

Create Dockerfile:

FROM python:3.10-slim

WORKDIR /app

# Install system dependencies
RUN apt-get update && apt-get install -y \
    gcc \
    postgresql-client \
    && rm -rf /var/lib/apt/lists/*

# Install Poetry
RUN pip install poetry

# Copy dependency files
COPY pyproject.toml poetry.lock ./

# Install dependencies
RUN poetry config virtualenvs.create false \
    && poetry install --no-dev

# Copy application code
COPY . .

# Create data directory
RUN mkdir -p /app/data

# Expose port
EXPOSE 8000

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
  CMD python -c "import requests; requests.get('http://localhost:8000/api/v1/health')"

# Run API server
CMD ["uvicorn", "app.api.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]

docker-compose.yml

Create docker-compose.yml:

version: '3.8'

services:
  patas-api:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql+asyncpg://patas:password@postgres/patas
      - AGGRESSIVENESS_PROFILE=conservative
      - SAFETY_MODE=CONSERVATIVE
      - PRIVACY_MODE=STRICT
      - EMBEDDING_PROVIDER=openai
      - OPENAI_API_KEY=${OPENAI_API_KEY}
    volumes:
      - ./data:/app/data
    depends_on:
      - postgres
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  postgres:
    image: postgres:15
    environment:
      - POSTGRES_DB=patas
      - POSTGRES_USER=patas
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U patas"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  postgres_data:

Build and Run

# Build image
docker-compose build

# Start services
docker-compose up -d

# View logs
docker-compose logs -f patas-api

# Stop services
docker-compose down

Production Docker Compose

For production, use environment-specific configuration:

# docker-compose.prod.yml
version: '3.8'

services:
  patas-api:
    image: patas-core:latest
    restart: always
    environment:
      - DATABASE_URL=${DATABASE_URL}
      - AGGRESSIVENESS_PROFILE=conservative
      - SAFETY_MODE=CONSERVATIVE
      - PRIVACY_MODE=STRICT
      - OPENAI_API_KEY=${OPENAI_API_KEY}
    volumes:
      - ./data:/app/data
    networks:
      - patas-network
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 4G
        reservations:
          cpus: '1'
          memory: 2G

  postgres:
    image: postgres:15
    restart: always
    environment:
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - patas-network
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 2G

networks:
  patas-network:
    driver: bridge

volumes:
  postgres_data:

On-Premise Setup

Requirements for On-Premise Deployment

  1. No External API Calls (if privacy is critical):

    • Use local embedding models
    • Disable LLM provider
    • Set PRIVACY_MODE=STRICT
  2. Local Embedding Models:

embeddings:
  provider: local
  model: sentence-transformers/all-MiniLM-L6-v2
  device: cpu  # or cuda if GPU available
  1. Network Isolation:
    • Deploy in isolated network
    • No outbound internet access required
    • All processing on-premise

On-Premise Configuration

# config.yaml for on-premise
privacy:
  mode: STRICT
  redact_pii: true
  allow_external_calls: false

embeddings:
  provider: local
  model: sentence-transformers/all-MiniLM-L6-v2

llm:
  provider: none  # No LLM, pure rule-based

api:
  host: "127.0.0.1"  # Local only
  port: 8000

Installation Steps

  1. Install Python dependencies:
pip install -e . --no-deps
pip install sentence-transformers torch
  1. Download embedding model (first run):
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
# Model will be cached locally
  1. Start API server:
uvicorn app.api.main:app --host 127.0.0.1 --port 8000

Monitoring and Observability

Health Checks

API Health Endpoint

curl http://localhost:8000/api/v1/health

Response:

{
  "status": "ok",
  "version": "2.0.0",
  "core_ready": true
}

Custom Health Check Script

#!/bin/bash
# healthcheck.sh

HEALTH_URL="http://localhost:8000/api/v1/health"
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" $HEALTH_URL)

if [ "$RESPONSE" = "200" ]; then
    echo "PATAS is healthy"
    exit 0
else
    echo "PATAS health check failed: HTTP $RESPONSE"
    exit 1
fi

Prometheus Metrics

If prometheus-client is installed, metrics are available at:

http://localhost:8000/metrics

Key metrics:

  • patas_rules_evaluated_total - Total rules evaluated
  • patas_pattern_hits_total{rule_id, tier, profile} - Pattern hits
  • patas_decisions_total{decision} - Decisions made
  • patas_evaluation_latency_seconds - Evaluation latency

Logging

JSON Logging (Production)

Set LOG_FORMAT=json in environment:

LOG_FORMAT=json uvicorn app.api.main:app ...

Log Levels

  • DEBUG: Detailed debugging information
  • INFO: General informational messages
  • WARNING: Warning messages
  • ERROR: Error messages
  • CRITICAL: Critical errors

Monitoring Setup

Prometheus Configuration

# prometheus.yml
scrape_configs:
  - job_name: 'patas'
    static_configs:
      - targets: ['localhost:8000']
    metrics_path: '/metrics'
    scrape_interval: 30s

Grafana Dashboard

Create dashboard with:

  • API request rate
  • Rule evaluation metrics
  • Pattern hit rates
  • Error rates
  • Latency percentiles

Alerting

Set up alerts for:

  • API health check failures
  • High error rates (> 1%)
  • High latency (P95 > 500ms)
  • Database connection failures
  • Safety evaluation failures

Scaling and Performance

Horizontal Scaling

PATAS API is stateless and can be scaled horizontally:

# Run multiple instances behind load balancer
uvicorn app.api.main:app --host 0.0.0.0 --port 8000 --workers 4
uvicorn app.api.main:app --host 0.0.0.0 --port 8001 --workers 4
uvicorn app.api.main:app --host 0.0.0.0 --port 8002 --workers 4

Database Connection Pooling

Configure in config.yaml:

database:
  pool_size: 20
  max_overflow: 40
  pool_timeout: 30
  pool_recycle: 3600

Caching

Enable Redis caching (if available):

cache:
  provider: redis
  url: redis://localhost:6379
  ttl: 3600

Performance Tuning

  1. Database Indexes: Ensure indexes on frequently queried columns
  2. Batch Processing: Use batch endpoints for large datasets
  3. Async Processing: Use async endpoints for I/O-bound operations
  4. Connection Pooling: Configure appropriate pool sizes

Security Hardening

1. Network Security

  • Use HTTPS in production (reverse proxy with TLS)
  • Restrict API access to internal network
  • Use firewall rules to limit access

2. Authentication (If Required)

Add API key authentication:

# In app/api/main.py
from fastapi import Security, HTTPException
from fastapi.security import APIKeyHeader

API_KEY = os.getenv("API_KEY")

api_key_header = APIKeyHeader(name="X-API-Key")

async def verify_api_key(api_key: str = Security(api_key_header)):
    if api_key != API_KEY:
        raise HTTPException(status_code=403, detail="Invalid API key")
    return api_key

3. Input Validation

  • All inputs validated via Pydantic models
  • SQL injection prevention via parameterized queries
  • XSS prevention via input sanitization

4. Secrets Management

  • Never commit secrets to repository
  • Use environment variables or secret management systems
  • Rotate API keys regularly

5. Database Security

  • Use strong database passwords
  • Restrict database access to application only
  • Enable SSL/TLS for database connections

6. Privacy Mode

Always use STRICT privacy mode in production:

PRIVACY_MODE=STRICT

This ensures:

  • No external API calls with message data
  • PII redaction enabled
  • Minimal logging

Troubleshooting

Common Issues

1. Database Connection Errors

Problem: Cannot connect to database

Solution:

# Check database URL
echo $DATABASE_URL

# Test connection
psql $DATABASE_URL -c "SELECT 1"

# Check database exists
psql $DATABASE_URL -l

2. API Server Not Starting

Problem: API server fails to start

Solution:

# Check logs
tail -f logs/patas.log

# Check port availability
netstat -tuln | grep 8000

# Check Python version
python --version  # Should be 3.10+

# Check dependencies
pip list | grep fastapi

3. Pattern Mining Fails

Problem: Pattern mining returns no results

Solution:

# Check if messages are ingested
patas list-messages --count

# Check embedding provider
echo $EMBEDDING_PROVIDER
echo $OPENAI_API_KEY  # If using OpenAI

# Check logs for errors
grep ERROR logs/patas.log

4. Safety Evaluation Fails

Problem: patas safety-eval fails

Solution:

# Check evaluation data
patas eval-rules

# Review rule metrics
patas explain-rule --id=RULE_123

# Adjust safety thresholds if needed
# See config.yaml: safety.min_precision, safety.max_ham_rate

5. High Memory Usage

Problem: High memory consumption

Solution:

# Reduce batch sizes
# In config.yaml:
pattern_mining:
  batch_size: 100  # Reduce from default

# Use streaming for large datasets
# Process in smaller batches

Debug Mode

Enable debug logging:

LOG_LEVEL=DEBUG uvicorn app.api.main:app ...

Getting Help

  1. Check Configuration and Deployment wiki pages
  2. Review application logs
  3. Check database state
  4. Verify configuration

Post-Deployment Checklist

  • API health check returns 200
  • Safety evaluation passes
  • Monitoring configured and working
  • Logs are being collected
  • Database backups configured
  • Firewall rules applied
  • SSL/TLS configured (if exposed)
  • API keys rotated
  • Documentation updated

Next Steps


Last Updated: 2025-11-18

Clone this wiki locally