Node configuration
A Demos node is configured almost entirely from a single.env file. The repo ships .env.example as the canonical template:
./run, advanced), two settings differ — see Track-specific overrides below.
Track-specific overrides
| Variable | Track 1 (Docker Compose) | Track 2 (bare metal ./run) |
|---|---|---|
PG_HOST | postgres (in-network service name) | localhost |
PG_PORT | 5432 (container-internal) | 5332 (host-mapped from the sidecar) |
TLSNOTARY_HOST | tlsnotary (in-network service name) | localhost |
.env is shared between the two tracks.
Consensus and governance
| Variable | Default | Notes |
|---|---|---|
CONSENSUS_TIME | 10 | Block production interval in seconds. Lower = faster blocks, higher CPU. |
RPC_FEE | 1 | Per-tx fee component. |
NETWORK_FEE | 1 | Per-tx fee component. |
BURN_FEE | 1 | Per-tx fee component (burned). Total per-tx flat fee = RPC_FEE + NETWORK_FEE + BURN_FEE. |
MIN_VALIDATOR_STAKE | 1000000000000000000 | Minimum stake to become a validator (raw bigint as string, must fit Postgres int64 ≤ 9.2e18). |
Network and ports
| Variable | Default | Notes |
|---|---|---|
RPC_PORT | 53550 | Main HTTP RPC listen port. |
EXPOSED_URL | http://localhost:53550 | Public URL advertised to peers and SDK clients. Loopback default is fine for local dev — set to your reachable address before joining a real network. |
OMNI_ENABLED | true | Toggle the OmniProtocol binary RPC server. |
OMNI_PORT | 53551 | OmniProtocol TCP server port (auto-derived as RPC_PORT + 1 if unset). |
OMNI_MODE | OMNI_PREFERRED | One of HTTP_ONLY, OMNI_PREFERRED, OMNI_ONLY. |
RPC_SIGNALING_PORT | 3005 | WebRTC signaling server port (peer discovery handshake for legacy MessagingPeer). |
RPC_MCP_PORT | 3001 | MCP (Model Context Protocol) server port for AI agent integrations. |
Database (PostgreSQL)
| Variable | Default | Notes |
|---|---|---|
PG_HOST | postgres | Track 1: in-network service name. Track 2: set to localhost. |
PG_PORT | 5432 | Track 1: container-internal. Track 2: set to 5332 (the host-mapped port the ./run sidecar uses). |
PG_USER | demosuser | |
PG_PASSWORD | demospassword | Change before sharing the host. |
PG_DATABASE | demos |
Identity and peers
| Variable | Default | Notes |
|---|---|---|
IDENTITY_FILE | .demos_identity | Path to the node’s ed25519 identity keypair. Auto-generated on first boot. Under Track 1 the entrypoint persists this into demos_node_state so it survives container recreation. |
PEER_LIST_FILE | demos_peerlist.json | Cached peer list. Same persistence treatment as the identity file. |
.demos_identity is the single most important file to back up.
TLSNotary
TLSNotary provides cryptographic attestation of HTTPS responses.| Variable | Default | Notes |
|---|---|---|
TLSNOTARY_ENABLED | true | Set to false to skip TLSNotary entirely. |
TLSNOTARY_HOST | tlsnotary | Track 1: in-network service name. Track 2: set to localhost. |
TLSNOTARY_PORT | 7047 | Attestation server port. |
TLSNOTARY_MODE | docker | docker (sidecar container) or ffi (in-process Rust binding). |
TLSNOTARY_FATAL | false | If true, TLSNotary failures crash the node. Keep false for graceful degradation. |
TLSNOTARY_SIGNING_KEY | (empty) | Leave empty in default Docker mode — the sidecar manages its own key. Only set when TLSNOTARY_MODE=ffi (64-char hex secp256k1 key, or empty to auto-generate into .tlsnotary-key). |
TLSNOTARY_ENABLED aligned with the tlsnotary profile in COMPOSE_PROFILES — enabling one without the other produces noisy warnings.
Monitoring
| Variable | Default | Notes |
|---|---|---|
METRICS_ENABLED | true | Exposes Prometheus metrics at http://<node>:<METRICS_PORT>/metrics. |
METRICS_PORT | 9090 | Container-internal port. Pinned to 9090 in compose to match the static scrape target in monitoring/prometheus/prometheus.yml. Override only on bare metal. |
METRICS_HOST | 0.0.0.0 | Bind address. |
METRICS_HOST_PORT | 9090 | Host-mapped port for the metrics endpoint (Track 1 only). Set this if 9090 is already taken on the host. |
GRAFANA_PORT | 3000 | Dashboard UI port. |
GRAFANA_ADMIN_USER | admin | |
GRAFANA_ADMIN_PASSWORD | demos | Change this before opening Grafana to anything outside your machine. |
PROMETHEUS_PORT | 9091 | Prometheus server external (host-mapped) port. Internal stays 9090. |
Logging and runtime
| Variable | Default | Notes |
|---|---|---|
LOG_LEVEL | info | One of debug, info, warning, error, critical. debug produces a wall of per-block consensus JSON — only enable when actually debugging. |
PROD | false | Set true in production (enables DTR production relay and prod-only safety checks). |
L2PS_ZK_ENABLED | false | Advanced: enable ZK proofs in the L2PS layer. Experimental. |
Docker Compose only
These variables are consumed bydocker-compose.yml and not by the node binary itself, so they only matter on Track 1.
| Variable | Default | Notes |
|---|---|---|
COMPOSE_PROFILES | monitoring,tlsnotary | Comma-separated list of profiles to bring up. Empty = bare minimum (postgres + node). Other profiles: full (adds node-exporter for host metrics), neo4j (only for CGC/KYC features). |
IMAGE_NAME | demos-node | Image name. Override to pull a pre-built image (e.g. ghcr.io/kynesyslabs/node). |
IMAGE_TAG | local | Image tag. |
Optional external API keys
.env.example ships with these commented out. Uncomment only the ones you need; each unlocks a specific feature:
| Variable | Used by |
|---|---|
SOLANA_RPC | Solana RPC endpoint override (default: public mainnet RPC) |
ETHERSCAN_API_KEY | EVM block explorer queries |
HELIUS_API_KEY | Solana enhanced RPC (NFTs, DAS API) |
NOMIS_API_KEY / NOMIS_CLIENT_ID | On-chain reputation scoring |
RAPID_API_KEY | Various enrichment routes |
GITHUB_TOKEN | GitHub-based identity attestations |
DISCORD_BOT_TOKEN | Discord-based identity attestations |
HUMAN_PASSPORT_API_KEY | Sybil resistance scoring (Gitcoin Passport) |
Generating your identity
You do not configure the node’s keypair manually. On first boot the node:- Generates a fresh ed25519 keypair.
- Writes the private key to
IDENTITY_FILE(default.demos_identity). - Writes the public key to a file named
publickey_<timestamp>in the same directory and prints it to the console.
Configuring the peerlist
demos_peerlist.json lists known peers as { "<publicKey>": "<url>" }. Copy the example and edit it: