Skip to content

Configuration

dev-mondoshawan edited this page Apr 15, 2026 · 1 revision

Configuration

Complete configuration reference for the Dissensus AI Debate Engine.


Environment Variables

Create a .env file in the dissensus-engine/ directory. The engine reads these at startup.

Server Configuration

Variable Description Default Required
PORT HTTP port the server listens on 3000 No
NODE_ENV Environment mode (production or development) development No
TRUST_PROXY Trust reverse proxy (nginx). Set to 0 only if Node listens directly on public internet 1 No
TRUST_PROXY_HOPS Number of proxy hops to trust 1 No
DEBATE_OF_THE_DAY_TZ Timezone for "Debate of the Day" feature UTC No

API Keys

At least one API key is required for the server to function. When server-side keys are configured, visitors can use the app without providing their own keys.

Variable Description Required
DEEPSEEK_API_KEY DeepSeek API key (cheapest, ~$0.008/debate) At least one
OPENAI_API_KEY OpenAI API key (~$0.02-0.15/debate) At least one
GEMINI_API_KEY or GOOGLE_API_KEY Google Gemini API key (free tier available) At least one

Example .env File

# Server Configuration
PORT=3000
NODE_ENV=production

# Trust proxy (nginx) - keep enabled for VPS deployments
TRUST_PROXY=1
TRUST_PROXY_HOPS=1

# Timezone for "Debate of the Day"
DEBATE_OF_THE_DAY_TZ=America/New_York

# API Keys - Add any providers you want
DEEPSEEK_API_KEY=sk-your-deepseek-key
OPENAI_API_KEY=sk-your-openai-key
GEMINI_API_KEY=AIza-your-gemini-key

Nginx Configuration Reference

Critical SSE Settings

The /api/debate/stream endpoint requires special configuration to disable buffering:

location /api/debate/stream {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Connection '';

    # CRITICAL for SSE streaming — disable all buffering
    proxy_buffering off;
    proxy_cache off;
    chunked_transfer_encoding off;

    # Long timeout for debates (they can take 5+ minutes)
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
}

⚠️ Warning: Without proxy_buffering off, Nginx will buffer SSE responses and the debate won't stream in real-time.

Timeout Settings

Directive Value Purpose
proxy_read_timeout 600s Time to wait for data from upstream
proxy_send_timeout 600s Time to wait for client to receive data
proxy_connect_timeout 60s Time to establish connection

Security Headers

Add these to all server blocks:

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

Static Asset Caching

Serve static files directly from Nginx for better performance:

location /css/ {
    alias /home/dissensus/dissensus-engine/public/css/;
    expires 7d;
    add_header Cache-Control "public, immutable";
}

location /js/ {
    alias /home/dissensus/dissensus-engine/public/js/;
    expires 7d;
    add_header Cache-Control "public, immutable";
}

location /images/ {
    alias /home/dissensus/dissensus-engine/public/images/;
    expires 30d;
    add_header Cache-Control "public, immutable";
}

Gzip Compression

Enable compression for text-based responses:

gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript image/svg+xml;

SSL Configuration

After running Certbot, your config will include:

server {
    listen [::]:443 ssl ipv6only=on;
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/app.dissensus.fun/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.dissensus.fun/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}

server {
    if ($host = app.dissensus.fun) {
        return 301 https://$host$request_uri;
    }
    listen 80;
    listen [::]:80;
    server_name app.dissensus.fun;
    return 404;
}

Rate Limiting Configuration

Rate limits are configured in server/index.js:

const debateLimiter = rateLimit({
  windowMs: 60 * 1000,        // 1 minute window
  max: isProd ? 10 : 100,     // 10 debates/min in prod, 100 in dev
  message: { error: 'Too many debates. Please wait a minute and try again.' },
  standardHeaders: true,      // Send RateLimit-* headers
  legacyHeaders: false        // Disable X-RateLimit-* headers
});

Current Limits

Endpoint Production Development
Debate streaming 10/min 100/min
Card generation 20/min 100/min
Metrics 120/min 300/min

Trust Proxy Settings

