Files
routstr-core/.env.example

143 lines
6.3 KiB
Bash

# Core Configuration
# Upstream providers belong to the dashboard (Providers page). Leave this pair
# commented on a fresh node: a non-empty UPSTREAM_BASE_URL + UPSTREAM_API_KEY here
# seeds an enabled "custom" provider on the node's very first boot, and the value
# is then saved in Settings — so it survives later .env edits and comes back if
# the provider list is ever emptied again.
# 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 logs a one-time notice naming it — back that
# file up: it decrypts the auto-created Nostr nsec and other node secrets, and if
# it is lost they cannot be recovered. Set it explicitly (and keep it stable) to
# manage the key yourself, e.g. from a secrets manager. 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.
# Self-provision a Nostr identity on first boot when none is configured, so the
# node can announce itself without anyone pasting an nsec. The generated nsec is
# stored encrypted and never printed; only its npub is logged. Retrieve it with
# `python scripts/reveal_nsec.py` (needs ROUTSTR_SECRET_KEY). A provided NSEC
# still wins. The compose.node.yml first-run stack enables this by default.
# AUTO_GENERATE_NSEC=true
# Database
# DATABASE_URL=sqlite+aiosqlite:///keys.db
# PostgreSQL through compose.postgres.yml (opt-in, layered on compose.yml or
# compose.node.yml): it builds DATABASE_URL from these, so keep the password
# URL-safe, e.g. `openssl rand -hex 32`.
# POSTGRES_USER=routstr
# POSTGRES_PASSWORD=
# POSTGRES_DB=routstr
# Make every `docker compose` command without `-f` include PostgreSQL. An
# explicit `-f` replaces this: naming only compose.node.yml or compose.yml starts
# the node on an empty SQLite database even when COMPOSE_FILE is set. Use
# compose.yml:compose.postgres.yml on the standard stack.
# COMPOSE_FILE=compose.node.yml:compose.postgres.yml
# One-time import of a SQLite database into an empty PostgreSQL DATABASE_URL at
# startup; afterwards the file is renamed to <name>.imported-<timestamp> and later
# starts skip the copy. compose.postgres.yml defaults it to /app/keys.db; set it
# to an empty value to turn the import off.
# SQLITE_IMPORT_PATH=keys.db
# Pool controls are validated at boot, sourced only from the environment, and
# logged at startup. Keep total capacity across all workers below the database
# connection limit. Pre-ping is automatic for networked backends; SQLite may
# explicitly opt in if desired.
# DATABASE_POOL_SIZE=10
# DATABASE_MAX_OVERFLOW=20
# DATABASE_POOL_TIMEOUT=30
# DATABASE_POOL_RECYCLE=1800
# DATABASE_POOL_PRE_PING=false
# Warn when a checkout is held this many seconds.
# DATABASE_POOL_HOLD_WARN_SECONDS=10
# SQLite write-lock timeout, in seconds.
# DATABASE_BUSY_TIMEOUT=30
# SQLite serialises writes; increasing its pool can trade pool timeouts for
# "database is locked" errors rather than increasing write throughput.
# Node Information
# NAME=My Routstr Node
# DESCRIPTION=Fast AI API access with Bitcoin payments
# Publish to Nostr once this public HTTPS origin (or an onion URL) is set; leave
# unset to keep the node loopback-only and unpublished.
# 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" # this is the default
# CASHU_MINTS="https://mint.minibits.cash/Bitcoin,https://mint.cubabitcoin.org,https://ecashmint.otrta.me"
# MINT_OPERATION_CONCURRENCY=4
# MINT_OPERATION_TIMEOUT_SECONDS=30
# MINT_MAX_CONCURRENCY=4
# MINT_RETRY_MAX_ATTEMPTS=3
# Foreign top-up tokens are swapped into the first CASHU_MINTS entry over Lightning.
# Its unit is discovered from active keysets and enabled NUT-04/NUT-05 Bolt11 methods.
# FOREIGN_MINT_OPERATION_TIMEOUT_SECONDS=5
# FOREIGN_MINT_MELT_TIMEOUT_SECONDS=60
# FOREIGN_MINT_MAX_CONCURRENCY=4
# SWAP_RECONCILE_INTERVAL_SECONDS=60
# Payout Lightning address (user@host, lnurl1..., or an https:// LNURL-pay URL).
# Leave unset to accept payments without withdrawing; the payout loop then idles.
# RECEIVE_LN_ADDRESS=
# REFUND_SWEEP_CLAIM_TIMEOUT_SECONDS=900
# 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
# PROXY_EXTRA_ALLOWED_PATHS=
# Upstream Connection Pools (one pool per upstream origin)
# UPSTREAM_MAX_CONNECTIONS=200
# UPSTREAM_POOL_TIMEOUT=5
# UPSTREAM_READ_TIMEOUT=900
# Upstream Streaming Guards (0 disables; keep above reasoning models' think time)
# UPSTREAM_FIRST_TOKEN_TIMEOUT_SECONDS=0
# UPSTREAM_STREAM_IDLE_TIMEOUT_SECONDS=0
# UPSTREAM_ALLOWED_FAILS=3
# UPSTREAM_COOLDOWN_SECONDS=30
# Image generation: most USD (fee included) one request may be quoted at
# (0 = no limit), and most bytes a buffered image response may carry.
# IMAGE_MAX_REQUEST_USD=0
# IMAGE_MAX_RESPONSE_BYTES=41943040
# Request and reservation lifetime limits (seconds)
# STALE_RESERVATION_TIMEOUT_SECONDS=300
# MAX_REQUEST_LIFETIME_SECONDS=1800
# DOWNSTREAM_SEND_TIMEOUT_SECONDS=60
# REQUEST_CLEANUP_TIMEOUT_SECONDS=30
# 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