Skip to main content

Overview

Support Bot uses environment variables for configuration. All settings are defined in a .env file that should be created from the provided .env.example template.
Never commit .env files to version control. They contain sensitive credentials and API keys.

Setup

1

Copy example file

cp .env.example .env
2

Edit configuration

Open .env in your editor and set required values:
nano .env
# or
vim .env
3

Verify configuration

Ensure all required variables are set before starting the application.

Required Variables

AI Model Configuration

MODEL
string
required
The AI model to use for chat completions.Examples:
  • gemini-2.0-flash-exp (Google Gemini)
  • gpt-4 (OpenAI)
  • claude-3-opus (Anthropic)
  • llama3 (Ollama)
MODEL=gemini-2.0-flash-exp

Google AI (Gemini)

GEMINI_API_KEY
string
Single API key for Google Gemini models.
GEMINI_API_KEY=your_gemini_api_key_here
Get your API key from Google AI Studio.
GEMINI_API_KEYS
string
Multiple API keys for load balancing (comma-separated).
GEMINI_API_KEYS=key1,key2,key3
Use this when you have multiple Gemini API keys to distribute requests and avoid rate limits.
GOOGLE_API_KEY
string
Alternative Google API key for backward compatibility.
GOOGLE_API_KEY=your_google_api_key_here
Only one of GEMINI_API_KEY, GEMINI_API_KEYS, or GOOGLE_API_KEY is required if using Gemini models.

Database Configuration

DATABASE_URL
string
required
Async PostgreSQL connection string for the main database.Format: postgresql+asyncpg://user:password@host:port/databaseDefault (development):
DATABASE_URL=postgresql+asyncpg://postgres:admin@localhost:5434/bot_db
Production example:
DATABASE_URL=postgresql+asyncpg://user:[email protected]:5432/bot_db
DATABASE_URL_SYNC
string
required
Synchronous PostgreSQL connection string for migrations and scripts.Format: postgresql://user:password@host:port/databaseDefault (development):
DATABASE_URL_SYNC=postgresql://postgres:admin@localhost:5434/bot_db
Used by Alembic for database migrations.
VECTOR_DATABASE_URL
string
required
PostgreSQL connection string for the pgvector database.Format: postgresql://user:password@host:port/databaseDefault (development):
VECTOR_DATABASE_URL=postgresql://postgres:admin@localhost:5433/vector_db
Stores vector embeddings for semantic search.
QDRANT_URL
string
required
URL for the Qdrant vector search engine.Default (development):
QDRANT_URL=http://localhost:6333
Production example:
QDRANT_URL=https://qdrant.example.com:6333

Authentication & Security

JWT_SECRET_KEY
string
required
Secret key for signing JWT tokens.Generate a secure key:
openssl rand -hex 32
Example:
JWT_SECRET_KEY=a7f4c3e2b1d0a9f8e7d6c5b4a3e2d1c0b9a8f7e6d5c4b3a2e1d0c9b8a7f6e5d4
Use a cryptographically secure random string. Never use default or example values in production.
JWT_ALGORITHM
string
required
Algorithm for JWT token signing.Recommended: HS256
JWT_ALGORITHM=HS256
Other options: HS384, HS512, RS256
JWT_EXPIRY
integer
required
JWT token expiration time in seconds.Default: 86400 (24 hours)
JWT_EXPIRY=86400
Examples:
  • 1 hour: 3600
  • 7 days: 604800
  • 30 days: 2592000
ENCRYPTION_KEY
string
required
Key for encrypting sensitive data at rest.Generate using Fernet:
from cryptography.fernet import Fernet
print(Fernet.generate_key().decode())
Example:
ENCRYPTION_KEY=gAAAAABhk..._base64_encoded_key_...
ENABLE_PASSWORD_VALIDATION
boolean
Enable/disable password strength validation.
ENABLE_PASSWORD_VALIDATION=true
  • true: Enforce password complexity requirements
  • false: Allow any password (development only)

Environment-Specific Configuration

Development (.env)

For local development with Docker Compose:
# AI Model
MODEL=gemini-2.0-flash-exp
GEMINI_API_KEY=your_gemini_key

# Databases (Docker defaults)
DATABASE_URL=postgresql+asyncpg://postgres:admin@localhost:5434/bot_db
DATABASE_URL_SYNC=postgresql://postgres:admin@localhost:5434/bot_db
VECTOR_DATABASE_URL=postgresql://postgres:admin@localhost:5433/vector_db
QDRANT_URL=http://localhost:6333

# Security (development keys)
JWT_ALGORITHM=HS256
JWT_SECRET_KEY=dev_secret_key_change_in_production
JWT_EXPIRY=86400
ENCRYPTION_KEY=dev_encryption_key_change_in_production
ENABLE_PASSWORD_VALIDATION=false

Production (.env.prod)

For production deployment:
# AI Model
MODEL=gemini-2.0-flash-exp
GEMINI_API_KEYS=key1,key2,key3  # Multiple keys for rate limiting

# Databases (internal Docker network)
DATABASE_URL=postgresql+asyncpg://postgres:secure_password@db:5434/bot_db
DATABASE_URL_SYNC=postgresql://postgres:secure_password@db:5434/bot_db
VECTOR_DATABASE_URL=postgresql://postgres:secure_password@vector_db:5432/vector_db
QDRANT_URL=http://qdrant:6333

# Security (strong production keys)
JWT_ALGORITHM=HS256
JWT_SECRET_KEY=<generated_with_openssl_rand_hex_32>
JWT_EXPIRY=86400
ENCRYPTION_KEY=<generated_with_fernet>
ENABLE_PASSWORD_VALIDATION=true
In production:
  • Use strong, randomly generated keys
  • Enable password validation
  • Use internal Docker network hostnames for services
  • Consider using secrets management (e.g., AWS Secrets Manager, HashiCorp Vault)

Loading Environment Variables

Python Application

The application automatically loads .env using python-dotenv:
from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    model: str
    database_url: str
    jwt_secret_key: str
    
    class Config:
        env_file = ".env"
        case_sensitive = False

Docker Compose

Specify the env file in docker-compose.yml:
services:
  backend:
    env_file:
      - .env.prod

Manual Loading

# Load and export all variables
export $(cat .env | xargs)

# Verify
echo $DATABASE_URL

Validation

Verify your configuration before deployment:
# List all required variables
grep -v '^#' .env.example | cut -d= -f1

# Check if set in .env
for var in $(grep -v '^#' .env.example | cut -d= -f1); do
  if grep -q "^$var=" .env; then
    echo "✓ $var is set"
  else
    echo "✗ $var is missing"
  fi
done

Security Best Practices

Maintain separate files for each environment:
  • .env - Development
  • .env.prod - Production
  • .env.test - Testing
Add all to .gitignore:
.env
.env.*
!.env.example
Update credentials periodically:
# Generate new JWT secret
openssl rand -hex 32

# Generate new encryption key
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
Consider using:
  • AWS Secrets Manager
  • HashiCorp Vault
  • Azure Key Vault
  • Google Secret Manager
Example with AWS:
import boto3
import json

def get_secret():
    client = boto3.client('secretsmanager')
    response = client.get_secret_value(SecretId='support-bot/prod')
    return json.loads(response['SecretString'])
chmod 600 .env
Prevents other users from reading sensitive values.

Troubleshooting

Environment Not Loading

  1. Verify file location:
    ls -la .env
    
  2. Check file format (no BOM, Unix line endings):
    file .env
    
  3. Validate syntax:
    # No spaces around =
    KEY=value      # ✓ Correct
    KEY = value    # ✗ Wrong
    
Verify env_file in docker-compose.yml:
services:
  backend:
    env_file:
      - .env.prod  # Path relative to docker-compose.yml
Check loaded variables:
docker-compose config

Connection Errors

  1. Verify URL format:
    echo $DATABASE_URL
    
  2. Check host reachability:
    nc -zv localhost 5434
    
  3. Test credentials:
    psql $DATABASE_URL_SYNC -c "SELECT 1;"
    
  1. Check key is set:
    echo ${GEMINI_API_KEY:0:10}...  # Show first 10 chars
    
  2. Verify no extra whitespace:
    export GEMINI_API_KEY=$(echo $GEMINI_API_KEY | xargs)
    
  3. Test in API console:

Next Steps

Installation

Complete installation steps

Docker Deployment

Deploy with Docker Compose

Build docs developers (and LLMs) love