Configuration

Environment Variables

Cleanmails is configured entirely through environment variables. These are set in your .env file (located at /opt/cleanmails/.env after installation).

ENCRYPTION_KEY is required

The ENCRYPTION_KEY must be a 64-character hex string (32 bytes). It's used for AES-256-GCM encryption of all sender passwords and integration tokens. Generate with: openssl rand -hex 32

Full Example

/opt/cleanmails/.env
# Domain
DOMAIN=app.yourdomain.com

# Database
DB_PASSWORD=your-generated-password
DATABASE_URL=postgres://cleanmails:${DB_PASSWORD}@postgres:5432/cleanmails?sslmode=disable

# Redis
REDIS_URL=redis://redis:6379

# Security
ENCRYPTION_KEY=your-64-hex-char-key-here
JWT_SECRET=your-jwt-secret-here

# App
BASE_URL=https://app.yourdomain.com
API_PORT=8080
GIN_MODE=release
ALLOWED_ORIGINS=https://app.yourdomain.com

Core Settings

VariableDefaultDescription
DOMAINYour domain name (used by Caddy for SSL provisioning)
DATABASE_URLRequired. PostgreSQL connection string
REDIS_URLredis://localhost:6379Redis connection URL (used by Asynq task queue)
API_PORT8080Port the API server listens on
BASE_URLhttp://localhost:8080Public URL of your instance (used in tracking links, unsubscribe URLs)
GIN_MODEdebugSet to release in production (disables debug logging)
ALLOWED_ORIGINShttp://localhost:3000Comma-separated list of allowed CORS origins

Security

VariableDescription
ENCRYPTION_KEYRequired. 64-char hex string for AES-256-GCM encryption of credentials
JWT_SECRETRequired. Secret key for signing JWT tokens (7-day expiry)
DB_PASSWORDPostgreSQL password (used in DATABASE_URL and by the postgres container)

Database

VariableDefaultDescription
DB_PASSWORDPostgreSQL password (shared between app and postgres container)
DATABASE_URLFull PostgreSQL connection string with sslmode
REDIS_URLredis://redis:6379Redis URL for Asynq background jobs

Frontend

VariableDefaultDescription
NEXT_PUBLIC_API_URLhttp://localhost:8080API URL the frontend uses (set to your public URL in production)
HOSTNAME0.0.0.0Frontend listen host
PORT3000Frontend listen port
Auto-generated by installer

The install script (install.sh) automatically generates all secrets using openssl rand -hex. You only need to provide the --domain flag. The generated .env file is set to mode 640 for security.

Worker Configuration

The background worker connects to the same PostgreSQL and Redis instances. Worker behavior is configured through the Asynq server settings in code:

SettingValueDescription
Concurrency10Total concurrent task processors
Critical queue weight6Bounce/complaint handling priority
Default queue weight3Campaign dispatch, validation tasks
Low queue weight1IMAP sync, AI replies

Docker Resource Limits

The production Docker Compose sets memory limits per service:

ServiceMemory Limit
PostgreSQL512 MB
Redis192 MB
API Server256 MB
Worker256 MB
Frontend256 MB
Caddy64 MB