Skip to main content

Environment Variables

Consensus is configured through environment variables, making it easy to customize for different deployment environments without modifying code.

Server Configuration

Control where and how the server listens for connections:
VariableDefaultDescription
HOST0.0.0.0Server bind address (use 0.0.0.0 for Docker)
PORT3000HTTP server port
NODE_ENV(none)Environment mode: production, development, or test
HOST=0.0.0.0
PORT=3000
NODE_ENV=production
When running in Docker, always use HOST=0.0.0.0 to allow external connections. Using 127.0.0.1 will prevent access from outside the container.

Session Management

Secure session configuration is critical for authentication:
VariableDefaultDescription
SESSION_SECRETconsensus-secret-key-change-in-productionSecret key for signing session cookies
CRITICAL: The default session secret is insecure and MUST be changed in production. Use a cryptographically secure random string with at least 32 characters.
1

Generate Secure Secret

Use a secure random generator:
# Linux/macOS
openssl rand -hex 32

# Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

# Python
python3 -c "import secrets; print(secrets.token_hex(32))"
2

Set Environment Variable

export SESSION_SECRET="a1b2c3d4e5f6...your-generated-secret"
3

Verify Configuration

Check that the server is using your custom secret by looking for warnings in the logs.
The session cookie configuration is defined in src/web/server.ts:
{
  secret: config.session.secret,
  cookieName: "consensusSessionId",
  cookie: {
    secure: false, // Set to true in production with HTTPS
  }
}
For production deployments with HTTPS, modify src/web/server.ts:73 to set secure: true. This prevents session cookies from being transmitted over unencrypted connections.

Database Configuration

Configure where Consensus stores its SQLite database:
VariableDefaultDescription
DATA_DIRPlatform-specific XDG pathDirectory for database storage
DATA_DIR=/app/data
The database file is stored at $DATA_DIR/database.sqlite. Ensure this directory is writable by the application user.

Admin Defaults

Control the default administrator account created on first run:
VariableDefaultDescription
CONSENSUS_ADMIN_DEFAULT_PASSWORDadmin123Initial password for the default admin account
The default admin account is created with:
  • Username: admin
  • Password: Value of CONSENSUS_ADMIN_DEFAULT_PASSWORD
  • Must Change Password: true (forced to change on first login)
Always change this password immediately after deployment!

Demo Mode Configuration

Special variables for demo deployments (Dockerfile.demo):
VariableDefaultDescription
DEMO_MODEtrueEnables demo deployment mode
DB_RESET_INTERVAL_SECONDS86400Seconds between automatic database resets (24 hours)
DEMO_MODE=true
DB_RESET_INTERVAL_SECONDS=3600

Configuration Files

Application Config (src/config/index.ts)

The main configuration file reads environment variables and provides defaults:
export const config = {
    server: {
        host: process.env.HOST || "0.0.0.0",
        port: parseInt(process.env.PORT || "3000", 10),
    },
    session: {
        secret: process.env.SESSION_SECRET || "consensus-secret-key-change-in-production",
        cookieName: "consensusSessionId",
    },
};

Docker Environment Files

Create a .env file for Docker deployments:
.env
# Server
HOST=0.0.0.0
PORT=3000
NODE_ENV=production

# Security
SESSION_SECRET=your-cryptographically-secure-secret-key-here
CONSENSUS_ADMIN_DEFAULT_PASSWORD=your-secure-admin-password

# Database
DATA_DIR=/app/data
Reference it in docker-compose.yml:
services:
  consensus:
    env_file: .env
    # or use environment:
    environment:
      - HOST=${HOST}
      - PORT=${PORT}
      - SESSION_SECRET=${SESSION_SECRET}
Never commit .env files to version control. Add .env* to your .gitignore file.

Platform-Specific Paths

When DATA_DIR is not set, Consensus uses platform-specific XDG directories:
PlatformDefault Path
Linux~/.local/share/consensus
macOS~/Library/Application Support/consensus
Windows%LOCALAPPDATA%\consensus
This is handled by the env-paths package in src/db/connection.ts:8:
const dataDir = process.env.DATA_DIR || envPaths("consensus", { suffix: "" }).data;

Configuration Validation

Verify Settings on Startup

When the server starts, it logs important configuration:
Loading database from: /app/data/database.sqlite
Consensus E-Voting System running on http://0.0.0.0:3000

=== System Data ===
Admins (1):
  - admin (Administrator)

Check Database Location

node dist/index.js | grep "Loading database"

Verify Environment Variables

# Inside Docker container
docker exec consensus env | grep -E '(HOST|PORT|SESSION_SECRET|DATA_DIR)'

# Direct process
env | grep -E '(HOST|PORT|SESSION_SECRET|DATA_DIR)'

Security Best Practices

1

Use Strong Secrets

Generate cryptographically secure random values for SESSION_SECRET:
openssl rand -hex 32
2

Protect Environment Files

Set restrictive permissions on .env files:
chmod 600 .env
3

Use Environment-Specific Configs

Maintain separate .env files for each environment:
  • .env.production
  • .env.staging
  • .env.development
4

Rotate Secrets Regularly

Change SESSION_SECRET periodically. Note that this will invalidate all active sessions.
Changing SESSION_SECRET will log out all users. Plan secret rotation during maintenance windows.

Common Configuration Scenarios

Behind a Reverse Proxy

.env
HOST=127.0.0.1
PORT=3000
NODE_ENV=production
SESSION_SECRET=your-secret-key
Configure nginx to proxy requests:
server {
    listen 80;
    server_name voting.example.com;
    
    location / {
        proxy_pass http://127.0.0.1:3000;
        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;
    }
}

Multiple Instances (Load Balancing)

Consensus uses SQLite, which does not support multiple concurrent writers. For load balancing, you must use a shared filesystem with proper locking or migrate to PostgreSQL/MySQL (requires code changes).

Development Environment

.env.development
HOST=127.0.0.1
PORT=3000
NODE_ENV=development
SESSION_SECRET=dev-secret-not-for-production
CONSENSUS_ADMIN_DEFAULT_PASSWORD=admin123

Environment Variable Reference

Complete list of all environment variables:
.env.example
# Server Configuration
HOST=0.0.0.0
PORT=3000
NODE_ENV=production

# Session Security
SESSION_SECRET=change-this-to-a-secure-random-value

# Database
DATA_DIR=/app/data

# Admin Defaults
CONSENSUS_ADMIN_DEFAULT_PASSWORD=change-on-first-login

# Demo Mode (optional)
DEMO_MODE=false
DB_RESET_INTERVAL_SECONDS=86400

# Build (optional)
PUPPETEER_SKIP_DOWNLOAD=true

Next Steps

Docker Deployment

Deploy using Docker containers

Security

Implement security best practices

Build docs developers (and LLMs) love