For rate limiting to work correctly behind Nginx, enable trust proxy:

TRUST_PROXY=1
TRUST_PROXY_HOPS=1

If running without a reverse proxy (not recommended for production):

TRUST_PROXY=0

Provider/Model Selection

Supported Providers

Provider Default Model Cost per Debate
DeepSeek deepseek-chat ~$0.008
OpenAI gpt-4o ~$0.15
OpenAI gpt-4o-mini ~$0.02
Gemini gemini-2.0-flash ~$0.006 (free tier available)
Gemini gemini-2.5-flash ~$0.03

Model IDs

DeepSeek:

  • deepseek-chat - DeepSeek V3.2

OpenAI:

  • gpt-4o - GPT-4o (best quality)
  • gpt-4o-mini - GPT-4o Mini (faster, cheaper)

Gemini:

  • gemini-2.0-flash - Gemini 2.0 Flash (fastest)
  • gemini-2.5-flash - Gemini 2.5 Flash (enhanced)
  • gemini-2.5-flash-lite - Gemini 2.5 Flash-Lite (lightweight)

Selecting a Provider

Via query parameter:

GET /api/debate/stream?topic=...&provider=deepseek&model=deepseek-chat

If no provider is specified, defaults to:

  1. deepseek with deepseek-chat
  2. gemini with gemini-2.0-flash
  3. openai with gpt-4o

PM2 Configuration

ecosystem.config.js

For advanced PM2 configuration, create ecosystem.config.js:

module.exports = {
  apps: [{
    name: 'dissensus',
    script: './server/index.js',
    cwd: '/home/dissensus/dissensus-engine',
    instances: 1,
    exec_mode: 'fork',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    error_file: './logs/err.log',
    out_file: './logs/out.log',
    log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
    merge_logs: true,
    max_memory_restart: '500M',
    restart_delay: 3000,
    max_restarts: 5,
    min_uptime: '10s',
    watch: false,
    kill_timeout: 5000,
    listen_timeout: 10000
  }]
};

Start with:

pm2 start ecosystem.config.js

Environment-Specific Settings

Development

NODE_ENV=development
PORT=3000
TRUST_PROXY=0

In development mode:

  • Rate limits are relaxed (100/min vs 10/min)
  • More verbose error messages
  • No helmet CSP enforcement

Production

NODE_ENV=production
PORT=3000
TRUST_PROXY=1
TRUST_PROXY_HOPS=1

In production mode:

  • Strict rate limiting
  • Helmet security headers enabled
  • Trust proxy enabled for accurate client IPs

Timezone Configuration

The DEBATE_OF_THE_DAY_TZ variable controls which timezone is used for determining the "current" debate topic.

Common values:

  • UTC - Coordinated Universal Time (default)
  • America/New_York - US Eastern Time
  • America/Los_Angeles - US Pacific Time
  • Europe/London - GMT/BST
  • Europe/Paris - Central European Time
  • Asia/Tokyo - Japan Standard Time

List all available timezones:

timedatectl list-timezones

File Permissions

Ensure correct ownership for the application directory:

# Set ownership to the dissensus user
sudo chown -R dissensus:dissensus /home/dissensus/dissensus-engine

# Set appropriate permissions
sudo chmod -R 755 /home/dissensus/dissensus-engine

# Ensure .env is readable only by owner
chmod 600 /home/dissensus/dissensus-engine/.env

Log Configuration

PM2 Logs

Default log locations:

  • Output: ~/.pm2/logs/dissensus-out.log
  • Errors: ~/.pm2/logs/dissensus-error.log

View logs:

pm2 logs dissensus
pm2 logs dissensus --lines 100
pm2 logs dissensus --err

Nginx Logs

# Access log
sudo tail -f /var/log/nginx/access.log

# Error log
sudo tail -f /var/log/nginx/error.log

Application Logs

The engine logs to stdout/stderr which PM2 captures:

⚡ DISSENSUS Engine running on http://localhost:3000
🧠 Providers: OpenAI, DeepSeek, Google Gemini
🔑 Server-side keys configured for: deepseek, openai
🔥 Ready to debate.