Overview
Rexec is configured entirely through environment variables. This guide documents all available configuration options with descriptions from the codebase.
Configuration File
Create a .env file in the root directory or pass environment variables to Docker:
Server Configuration
HTTP Server
Variable Description Default Required PORTAPI listen port 8080No GIN_MODEGin framework mode: debug or release debugNo BASE_URLBase URL of the API server http://localhost:8080Yes REXEC_APP_URLURL of the frontend application http://localhost:5173Yes REXEC_WS_HOSTHost for WebSocket connections (for port forwarding) localhost:8080Yes
Example:
PORT = 8080
GIN_MODE = release
BASE_URL = https://rexec.yourdomain.com
REXEC_APP_URL = https://rexec.yourdomain.com
REXEC_WS_HOST = rexec.yourdomain.com:8080
Set GIN_MODE=release in production to disable debug logging and improve performance.
Security Configuration
Authentication & Encryption
Variable Description Default Required JWT_SECRETSecret key for signing JWT authentication tokens Random if unset Yes REXEC_ENCRYPTION_KEYEncryption key for sensitive data (must be 16, 24, or 32 bytes) rexec-dev-key-do-not-use-in-prodYes ALLOWED_ORIGINSComma-separated list of allowed origins for WebSocket connections http://localhost:5173,http://localhost:8080No BLOCK_EMPTY_ORIGINBlock WebSocket connections with empty Origin headers falseNo
Generate Secure Keys:
# JWT Secret (any length, base64 recommended)
openssl rand -base64 32
# Encryption Key (must be exactly 16, 24, or 32 characters)
openssl rand -base64 32 | cut -c1-32
Example:
JWT_SECRET = your-super-secret-jwt-key-change-this-in-production
REXEC_ENCRYPTION_KEY = your-32-character-encryption-key
ALLOWED_ORIGINS = https://app.rexec.dev,https://rexec.dev
BLOCK_EMPTY_ORIGIN = true
Production Security Critical:
Never use default values for JWT_SECRET or REXEC_ENCRYPTION_KEY in production
Generate cryptographically secure random keys
Store keys securely (use secrets management in production)
Rotate keys periodically
Database Configuration
PostgreSQL
Variable Description Default Required DATABASE_URLPostgreSQL connection string postgres://rexec:rexec@localhost:5432/rexec?sslmode=disableYes
Connection String Format:
postgres://username:password@host:port/database?options
Example:
# Local PostgreSQL
DATABASE_URL = postgres://rexec:secure_password@localhost:5432/rexec? sslmode = disable
# Remote PostgreSQL with SSL
DATABASE_URL = postgres://rexec:[email protected] :5432/rexec? sslmode = require
# Docker Compose (internal network)
DATABASE_URL = postgres://rexec: ${ POSTGRES_PASSWORD } @postgres:5432/rexec? sslmode = disable
Use sslmode=require or sslmode=verify-full for production databases to encrypt connections.
Redis
Variable Description Default Required REDIS_URLRedis connection URL for sessions, pub/sub, and caching redis://localhost:6379Yes
Connection String Format:
redis://[username:password@]host:port/database
Example:
# Local Redis
REDIS_URL = redis://localhost:6379
# Redis with password
REDIS_URL = redis://:password@localhost:6379
# Redis with database selection
REDIS_URL = redis://localhost:6379/0
# Docker Compose
REDIS_URL = redis://redis:6379
Redis is required for production deployments and scaling across multiple instances.
Docker Configuration
Container Runtime
Variable Description Default Required DOCKER_HOSTDocker daemon endpoint unix:///var/run/docker.sockYes CONTAINER_RUNTIMEContainer runtime: docker or podman dockerNo OCI_RUNTIMEOCI runtime: runc or crun runcNo VOLUME_PATHPath for container volumes /var/lib/rexec/volumesNo CONTAINER_NETWORKDocker network name for containers rexec-networkNo CONTAINER_IDLE_TIMEOUTContainer idle timeout in seconds 3600No
Docker Host Examples:
# Local Docker socket (Linux)
DOCKER_HOST = unix:///var/run/docker.sock
# Remote Docker with TLS
DOCKER_HOST = tcp://docker-host.example.com:2376
# SSH connection
DOCKER_HOST = ssh://[email protected]
Remote Docker with TLS
For secure remote Docker connections:
Variable Description Required DOCKER_TLS_VERIFYEnable TLS verification (set to 1) Yes DOCKER_CA_CERTCA certificate content (PEM format) Yes DOCKER_CLIENT_CERTClient certificate content (PEM format) Yes DOCKER_CLIENT_KEYClient private key content (PEM format) Yes
Example:
DOCKER_HOST = tcp://docker-host.example.com:2376
DOCKER_TLS_VERIFY = 1
DOCKER_CA_CERT = /path/to/ca.pem
DOCKER_CLIENT_CERT = /path/to/cert.pem
DOCKER_CLIENT_KEY = /path/to/key.pem
Resource Limits
Default Container Resources
Variable Description Default Required DEFAULT_MEMORY_MBDefault memory limit per container (MB) 512No DEFAULT_CPU_SHARESDefault CPU shares per container 512No DEFAULT_DISK_MBDefault disk limit per container (MB) 1024No
Example:
# Give containers more resources
DEFAULT_MEMORY_MB = 1024
DEFAULT_CPU_SHARES = 1024
DEFAULT_DISK_MB = 2048
Storage Configuration
Local Storage
Variable Description Default Required RECORDINGS_PATHPath for terminal session recordings ./data/recordingsNo SCRIPTS_DIRDirectory containing install scripts ./scriptsNo DOWNLOADS_DIRDirectory for downloadable binaries ./downloadsNo WEB_DIRDirectory containing built frontend webNo
Example:
RECORDINGS_PATH = /var/lib/rexec/recordings
SCRIPTS_DIR = /opt/rexec/scripts
DOWNLOADS_DIR = /opt/rexec/downloads
WEB_DIR = /opt/rexec/web
S3 Storage (Optional)
For storing session recordings in S3-compatible storage:
Variable Description Required S3_BUCKETS3 bucket name Yes (if using S3) S3_REGIONS3 region Yes (if using S3) S3_ENDPOINTS3 endpoint (for MinIO or custom S3) No S3_ACCESS_KEY_IDS3 access key Yes (if using S3) S3_SECRET_ACCESS_KEYS3 secret key Yes (if using S3) S3_PREFIXPrefix for S3 object keys No S3_FORCE_PATH_STYLEUse path-style S3 URLs (for MinIO) No
AWS S3 Example:
S3_BUCKET = rexec-recordings
S3_REGION = us-east-1
S3_ACCESS_KEY_ID = AKIAIOSFODNN7EXAMPLE
S3_SECRET_ACCESS_KEY = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
S3_PREFIX = recordings
MinIO Example:
S3_BUCKET = rexec-recordings
S3_REGION = us-east-1
S3_ENDPOINT = http://minio:9000
S3_ACCESS_KEY_ID = minioadmin
S3_SECRET_ACCESS_KEY = minioadmin
S3_PREFIX = recordings
S3_FORCE_PATH_STYLE = true
SSH Gateway (Optional)
Variable Description Default Required SSH_GATEWAY_ENABLEDEnable SSH gateway for container access falseNo SSH_GATEWAY_HOST_KEYPath to SSH host key /app/.ssh/host_keyNo
Example:
SSH_GATEWAY_ENABLED = true
SSH_GATEWAY_HOST_KEY = /app/.ssh/host_key
The SSH gateway allows SSH access to containers on port 22. Useful for traditional SSH workflows.
Billing Integration (Optional)
Stripe
Variable Description Required STRIPE_SECRET_KEYStripe secret API key Yes (if using Stripe) STRIPE_WEBHOOK_SECRETStripe webhook signing secret Yes (if using Stripe) STRIPE_PRICE_PROStripe price ID for Pro plan No STRIPE_PRICE_ENTERPRISEStripe price ID for Enterprise plan No
Example:
STRIPE_SECRET_KEY = sk_test_51234567890abcdefghijklmnopqrstuvwxyz
STRIPE_WEBHOOK_SECRET = whsec_1234567890abcdefghijklmnopqrstuvwxyz
STRIPE_PRICE_PRO = price_1234567890abcdefghijklmnop
STRIPE_PRICE_ENTERPRISE = price_0987654321zyxwvutsrqponmlkji
OAuth Integration (Optional)
PipeOps OAuth
Variable Description Required PIPEOPS_OAUTH_BASE_URLPipeOps OAuth base URL Yes (if using PipeOps) PIPEOPS_API_URLPipeOps API URL Yes (if using PipeOps) PIPEOPS_CLIENT_IDPipeOps OAuth client ID Yes (if using PipeOps) PIPEOPS_REDIRECT_URIOAuth callback redirect URI Yes (if using PipeOps)
Example:
PIPEOPS_OAUTH_BASE_URL = https://api.pipeops.io/oauth
PIPEOPS_API_URL = https://api.pipeops.io
PIPEOPS_CLIENT_ID = your-client-id
PIPEOPS_REDIRECT_URI = http://localhost:8080/auth/pipeops/callback
Logging
Variable Description Default Required LOG_LEVELLog level: debug, info, warn, error infoNo
Example:
# Development
LOG_LEVEL = debug
# Production
LOG_LEVEL = info
Complete Example Configurations
Development Configuration
# Server
PORT = 8080
GIN_MODE = debug
REXEC_APP_URL = http://localhost:5173
REXEC_WS_HOST = localhost:8080
BASE_URL = http://localhost:8080
# Security (Development only!)
JWT_SECRET = dev-secret-change-in-production
REXEC_ENCRYPTION_KEY = rexec-dev-key-do-not-use-in-prod
ALLOWED_ORIGINS = http://localhost:5173,http://localhost:8080
BLOCK_EMPTY_ORIGIN = false
# Database
DATABASE_URL = postgres://rexec:rexec@localhost:5432/rexec? sslmode = disable
REDIS_URL = redis://localhost:6379
# Docker
DOCKER_HOST = unix:///var/run/docker.sock
VOLUME_PATH = /var/lib/rexec/volumes
CONTAINER_NETWORK = rexec-network
CONTAINER_IDLE_TIMEOUT = 3600
# Resources
DEFAULT_MEMORY_MB = 512
DEFAULT_CPU_SHARES = 512
DEFAULT_DISK_MB = 1024
# Storage
RECORDINGS_PATH = ./data/recordings
SCRIPTS_DIR = ./scripts
DOWNLOADS_DIR = ./downloads
# Logging
LOG_LEVEL = debug
Production Configuration
# Server
PORT = 8080
GIN_MODE = release
REXEC_APP_URL = https://rexec.yourdomain.com
REXEC_WS_HOST = rexec.yourdomain.com:8080
BASE_URL = https://rexec.yourdomain.com
# Security - CHANGE THESE!
JWT_SECRET =< generated-with-openssl-rand-base64-32 >
REXEC_ENCRYPTION_KEY =< generated-32-character-key >
ALLOWED_ORIGINS = https://rexec.yourdomain.com
BLOCK_EMPTY_ORIGIN = true
# Database (with SSL)
DATABASE_URL = postgres://rexec: ${ POSTGRES_PASSWORD } @postgres.internal:5432/rexec? sslmode = require
REDIS_URL = redis://: ${ REDIS_PASSWORD } @redis.internal:6379
# Docker (Remote with TLS)
DOCKER_HOST = tcp://docker-host.internal:2376
DOCKER_TLS_VERIFY = 1
DOCKER_CA_CERT = /certs/ca.pem
DOCKER_CLIENT_CERT = /certs/cert.pem
DOCKER_CLIENT_KEY = /certs/key.pem
VOLUME_PATH = /var/lib/rexec/volumes
CONTAINER_NETWORK = rexec-network
CONTAINER_IDLE_TIMEOUT = 1800
# Resources (Production limits)
DEFAULT_MEMORY_MB = 1024
DEFAULT_CPU_SHARES = 1024
DEFAULT_DISK_MB = 2048
# S3 Storage
S3_BUCKET = rexec-prod-recordings
S3_REGION = us-east-1
S3_ACCESS_KEY_ID = ${ AWS_ACCESS_KEY_ID }
S3_SECRET_ACCESS_KEY = ${ AWS_SECRET_ACCESS_KEY }
S3_PREFIX = recordings
# SSH Gateway
SSH_GATEWAY_ENABLED = true
SSH_GATEWAY_HOST_KEY = /app/.ssh/host_key
# Billing
STRIPE_SECRET_KEY = ${ STRIPE_SECRET_KEY }
STRIPE_WEBHOOK_SECRET = ${ STRIPE_WEBHOOK_SECRET }
# Logging
LOG_LEVEL = info
Environment Variable Priority
Rexec reads configuration in this order (later sources override earlier ones):
Default values in code
.env file in working directory
Environment variables from shell/Docker
Command-line flags (if available)
Security Best Practices
Troubleshooting
Invalid Encryption Key Length
Error: REXEC_ENCRYPTION_KEY must be 16, 24, or 32 bytes
Solution: Ensure your key is exactly 16, 24, or 32 characters:
# Generate a 32-character key
openssl rand -base64 32 | cut -c1-32
Database Connection Failed
Error: dial tcp: lookup postgres: no such host
Solution: Check your DATABASE_URL connection string and ensure PostgreSQL is accessible.
Docker Connection Refused
Error: Cannot connect to Docker daemon
Solution: Verify DOCKER_HOST is correct and Docker is running:
Next Steps
Docker Compose Deploy Rexec with Docker Compose
Manual Setup Build and deploy from source