Configuration Overview
Fystack's main configuration lives in ./dev/config.yaml. This page explains every section, highlighting what's mandatory vs optional.
Quick Reference
| Field | Required? | Notes |
|---|---|---|
price_providers.coinmarketcap.api_key | Mandatory | Get from CoinMarketCap |
encryption_key | Pre-set (replace for production) | 16-byte hex key |
jwt.secret | Pre-set | Can customize, 16-byte hex |
integrity.signer.ed25519.private_key | Auto-generated | Generated by setup-nodes.sh |
mpc.signer.local.pk_raw | Auto-generated | Generated by setup-nodes.sh |
email.resend_api_key | Optional | Required only for email invitations |
cors.allow_origins | Must match frontend URL | Critical for VPS deployments |
cookie.same_site | Default: strict | May need none for cross-domain setups |
networks.* | Pre-configured | Testnets enabled by default |
Full Configuration Walkthrough
App URLs
app:
root_url: http://localhost:5174
sign_in_url: http://localhost:5174/auth
sign_up_url: http://localhost:5174/auth/sign-up
workspace_url: http://localhost:5174/auth/workspace
checkout_url: http://localhost:5174/checkout
reset_url: http://localhost:5174/auth/reset-password
email_verification_url: http://localhost:5174/auth/verify-email
cli_auth_url: http://localhost:5174/auth/cli
These URLs are used for email templates (password reset, invitations). For local development, the defaults work fine. For VPS deployments, update these to match your frontend domain.
When deploying to a VPS, update all app.* URLs to your frontend domain (e.g., https://app.yourdomain.com). These appear in email links sent to users.
Database Configuration
db:
postgres:
host: "postgres"
user: "postgres"
dbname: "custody"
port: 5432
password: "mysecretpassword"
sslmode: ""
mongo:
dsn: "mongodb://admin:password@mongo:27017"
database: "apex"
For the default Docker Compose setup, these values work as-is — they reference service names within the Docker network. For production, change passwords and consider enabling SSL.
Redis
redis:
address: "redis:6379"
password: "6s9H5G9o4p5Fz25K9RyWd6eOryU8nQ"
Pre-configured for the Docker Compose setup. The password matches the REDIS_ARGS in docker-compose.yaml.
CORS Configuration
cors:
allow_origins: http://localhost:8015
This must match the URL where your Fystack UI is accessible. If the UI is at https://app.yourdomain.com, set:
cors:
allow_origins: https://app.yourdomain.com
Mismatched CORS origins are the #1 cause of errors in VPS deployments. See Troubleshooting for details.
Cookie Configuration
cookie:
same_site: strict
Controls the SameSite attribute on authentication cookies.
| Value | When to Use |
|---|---|
strict | Frontend and API on the same domain or subdomains of the same domain. Works for localhost (localhost:8015 + localhost:8150) and subdomain setups (app.fystack.io + api.fystack.io). Recommended for most setups. |
none | Frontend and API on completely different root domains (e.g., myapp.com and api.otherdomain.com) — requires HTTPS |
Keep strict for most deployments. Browsers consider subdomains of the same root domain (e.g., app.yourdomain.com and api.yourdomain.com) as "same-site", so strict works perfectly.
Only use none if your frontend and API are on entirely different root domains, and it requires HTTPS.
JWT Secret
jwt:
secret: a9cb1255ea2bb890cc79c12a4fb93499
Used to sign authentication tokens. The default value works for testing. For production, generate a new one:
openssl rand -hex 16
Encryption Key
encryption_key: 82441c6785f53e02dbf97db9db2107ad
A 16-byte hex key used to encrypt sensitive data at rest. The template includes a default value that works for testing. For production, generate your own:
openssl rand -hex 16
Then update both config.yaml and the ENCRYPTION_KEY environment variable in docker-compose.yaml:
# docker-compose.yaml → apex service
environment:
- ENCRYPTION_KEY=your-new-key-here
If you lose this key, encrypted data in the database becomes unrecoverable. Back it up securely. If you change the key after data has been encrypted, that data will be unreadable.
Price Providers
price_providers:
dexscreener:
endpoint: "https://api.dexscreener.com/latest/dex/search"
coinmarketcap:
endpoint: "https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest"
api_key: "" # MANDATORY - add your key here
codex:
endpoint: "https://graph.defined.fi/graphql"
api_key: "" # Optional
- CoinMarketCap: Mandatory. Fystack uses this for token pricing. Free tier works.
- DexScreener: Pre-configured, no API key needed.
- Codex: Optional, for on-chain price data from DeFi pools.
Network Configuration
EVM, Solana, and Tron chains use different configuration formats in config.yaml. Make sure you use the correct structure for each chain type.
The network key (e.g., ETHER_SEPOLIA_TESTNET) is the internal_code. It must match what you configure in the Fystack UI when creating networks.
EVM Chains
EVM chains use the providers field with http and wss endpoints:
networks:
ETHER_SEPOLIA_TESTNET:
enabled: true
wss_enabled: true
providers:
- name: "alchemy"
http: "https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY"
wss: "wss://eth-sepolia.g.alchemy.com/v2/YOUR_KEY"
# Backup RPC for failover
- name: "publicnode"
http: "https://ethereum-sepolia-rpc.publicnode.com"
wss: "wss://ethereum-sepolia-rpc.publicnode.com"
BASE_SEPOLIA_TESTNET:
enabled: true
wss_enabled: false # Disable to save RPC costs, rely on multichain indexer
providers:
- name: "publicnode"
http: "https://base-sepolia-rpc.publicnode.com"
wss_enabled controls whether Apex subscribes to new blocks via WebSocket for real-time indexing. Set to false if you want to rely on the multichain indexer instead, which saves RPC costs. See the Transaction Indexer section for details.
Solana
Solana uses the rpc_nodes field:
networks:
SOL_DEVNET:
enabled: true
rpc_nodes:
- url: "https://api.devnet.solana.com"
SOL_MAINNET:
enabled: false
rpc_nodes:
- url: "https://api.mainnet-beta.solana.com"
# Backup RPC
- url: "https://solana-mainnet.g.alchemy.com/v2/YOUR_KEY"
Tron
Tron also uses rpc_nodes. For mainnet, the TronGrid API requires an API key passed via headers:
networks:
TRON_SHASTA_TESTNET:
enabled: true
rpc_nodes:
- url: "https://api.shasta.trongrid.io/"
TRON_MAINNET:
enabled: true
rpc_nodes:
- url: "https://api.trongrid.io/"
headers:
TRON-PRO-API-KEY: "your-trongrid-api-key"
Tron mainnet requires a TronGrid Pro API key. Sign up at trongrid.io to get one. Without it, requests will be rate-limited.
Backup RPCs for Reliability
You can add multiple providers or RPC nodes per network. Fystack will failover to backup endpoints if the primary is unavailable:
networks:
# EVM: add multiple providers
ETHER_MAINNET:
enabled: true
wss_enabled: true
providers:
- name: "alchemy"
http: "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"
wss: "wss://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"
- name: "infura"
http: "https://mainnet.infura.io/v3/YOUR_KEY"
wss: "wss://mainnet.infura.io/ws/v3/YOUR_KEY"
- name: "publicnode"
http: "https://ethereum-rpc.publicnode.com"
# Solana: add multiple rpc_nodes
SOL_MAINNET:
enabled: true
rpc_nodes:
- url: "https://solana-mainnet.g.alchemy.com/v2/YOUR_KEY"
- url: "https://api.mainnet-beta.solana.com"
This improves resilience during RPC outages — if one provider goes down, Fystack automatically uses the next available endpoint.
Network Configuration Reference
| Field | Chain Types | Description |
|---|---|---|
enabled | All | Whether the network is active |
wss_enabled | EVM only | Subscribe to new blocks via WebSocket. Disable to save RPC costs. |
providers | EVM only | List of RPC providers with name, http, and optional wss |
rpc_nodes | Solana, Tron | List of RPC endpoints with url and optional headers |
To add a new chain:
- Add it to
config.yamlundernetworks:using the correct format for the chain type - In the Fystack UI, create a new network with the same
internal_code - If using the multichain indexer, also add it to
config.indexer.yaml— see Multichain Indexer - Recreate Apex:
docker compose -f ./dev/docker-compose.yaml up -d --force-recreate apex
MPC Signer
mpc:
signer:
type: "local"
local:
pk_raw: "" # Auto-populated by setup-nodes.sh
encrypted_pk_path: "event_initiator.key.age"
encrypted_pk_password: ""
The event initiator private key, used by Apex to sign MPC session requests. This is auto-generated by setup-nodes.sh during fystack-ignite.sh — you don't need to set it manually.
Integrity Signer
integrity:
signer:
version: 1
type: "ed25519"
ed25519:
private_key: "" # Auto-generated by setup-nodes.sh
Used for data integrity verification. The ed25519 seed is auto-generated by setup-nodes.sh. To generate manually:
openssl rand -hex 32
Email Configuration
email:
resend_api_key: "<API_KEY>"
sender_name: "Fystack"
sender_email: "noreply@fystack.io"
Fystack uses Resend for transactional emails (invitations, password resets).
- For testing: You can skip this. Signup works without email verification in the default setup.
- For production: Create a Resend account, get an API key, and configure your sender domain.
OAuth2 (Optional)
oauth2:
google:
client_id: "..."
client_secret: "..."
callback_url: "http://localhost:8150/api/v1/authentication/google/callback"
Optional Google OAuth integration. Replace with your Google Cloud OAuth credentials if you want Google sign-in. Update callback_url for VPS deployments.
Telegram Alerts (Optional)
telegram:
bot_token: ""
long_polling: true
bot_name: "<Your bot name>"
Optional Telegram bot for system alerts. Create a bot via @BotFather and add the token here.
Logging
logging:
mode: "stdout" # Options: "file", "stdout", "both"
format: "json" # Options: "json", "pretty"
blockchain:
enabled: true
stdout: true
api:
enabled: true
stdout: true
Controls log output. For debugging, use format: "pretty" for human-readable logs.
System Admins
system_admins:
- "admin@yourcompany.com"
Email addresses that will have system administrator privileges. Update this with your actual admin emails.
Other Configuration Files
config.indexer.yaml
Configures the multichain indexer. Key fields:
chains:
tron_testnet:
network_id: "bc75c4b8-f7b6-4f2f-a79a-5d3a7084f0c1"
internal_code: "TRON_SHASTA_TESTNET" # Must match config.yaml
type: "tron"
start_block: 58083393
nodes:
- url: "https://api.shasta.trongrid.io/"
The internal_code must match the network key in config.yaml and the network created in the Fystack UI.
config.rescanner.yaml
Configures the rescanner for Solana block gap recovery:
networks:
SOL_DEVNET:
enabled: true
id: "2e89cd02-8585-47b3-90e3-a92185f6ca5f"
name: "Solana devnet"
rpcnodes:
- url: "https://api.devnet.solana.com"
Next Steps
- VPS Deployment — Deploy to a remote server
- Reverse Proxy — Set up nginx, SSL, and CORS for production