mirror of
https://github.com/Routstr/routstr-core.git
synced 2026-08-09 02:54:37 +00:00
Add DATABASE_POOL_SIZE / DATABASE_MAX_OVERFLOW / DATABASE_POOL_TIMEOUT, consumed like every other typed env var through the pydantic Settings (constrained Fields, defaults 5/10/30 matching SQLAlchemy's own baseline so leaving them unset is behaviour-neutral). An out-of-range or non-integer value fails validation and refuses to boot — the same fail-loud behaviour a malformed DATABASE_URL already has — rather than silently starting up misconfigured. create_db_engine sizes the pool from these and logs the effective values at startup so they can be confirmed from the boot output during an incident. In-memory SQLite (StaticPool, which rejects the pool kwargs) is detected and built without them. pool_pre_ping is deliberately not exposed: the default backend is a local SQLite file with no network peer to drop idle connections, so it would add a SELECT 1 per checkout for no benefit — and it detects dead connections, not the live-but-wedged ones behind the exhaustion this series addresses. These knobs are infrastructure the node needs before it can open a DB session, so they can never be sourced from the DB (chicken-and-egg). A new ENV_ONLY_FIELDS set keeps them out of the persisted settings blob and stops a DB value from shadowing env in both SettingsService.initialize and .update, so env stays authoritative. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
92 lines
4.0 KiB
Bash
92 lines
4.0 KiB
Bash
# Core Configuration
|
|
UPSTREAM_BASE_URL=https://api.openai.com/v1
|
|
UPSTREAM_API_KEY=your-upstream-api-key
|
|
|
|
# Tinfoil (confidential inference enclaves, EHBP)
|
|
# TINFOIL_API_KEY=your-tinfoil-api-key
|
|
|
|
# Secret key used to encrypt node secrets at rest (optional). If unset, the node
|
|
# generates one on first start, writes it to routstr_secret.key (override the path
|
|
# with ROUTSTR_SECRET_KEY_FILE), and prints it once — back that file up, because
|
|
# losing the key makes previously encrypted secrets unreadable. Set it explicitly
|
|
# to manage the key yourself (recommended in production). Generate one with:
|
|
# uv run python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
|
|
ROUTSTR_SECRET_KEY=
|
|
|
|
# The admin password and the Nostr identity (nsec) are NOT set here. The admin
|
|
# password is generated and logged once on first start (read it from the logs to
|
|
# sign in); both are managed afterwards from the admin UI and stored encrypted in
|
|
# the database. ADMIN_PASSWORD / NSEC are still read once as a legacy seed for
|
|
# existing deployments, but new nodes should set them in the UI — a value left in
|
|
# .env is ignored once the node has been configured.
|
|
|
|
# Database
|
|
# DATABASE_URL=sqlite+aiosqlite:///keys.db
|
|
|
|
# Database tuning (advanced — you almost certainly do not need these)
|
|
# ---------------------------------------------------------------------------
|
|
# These size the SQLAlchemy connection pool. The defaults below match
|
|
# SQLAlchemy's own baseline, so leaving them unset changes nothing. Touch them
|
|
# ONLY if the logs show the pool running out of connections:
|
|
#
|
|
# QueuePool limit of size 5 overflow 10 reached, connection timed out, timeout 30.00
|
|
#
|
|
# The effective values are printed at startup ("Database pool configured: ...")
|
|
# so you can confirm what is actually in effect while diagnosing an incident.
|
|
# An invalid value (non-integer, or a pool size below 1) stops the node at boot
|
|
# with a clear error rather than starting up misconfigured.
|
|
#
|
|
# DATABASE_POOL_SIZE Connections kept open in the pool. (default 5)
|
|
# DATABASE_MAX_OVERFLOW Extra connections opened under load, (default 10)
|
|
# beyond pool_size, then discarded.
|
|
# DATABASE_POOL_TIMEOUT Seconds a request waits for a free (default 30)
|
|
# connection before failing with the error above.
|
|
#
|
|
# Note for the default SQLite backend: SQLite serialises writes behind a single
|
|
# database-level lock, so a bigger pool does NOT buy more write throughput — it
|
|
# only lets more readers run at once (WAL mode) and trades pool-timeout errors
|
|
# for "database is locked" errors. If you exhaust the pool on SQLite, the cause
|
|
# is almost always connections being held too long, not the pool being too
|
|
# small. These knobs come into their own if you point DATABASE_URL at a
|
|
# networked database (e.g. Postgres), where connections genuinely run in
|
|
# parallel; there, size the pool against the server's max_connections.
|
|
#
|
|
# DATABASE_POOL_SIZE=5
|
|
# DATABASE_MAX_OVERFLOW=10
|
|
# DATABASE_POOL_TIMEOUT=30
|
|
|
|
# Node Information
|
|
# NAME=My Routstr Node
|
|
# DESCRIPTION=Fast AI API access with Bitcoin payments
|
|
# HTTP_URL=https://api.mynode.com
|
|
# ONION_URL=http://mynode.onion (auto fetched from compose)
|
|
# RELAYS="wss://relay.damus.io,wss://relay.nostr.band,wss://eden.nostr.land,wss://relay.routstr.com"
|
|
# ENABLE_ANALYTICS_SHARING=true
|
|
# CASHU_MINTS="https://mint.minibits.cash/Bitcoin,https://mint.cubabitcoin.org,https://ecashmint.otrta.me"
|
|
# RECEIVE_LN_ADDRESS=
|
|
|
|
# Custom Pricing Configuration
|
|
# MODEL_BASED_PRICING=true
|
|
# COST_PER_REQUEST=1
|
|
# COST_PER_1K_INPUT_TOKENS=0
|
|
# COST_PER_1K_OUTPUT_TOKENS=0
|
|
# EXCHANGE_FEE=1.005
|
|
# UPSTREAM_PROVIDER_FEE=1.05
|
|
|
|
# Network Configuration
|
|
# CORS_ORIGINS=*
|
|
# TOR_PROXY_URL=socks5://127.0.0.1:9050
|
|
|
|
# Logging
|
|
# LOG_LEVEL=INFO
|
|
# ENABLE_CONSOLE_LOGGING=true
|
|
|
|
# Custom Model Management
|
|
# BASE_URL=https://openrouter.ai/api/v1
|
|
# MODELS_PATH=models.json
|
|
# SOURCE=
|
|
|
|
# UI Configuration (for Next.js frontend)
|
|
# These variables are prefixed with NEXT_PUBLIC_ to be accessible in the browser
|
|
# NEXT_PUBLIC_API_URL=http://127.0.0.1:8000
|