Skip to main content
Fluxer is configured via a JSON file that follows a strict schema. This page documents all available configuration options.

Configuration File Location

By default, Fluxer looks for the configuration at:
# Docker deployment
/usr/src/app/config/config.json

# Specify custom location via environment variable
export FLUXER_CONFIG=/path/to/config.json

Core Configuration

Environment

Controls runtime behavior and logging verbosity.
{
  "env": "production"
}
env
string
required
Runtime environment. Options: development, production, test.
  • development: Verbose logging, relaxed security
  • production: Optimized for performance, strict security
  • test: Used for automated testing

Domain Configuration

Defines how Fluxer constructs public URLs for all services.
{
  "domain": {
    "base_domain": "chat.example.com",
    "public_scheme": "https",
    "public_port": 443,
    "internal_scheme": "http",
    "internal_port": 8080,
    "static_cdn_domain": "cdn.example.com",
    "invite_domain": "invite.example.com",
    "gift_domain": "gift.example.com"
  }
}
base_domain
string
required
Primary domain name for your instance (e.g., chat.example.com or localhost).
public_scheme
string
default:"http"
Public URL scheme. Use https in production.
public_port
number
default:"8088"
Public-facing port. Use 443 for HTTPS, 80 for HTTP.
static_cdn_domain
string
default:"fluxerstatic.com"
Optional separate domain for serving static assets.
invite_domain
string
Custom domain for short invite links (e.g., fluxer.gg).

Database Configuration

Fluxer supports SQLite (single-node) and Cassandra (distributed) backends.

SQLite (Default)

Recommended for deployments under 10,000 users.
{
  "database": {
    "backend": "sqlite",
    "sqlite_path": "./data/fluxer.db"
  }
}
backend
string
required
Database backend. Options: sqlite, cassandra.
sqlite_path
string
default:"./data/fluxer.db"
Path to SQLite database file. Created automatically if it doesn’t exist.

Cassandra (Distributed)

For large-scale deployments requiring high availability.
{
  "database": {
    "backend": "cassandra",
    "cassandra": {
      "hosts": ["cassandra-node-1", "cassandra-node-2", "cassandra-node-3"],
      "keyspace": "fluxer",
      "local_dc": "dc1",
      "username": "cassandra",
      "password": "your-cassandra-password"
    }
  }
}
cassandra.hosts
array
required
Array of Cassandra contact points (hostnames or IPs).
cassandra.keyspace
string
required
Cassandra keyspace name (must be created beforehand).
cassandra.local_dc
string
required
Local datacenter name for topology-aware routing.
cassandra.username
string
required
Cassandra authentication username.
cassandra.password
string
required
Cassandra authentication password.

Internal Services

Configuration for internal service-to-service communication.
{
  "internal": {
    "kv": "redis://valkey:6379/0",
    "kv_mode": "standalone",
    "queue": "http://localhost:8088/queue",
    "media_proxy": "http://localhost:8088/media"
  }
}
kv
string
default:"redis://localhost:6379/0"
Redis/Valkey connection URL for caching and coordination.
kv_mode
string
default:"standalone"
Connection mode: standalone or cluster.
kv_cluster_nodes
array
For cluster mode: array of {host, port} objects.
"kv_cluster_nodes": [
  {"host": "redis-1", "port": 6379},
  {"host": "redis-2", "port": 6379},
  {"host": "redis-3", "port": 6379}
]

S3 Storage Configuration

