Files
sure/.env.example
T
Juan José Mata fd6f4ff078 Add live AI checks to system health (#3155)
* Add live AI checks to system health

Give super admins a dedicated AI status view with bounded liveness probes for LLMs, vector stores, pgvector, and embedding endpoints. Record sanitized failures in both the system debug log and Rails logger, and document the recommended local configuration.\n\nCloses #3145

* Fix AI health CI checks

* Address AI health review feedback

* Correct Ollama model preload guidance

* Distinguish OpenAI-compatible providers

* Make Ollama startup readiness explicit

* Recognize Cloudflare AI endpoints
2026-08-24 22:41:08 +02:00

250 lines
10 KiB
Bash

# ================================ PLEASE READ ===========================================================
# This file outlines all the possible environment variables supported by the Sure app for self hosting.
#
# If you're a developer setting up your local environment, please use `.env.local.example` instead.
# ========================================================================================================
# Required self-hosting vars
# --------------------------------------------------------------------------------------------------------
# Enables self hosting features (should be set to true unless you know what you're doing)
SELF_HOSTED=true
# Controls onboarding flow (valid: open, closed, invite_only)
ONBOARDING_STATE=open
# Secret key used to encrypt credentials (https://api.rubyonrails.org/v7.1.3.2/classes/Rails/Application.html#method-i-secret_key_base)
# Has to be a random string, generated eg. by running `openssl rand -hex 64`
SECRET_KEY_BASE=secret-value
# Optional self-hosting vars
# --------------------------------------------------------------------------------------------------------
# Optional: OpenAI-compatible API endpoint config
OPENAI_ACCESS_TOKEN=
OPENAI_MODEL=
OPENAI_URI_BASE=
# Optional: LLM token budget (applies to chat, auto-categorize, merchant detection, PDF processing).
# Lower these for small-context local models (Ollama, LM Studio, LocalAI).
# For larger local models, raise the context window to match the model you actually run.
# Example: Gemma 3/4, Qwen, and other large-context models often need `LLM_CONTEXT_WINDOW=8192` or higher.
# LLM_CONTEXT_WINDOW=2048
# LLM_MAX_RESPONSE_TOKENS=512
# LLM_MAX_HISTORY_TOKENS=
# LLM_SYSTEM_PROMPT_RESERVE=256
# LLM_MAX_ITEMS_PER_CALL=25
# Optional: how long the chat waits for an assistant response before showing a
# "no response" error. Raise for slow local models — OpenAI-compatible providers
# are not streamed, so nothing renders until the whole reply is generated.
#
# This clock starts when the message is queued and covers the whole turn, so it
# is a SUM, not a maximum. The worst case is:
#
# (1 + ASSISTANT_MAX_TOOL_CALL_ITERATIONS) * OPENAI_REQUEST_TIMEOUT
# + tool execution + queue wait
#
# At the defaults that bound is 6 * 60 = 360s plus overhead. The 90s default is
# sized for typical latency rather than that bound — cloud models answer in
# seconds, so a turn rarely approaches it. Size against the formula once your
# per-call latency is genuinely near OPENAI_REQUEST_TIMEOUT, which is the case
# for local models. Set too low, you get a generic "no response" instead of the
# specific timeout error, and the job keeps burning tokens after the chat gave up.
# Minimum 30; also settable on the Self-Hosting settings page.
# AI_RESPONSE_TIMEOUT=90
#
# Lowering the tool-call cap is often the better lever on slow hardware: it cuts
# the first term of that sum instead of requiring a very long timeout.
# ASSISTANT_MAX_TOOL_CALL_ITERATIONS=5
# Optional: OpenAI-compatible capability flags
# OPENAI_REQUEST_TIMEOUT=60 # HTTP timeout in seconds; raise for slow local models
# OPENAI_SUPPORTS_PDF_PROCESSING=true # Set to false for endpoints without vision support
# OPENAI_SUPPORTS_RESPONSES_ENDPOINT= # Override Responses-API vs chat.completions routing
# LLM_JSON_MODE= # auto | strict | json_object | none
# Optional: document-search vector store. Hosted OpenAI is selected by default
# when OPENAI_ACCESS_TOKEN is configured. For a local OpenAI-compatible LLM,
# use pgvector plus a separate OpenAI-compatible embeddings endpoint.
# VECTOR_STORE_PROVIDER=pgvector # openai | pgvector | qdrant (scaffolded only)
# EMBEDDING_URI_BASE=http://ollama:11434/v1
# EMBEDDING_MODEL=mxbai-embed-large
# EMBEDDING_DIMENSIONS=1024 # Must match the embedding model
# EMBEDDING_ACCESS_TOKEN= # Optional; falls back to OPENAI_ACCESS_TOKEN
# AI_HEALTH_PROBE_TIMEOUT=5 # Per-request timeout for admin live checks
# AI_HEALTH_PROBE_CACHE_TTL=60 # Cache live results and deduplicate failure logs
# Optional: External AI Assistant — delegates chat to a remote AI agent
# instead of calling LLMs directly. The agent calls back to Sure's /mcp endpoint.
# See docs/hosting/ai.md for full details.
# ASSISTANT_TYPE=external
# EXTERNAL_ASSISTANT_URL=https://your-agent-host/v1/chat/completions
# EXTERNAL_ASSISTANT_TOKEN=your-api-token # pipelock:ignore
# EXTERNAL_ASSISTANT_AGENT_ID=main
# EXTERNAL_ASSISTANT_SESSION_KEY=agent:main:main
# EXTERNAL_ASSISTANT_ALLOWED_EMAILS=user@example.com
# Optional: MCP server endpoint — enables /mcp for external AI assistants.
# Both values are required. MCP_USER_EMAIL must match an existing user's email.
# MCP_API_TOKEN=your-random-bearer-token # pipelock:ignore
# MCP_USER_EMAIL=user@example.com
# Optional: Langfuse config
LANGFUSE_HOST=https://cloud.langfuse.com
LANGFUSE_PUBLIC_KEY=
LANGFUSE_SECRET_KEY=
# Optional: Twelve Data API Key for exchange rates + stock prices
# (you can also set this in your self-hosted settings page)
# Get it here: https://twelvedata.com/
TWELVE_DATA_API_KEY=
# Optional: Provider selection for exchange rates and securities data
# Options: twelve_data (default), yahoo_finance
# EXCHANGE_RATE_PROVIDER=twelve_data
# SECURITIES_PROVIDER=twelve_data
# Alternative: Use Yahoo Finance as provider (free, no API key required)
EXCHANGE_RATE_PROVIDER=yahoo_finance
SECURITIES_PROVIDER=yahoo_finance
# Brandfetch to grab logos for banks and merchants
BRAND_FETCH_CLIENT_ID=
# Custom port config
# For users who have other applications listening at 3000, this allows them to set a value puma will listen to.
PORT=3000
# SMTP Configuration
# This is only needed if you intend on sending emails from your Sure instance (such as for password resets or email financial reports).
# Resend.com is a good option that offers a free tier for sending emails.
SMTP_ADDRESS=
SMTP_PORT=465
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_TLS_ENABLED=true
SMTP_TLS_SKIP_VERIFY=false
# Address that emails are sent from
EMAIL_SENDER=
# Database Configuration
DB_HOST=localhost # May need to be changed to `DB_HOST=db` if using devcontainer
DB_PORT=5432
POSTGRES_PASSWORD=postgres # pipelock:ignore
POSTGRES_USER=postgres
# Redis configuration
# Standard Redis URL (for direct connection)
REDIS_URL=redis://localhost:6379/1
# Redis Sentinel configuration (for high availability)
# When REDIS_SENTINEL_HOSTS is set, it takes precedence over REDIS_URL
# REDIS_SENTINEL_HOSTS=sentinel1:26379,sentinel2:26379,sentinel3:26379
# REDIS_SENTINEL_MASTER=mymaster
# REDIS_SENTINEL_USERNAME=default
# REDIS_PASSWORD=your-redis-password # pipelock:ignore
# Sidekiq Web UI (/sidekiq)
# The queue dashboard is reachable in production only by signed-in super admins
# (the first user created on the instance). Optionally set BOTH variables below
# to require basic-auth credentials as a second layer on top of that.
# SIDEKIQ_WEB_USERNAME=
# SIDEKIQ_WEB_PASSWORD=
# App Domain
# This is the domain that your Sure instance will be hosted at. It is used to generate links in emails and other places.
APP_DOMAIN=
# WebAuthn / passkey configuration
# RP ID is usually the registrable domain (example.com), not a full URL.
# Allowed origins is a comma-separated list of the full origins where users
# access Sure (scheme included), e.g. https://sure.example.com,https://app.example.com.
WEBAUTHN_RP_ID=
WEBAUTHN_ALLOWED_ORIGINS=
# Set to false to keep passkeys as a second factor only, instead of also
# allowing passwordless sign-in. See docs/hosting/webauthn.md.
# AUTH_PASSKEY_LOGIN_ENABLED=true
# OpenID Connect configuration
OIDC_CLIENT_ID=
OIDC_CLIENT_SECRET=
OIDC_ISSUER=
OIDC_REDIRECT_URI=
# Product/Brand Name
PRODUCT_NAME=
BRAND_NAME=
# PostHog configuration
POSTHOG_KEY=
POSTHOG_HOST=
# Disable enforcing SSL connections
# DISABLE_SSL=true
# Customizations to outbound SSL/TLS connections
# Path to custom CA certificate (PEM format)
# SSL_CA_FILE=
# Enable/disable SSL verification
# SSL_VERIFY=true
# Enable verbose SSL logging
# SSL_DEBUG=false
# Active Record Encryption Keys (Optional)
# These keys are used to encrypt sensitive data like API keys in the database.
# For managed mode: Set these environment variables to provide encryption keys.
# For self-hosted mode: If not provided, they will be automatically generated based on your SECRET_KEY_BASE.
# You can generate your own keys by running: rails db:encryption:init
# ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=
# ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=
# ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=
# ======================================================================================================
# Active Storage Configuration - responsible for storing file uploads
# ======================================================================================================
#
# * Defaults to disk storage but you can also use Amazon S3, Cloudflare R2, or Google Cloud Storage
# * Set the appropriate environment variables to use these services.
# * Ensure libvips is installed on your system for image processing - https://github.com/libvips/libvips
#
# Amazon S3
# ==========
# ACTIVE_STORAGE_SERVICE=amazon <- Enables Amazon S3 storage
# S3_ACCESS_KEY_ID=
# S3_SECRET_ACCESS_KEY=
# S3_REGION= # defaults to `us-east-1` if not set
# S3_BUCKET=
#
# Cloudflare R2
# =============
# ACTIVE_STORAGE_SERVICE=cloudflare <- Enables Cloudflare R2 storage
# CLOUDFLARE_ACCOUNT_ID=
# CLOUDFLARE_ACCESS_KEY_ID=
# CLOUDFLARE_SECRET_ACCESS_KEY=
# CLOUDFLARE_BUCKET=
#
# Generic S3
# ==========
# ACTIVE_STORAGE_SERVICE=generic_s3 <- Enables Generic S3 storage
# GENERIC_S3_ACCESS_KEY_ID=
# GENERIC_S3_SECRET_ACCESS_KEY=
# GENERIC_S3_REGION=
# GENERIC_S3_BUCKET=
# GENERIC_S3_ENDPOINT=
# GENERIC_S3_FORCE_PATH_STYLE= <- defaults to false
#
# Google Cloud Storage
# ====================
# ACTIVE_STORAGE_SERVICE=google <- Enables Google Cloud Storage
# GCS_PROJECT=
# GCS_BUCKET=
# GCS_KEYFILE_JSON= <- JSON content of service account key (preferred)
# GCS_KEYFILE= <- path to service account JSON key file
# Skylight
# ========
SKYLIGHT_AUTHENTICATION=
SKYLIGHT_ENABLED=