Fluxer stores uploaded media in S3-compatible object storage.
{
  "s3": {
    "endpoint": "http://127.0.0.1:8080/s3",
    "region": "us-east-1",
    "access_key_id": "your-access-key",
    "secret_access_key": "your-secret-key",
    "presigned_url_base": "https://cdn.example.com",
    "buckets": {
      "cdn": "fluxer",
      "uploads": "fluxer-uploads",
      "downloads": "fluxer-downloads",
      "reports": "fluxer-reports",
      "harvests": "fluxer-harvests"
    }
  }
}
endpoint
string
required
S3 endpoint URL. Use built-in storage (http://127.0.0.1:8080/s3) or external provider.
access_key_id
string
required
S3 access key ID.
secret_access_key
string
required
S3 secret access key.
presigned_url_base
string
Public base URL for presigned download links. Set this when endpoint is internal.

Service Configuration

Server Service

Main HTTP server configuration.
{
  "services": {
    "server": {
      "port": 8080,
      "host": "0.0.0.0",
      "static_dir": "/usr/src/app/assets"
    }
  }
}
port
number
default:"8080"
HTTP port to listen on.
host
string
default:"0.0.0.0"
Network interface to bind to. Use 0.0.0.0 for all interfaces.

Gateway Service (WebSocket)

Real-time WebSocket gateway configuration.
{
  "services": {
    "gateway": {
      "port": 8082,
      "admin_reload_secret": "your-reload-secret",
      "media_proxy_endpoint": "http://127.0.0.1:8080/media",
      "logger_level": "info",
      "push_enabled": true,
      "presence_shards": 1,
      "guild_shards": 1
    }
  }
}
admin_reload_secret
string
required
Secret used to trigger hot code reloads (Erlang OTP feature).
logger_level
string
default:"info"
Erlang logger level: debug, info, warn, error.
push_enabled
boolean
default:"true"
Enable push notification delivery through the gateway.
presence_shards
number
default:"1"
Number of shards for presence tracking. Increase for high concurrency.

Media Proxy Service

Handles image/video processing and proxying.
{
  "services": {
    "media_proxy": {
      "secret_key": "your-64-char-hex-secret",
      "require_cloudflare_edge": false,
      "rate_limit": {
        "limit": 1000,
        "window_ms": 60000
      }
    }
  }
}
secret_key
string
required
Secret key for signing media URLs. Generate with openssl rand -hex 32.
require_cloudflare_edge
boolean
default:"false"
Require requests to originate from Cloudflare edge IPs.

Admin Panel

Configuration for the admin dashboard.
{
  "services": {
    "admin": {
      "port": 3001,
      "secret_key_base": "your-64-char-hex-secret",
      "oauth_client_secret": "your-oauth-secret",
      "base_path": "/admin"
    }
  }
}
secret_key_base
string
required
Base secret for signing admin session tokens.
oauth_client_secret
string
required
OAuth client secret for admin authentication.

NATS (Microservices Mode)

Required only in microservices deployment mode.
{
  "services": {
    "nats": {
      "core_url": "nats://nats:4222",
      "jetstream_url": "nats://nats:4222",
      "auth_token": "your-nats-token"
    }
  }
}

Authentication Configuration

{
  "auth": {
    "sudo_mode_secret": "your-64-char-hex-secret",
    "connection_initiation_secret": "your-64-char-hex-secret",
    "vapid": {
      "public_key": "your-vapid-public-key",
      "private_key": "your-vapid-private-key",
      "email": "[email protected]"
    },
    "passkeys": {
      "rp_name": "Fluxer",
      "rp_id": "chat.example.com"
    },
    "bluesky": {
      "enabled": true,
      "client_name": "Fluxer",
      "keys": []
    }
  }
}
sudo_mode_secret
string
required
Secret for verifying elevated permission tokens.
vapid
object
required
VAPID keys for Web Push notifications. Generate with npx web-push generate-vapid-keys.
passkeys.rp_id
string
Relying party ID for WebAuthn (typically your domain).

Integrations

Email

SMTP configuration for sending verification codes and notifications.
{
  "integrations": {
    "email": {
      "enabled": true,
      "provider": "smtp",
      "from_email": "[email protected]",
      "from_name": "Fluxer",
      "smtp": {
        "host": "smtp.example.com",
        "port": 587,
        "username": "your-smtp-username",
        "password": "your-smtp-password",
        "secure": true
      }
    }
  }
}
Full-text search configuration.
{
  "integrations": {
    "search": {
      "engine": "meilisearch",
      "url": "http://meilisearch:7700",
      "api_key": "your-meilisearch-master-key"
    }
  }
}
engine
string
Search backend: meilisearch or elasticsearch.
Elasticsearch Configuration:
{
  "integrations": {
    "search": {
      "engine": "elasticsearch",
      "url": "http://elasticsearch:9200",
      "username": "elastic",
      "password": "your-es-password"
    }
  }
}

Voice & Video (LiveKit)

{
  "integrations": {
    "voice": {
      "enabled": true,
      "api_key": "your-livekit-api-key",
      "api_secret": "your-livekit-api-secret",
      "url": "wss://chat.example.com/livekit",
      "webhook_url": "https://chat.example.com/api/webhooks/livekit",
      "default_region": {
        "id": "default",
        "name": "Default Region",
        "emoji": "🌐",
        "latitude": 0.0,
        "longitude": 0.0
      }
    }
  }
}
default_region
object
Automatically creates this voice region on startup if none exist.
See Voice Setup for complete LiveKit configuration.

GIF Providers

{
  "integrations": {
    "gif": {
      "provider": "klipy"
    },
    "klipy": {
      "api_key": "your-klipy-api-key"
    },
    "tenor": {
      "api_key": "your-tenor-api-key"
    }
  }
}

CAPTCHA

{
  "integrations": {
    "captcha": {
      "enabled": true,
      "provider": "hcaptcha",
      "hcaptcha": {
        "site_key": "your-hcaptcha-site-key",
        "secret_key": "your-hcaptcha-secret-key"
      }
    }
  }
}
Supported providers: hcaptcha, turnstile, none.

ClamAV (Antivirus)

{
  "integrations": {
    "clamav": {
      "enabled": true,
      "host": "clamav",
      "port": 3310,
      "fail_open": true
    }
  }
}
fail_open
boolean
default:"true"
Allow file uploads if ClamAV scanning fails (recommended).

Instance Settings

{
  "instance": {
    "deployment_mode": "monolith",
    "self_hosted": true,
    "auto_join_invite_code": "",
    "private_key_path": "/usr/src/app/data/instance_key.pem"
  }
}
deployment_mode
string
default:"monolith"
Deployment architecture: monolith or microservices.
private_key_path
string
Path to x25519 private key for E2E encryption. Auto-generated if not specified.

Development Settings

These settings should never be enabled in production.
{
  "dev": {
    "disable_rate_limits": true,
    "relax_registration_rate_limits": true,
    "test_mode_enabled": false
  }
}
{
  "cookie": {
    "domain": ".example.com",
    "secure": true
  }
}
secure
boolean
default:"false"
Set Secure flag on cookies. Required for HTTPS deployments.

Proxy & IP Detection

{
  "proxy": {
    "trust_cf_connecting_ip": true
  }
}
trust_cf_connecting_ip
boolean
default:"false"
Trust Cloudflare’s CF-Connecting-IP header for real client IPs.

Observability

OpenTelemetry

{
  "telemetry": {
    "enabled": true,
    "otlp_endpoint": "http://otel-collector:4318",
    "service_name": "fluxer",
    "environment": "production",
    "trace_sampling_ratio": 0.1
  }
}

Sentry

{
  "sentry": {
    "enabled": true,
    "dsn": "https://[email protected]/project-id"
  }
}

Environment Variable Overrides

Some settings can be overridden with environment variables:
VariableDescription
FLUXER_CONFIGPath to config.json
NODE_ENVRuntime environment (overrides env in config)
PORTHTTP server port
HOSTHTTP server host

Configuration Validation

Fluxer validates your configuration against the JSON schema on startup:
# Validate config manually
npx ajv validate \
  -s packages/config/src/ConfigSchema.json \
  -d config/config.json

Complete Example

Here’s a complete production configuration:
{
  "$schema": "../packages/config/src/ConfigSchema.json",
  "env": "production",
  "domain": {
    "base_domain": "chat.example.com",
    "public_scheme": "https",
    "public_port": 443
  },
  "database": {
    "backend": "sqlite",
    "sqlite_path": "./data/fluxer.db"
  },
  "internal": {
    "kv": "redis://valkey:6379/0",
    "kv_mode": "standalone"
  },
  "s3": {
    "access_key_id": "minioadmin",
    "secret_access_key": "minioadmin",
    "endpoint": "http://127.0.0.1:8080/s3"
  },
  "services": {
    "server": {
      "port": 8080,
      "host": "0.0.0.0"
    },
    "media_proxy": {
      "secret_key": "a1b2c3d4e5f6..."
    },
    "admin": {
      "secret_key_base": "a1b2c3d4e5f6...",
      "oauth_client_secret": "a1b2c3d4e5f6..."
    },
    "marketing": {
      "enabled": false
    },
    "gateway": {
      "port": 8082,
      "admin_reload_secret": "a1b2c3d4e5f6...",
      "media_proxy_endpoint": "http://127.0.0.1:8080/media"
    }
  },
  "auth": {
    "sudo_mode_secret": "a1b2c3d4e5f6...",
    "connection_initiation_secret": "a1b2c3d4e5f6...",
    "vapid": {
      "public_key": "BG...",
      "private_key": "..."
    }
  },
  "integrations": {
    "email": {
      "enabled": true,
      "provider": "smtp",
      "from_email": "[email protected]",
      "smtp": {
        "host": "smtp.sendgrid.net",
        "port": 587,
        "username": "apikey",
        "password": "SG...",
        "secure": true
      }
    },
    "search": {
      "engine": "meilisearch",
      "url": "http://meilisearch:7700",
      "api_key": "masterKey123"
    },
    "voice": {
      "enabled": true,
      "api_key": "APIkey123",
      "api_secret": "secretABC",
      "url": "wss://chat.example.com/livekit",
      "webhook_url": "https://chat.example.com/api/webhooks/livekit"
    }
  },
  "cookie": {
    "secure": true
  },
  "proxy": {
    "trust_cf_connecting_ip": true
  }
}

Next Steps

Architecture

Understand how Fluxer’s components work together

Voice Setup

Configure LiveKit for real-time voice and video

Build docs developers (and LLMs) love