Skip to main content

Configuration

Regius uses environment variables for configuration. When you create a new application, a .env file is generated with default configurations. You only need to fill in the required values.

Beyond .env, Regius supports multiple config file formats, config profiles, startup validation, and hot-reload. See Configuration Files & Profiles below, and the Secrets Management section for fetching and encrypting sensitive values.

Configuration Files & Profiles​

Multiple File Formats​

.env, .yaml/.yml, .json, and .toml are auto-discovered in the app root and config/ subdirectory. Nested keys are flattened to env-var convention (e.g. database.type becomes DATABASE_TYPE). Lists become comma-separated strings. Existing OS env vars always take precedence.

# config.yaml - nested keys become env vars
app_name: myapp
port: "8080"
debug: true

database:
type: postgres
host: localhost
port: 5432

cors:
allowed_origins:
- http://localhost:3000
- http://example.com
# config.toml - same structure, different format
app_name = "myapp"
port = "8080"
debug = true

[database]
type = "postgres"
host = "localhost"
port = 5432

Config Profiles​

Set APP_PROFILE=dev (or staging, prod) to load profile-specific files that override base values. Profile files follow the naming convention .env.dev, config.dev.yaml, etc. Profile subdirectories (config/dev/) are also supported.

# Set the active profile via env var
export APP_PROFILE=dev

# Base file: config.yaml (always loaded)
# Profile file: config.dev.yaml (overrides base values)
# Profile subdirectory: config/dev/ (also loaded, overrides base)

Startup Validation​

config.DefaultValidator() checks standard env vars (PORT, DATABASE_TYPE, CACHE, SESSION_TYPE, HASH_ALGORITHM, booleans, numeric fields) on startup. All failures are collected into a single error. Extend with custom rules via Validator.AddRule().

Hot-Reload​

app.WatchConfig(callback) watches config files with fsnotify and reloads them on change. A tracker distinguishes config-set vars from OS env vars so only config-sourced values are updated. Changes are debounced and reported via callback with ValueChange entries (added/modified/removed).

watcher, err := app.WatchConfig(func(changes []cfg.ValueChange) {
for _, c := range changes {
app.InfoLog.Printf("config %s: %s (old: %q, new: %q)",
c.Type, c.Key, c.OldValue, c.NewValue)
}
})
if err != nil {
log.Fatal(err)
}
defer watcher.Stop()

Basic Configuration​

# Application name, without spaces
APP_NAME=testapp
APP_URL="http://localhost:4000"

# False for production, true for development
DEBUG=true

# Port settings
PORT=4000
RPC_PORT=4001

# Server name, e.g, www.example.com
SERVER_NAME=localhost

# Use HTTPS?
SECURE=false

Database Configuration​

# Database type: postgres, postgresql, mysql, mariadb, sqlite, sqlite3
DATABASE_TYPE=postgres
DATABASE_HOST=127.0.0.1
DATABASE_PORT=5432
DATABASE_USER=postgres
DATABASE_PASS=postgres
DATABASE_NAME=myapp
DATABASE_SSL_MODE=disable

# Optional pool tuning
DATABASE_MAX_OPEN_CONNS=25
DATABASE_MAX_IDLE_CONNS=25
DATABASE_CONN_MAX_LIFETIME=15m

# Optional query logging (for development)
DATABASE_QUERY_LOGGING=true

Migrations, seeds, and health checks use these environment variables directly — no additional configuration file required. See the Database section for details on connection pooling, health checks, transactions, read/write splitting, GORM, and query logging.

Storage Configuration​

MinIO Configuration​

MINIO_ENDPOINT=
MINIO_KEY=
MINIO_SECRET=
MINIO_USESSL=
MINIO_REGION=
MINIO_BUCKET=

S3 Configuration​

S3_KEY=
S3_SECRET=
S3_REGION=
S3_BUCKET=
S3_ENDPOINT=

SFTP Configuration​

SFTP_HOST=
SFTP_PORT=
SFTP_USER=
SFTP_PASS=

WebDAV Configuration​

WEBDAV_HOST=
WEBDAV_PORT=
WEBDAV_USER=
WEBDAV_PASS=
WEBDAV_USESSL=

Cache Configuration​

# Cache backend: redis or badger
CACHE=

# Redis settings
REDIS_HOST=
REDIS_PASSWORD=
REDIS_PREFIX=testapp

Session Configuration​

# Session store: cookie, mysql, mariadb, postgres or redis
SESSION_TYPE=cookie

# Cookie settings
COOKIE_NAME=testapp
COOKIE_LIFETIME=1440
COOKIE_PERSISTS=true
COOKIE_SECURE=false
COOKIE_DOMAIN=localhost

Mail Configuration​

SMTP Configuration​

# SMTP_ENCRYPTION=tls | ssl | none
SMTP_HOST=
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_PORT=
SMTP_ENCRYPTION=
MAIL_DOMAIN=
FROM_NAME=
FROM_ADDRESS=

API Mailer Configuration​

MAILER_API=
MAILER_KEY=
MAILER_URL=

Password Hashing​

# Algorithm: bcrypt | scrypt | argon2
HASH_ALGORITHM=bcrypt
# bcrypt cost (4-31, default 12)
HASH_COST=12
# scrypt parameters
HASH_SCRYPT_N=32768
HASH_SCRYPT_R=8
HASH_SCRYPT_P=1
# argon2id parameters
HASH_ARGON2_MEMORY=65536
HASH_ARGON2_ITERATIONS=3
HASH_ARGON2_PARALLELISM=2

See the Password Hashing section for usage details.

CORS Configuration​

CORS is enabled by default with sensible defaults.

CORS_ENABLED=true
CORS_ALLOWED_ORIGINS="*"
CORS_ALLOWED_METHODS="GET,POST,PUT,DELETE,OPTIONS,PATCH,HEAD"
CORS_ALLOWED_HEADERS="Accept,Authorization,Content-Type,X-CSRF-Token"
CORS_EXPOSED_HEADERS=""
CORS_ALLOW_CREDENTIALS=true
CORS_MAX_AGE=300

See the CORS section for usage details.

Security Headers Configuration​

Security headers (helmet equivalent) are disabled by default. HSTS is only emitted when SECURE=true.

SECURITY_HEADERS_ENABLED=false
CONTENT_SECURITY_POLICY=default-src 'self'; script-src 'self' https://cdn.jsdelivr.net 'unsafe-inline'; style-src 'self' https://cdn.jsdelivr.net 'unsafe-inline'; img-src 'self' data:; font-src 'self' https://cdn.jsdelivr.net; frame-ancestors 'self'
HSTS_MAX_AGE=31536000
HSTS_INCLUDE_SUBDOMAINS=true
HSTS_PRELOAD=false
REFERRER_POLICY=strict-origin-when-cross-origin
X_FRAME_OPTIONS=SAMEORIGIN

See the Security Headers section for usage details.

Request ID Tracing​

Request ID tracing is enabled by default.

REQUEST_ID_ENABLED=true
REQUEST_ID_HEADER=X-Request-ID
REQUEST_ID_RESPONSE_HEADER=X-Request-ID
REQUEST_ID_FORMAT=uuid

See the Request ID Tracing section for usage details.

Request Sanitization​

Request sanitization for XSS prevention is on by default.

REQUEST_SANITIZATION_ENABLED=true
REQUEST_SANITIZATION_POLICY=strict
REQUEST_SANITIZATION_QUERY=true
REQUEST_SANITIZATION_FORM=true
REQUEST_SANITIZATION_HEADERS=Referer,User-Agent
REQUEST_SANITIZATION_EXEMPT=/api/.*

See the Request Sanitization section for usage details.

IP Whitelist/Blacklist​

IP filtering is opt-in. Deny always wins over allow.

IP_FILTER_ENABLED=false
IP_FILTER_ALLOW=
IP_FILTER_DENY=
IP_FILTER_TRUST_PROXY=false
IP_FILTER_STATUS_CODE=403
IP_FILTER_MESSAGE=

See the IP Filtering section for usage details.

API Key Authentication​

API key authentication is opt-in and should be applied to API route groups only.

API_KEY_AUTH_ENABLED=false
API_KEYS=
API_KEY_HEADER=Authorization
API_KEY_SCHEME=Bearer
API_KEY_ALT_HEADER=X-API-Key
API_KEY_QUERY_PARAM=
API_KEY_REALM=api

See the API Key Authentication section for usage details.

OAuth Configuration​

GitHub OAuth​

GITHUB_KEY=
GITHUB_SECRET=
GITHUB_CALLBACK=

Google OAuth​

GOOGLE_KEY=
GOOGLE_SECRET=
GOOGLE_CALLBACK=

Other Configuration​

# Template engine (used by CLI scaffolding only; at runtime each handler
# picks its engine via render.Jet(), render.Go(), or a templ component)
# templ is the default. Options: templ | jet | go
RENDERER=templ

# Encryption key (32 characters long)
KEY=DPFtfVnxbtnXXRzVnRzrLxDzXXRh+Xft

# File upload settings
ALLOWED_FILETYPES="image/png,image/jpeg,image/gif,application/pdf"
# 5MB in bytes
MAX_FILESIZE=5242880

Internationalization (i18n)​

i18n is enabled by default. DEFAULT_LOCALE is used when no locale cookie or Accept-Language header is present. SUPPORTED_LOCALES is a comma-separated list of available languages.

I18N_ENABLED=true
DEFAULT_LOCALE=en
SUPPORTED_LOCALES=en,es
LOCALE_COOKIE_NAME=locale

See the Internationalization section for usage details.

Background Jobs​

Background jobs are opt-in. Workers and the scheduler run only when JOBS_ENABLED=true; the manager is always constructed so Enqueue works even with workers off. JOBS_BACKEND picks the store: memory (default), redis (reuses REDIS_*), or sql (the app's database pool).

JOBS_ENABLED=false
JOBS_BACKEND=memory
JOBS_PREFIX=regius:jobs
JOBS_WORKERS=4
JOBS_POLL_INTERVAL=1s
JOBS_LEASE=5m
JOBS_MAX_ATTEMPTS=3
JOBS_GRACEFUL_TIMEOUT=30s
JOBS_RETENTION=24h
JOBS_SCHEDULER_LOCK=true
JOBS_DASHBOARD_ENABLED=false

See the Background Jobs section for usage details.

WebSockets​

WebSockets are opt-in (WS_ENABLED); the hub is always constructed. WS_ENABLED mounts the default broadcast route at WS_PATH; authenticated sockets should be mounted on app routes instead (regius make websocket does this). Cross-origin handshakes are rejected by default.

WS_ENABLED=false
WS_PATH=/ws
WS_ALLOWED_ORIGINS=
WS_ALLOW_EMPTY_ORIGIN=true
WS_HEARTBEAT=30s
WS_WRITE_TIMEOUT=10s
WS_PONG_TIMEOUT=60s
WS_MAX_MESSAGE_SIZE=32768
WS_CLIENT_BUFFER=16
WS_MAX_CLIENTS=0

See the WebSockets section for usage details.

Scalar API Reference​

Scalar is opt-in via SCALAR_ENABLED; when enabled it mounts the docs UI (/docs) and the OpenAPI spec endpoint (/openapi.json).

SCALAR_ENABLED=false
#SCALAR_DOCS_PATH=/docs
#SCALAR_SPEC_PATH=/openapi.json
#SCALAR_TITLE=API Reference
#SCALAR_CDN_URL=https://cdn.jsdelivr.net/npm/@scalar/api-reference
#SCALAR_SPEC_FILE=
#SCALAR_THEME=default
#SCALAR_SHOW_CLIENTS={"go":["native"],"java":true,"curl","fetch"}

See the Scalar API Reference section for usage details.

Browser Live-Reload​

Development-only browser reload, set automatically by regius dev. Never enable in production.

DEV_RELOAD_ENABLED=false
DEV_RELOAD_PATH=/__dev

See the Browser Live-Reload section for usage details.

Docker Compose Configuration​

# PostgreSQL
POSTGRES_DB=
POSTGRES_USER=
POSTGRES_PASSWORD=

# MySQL
MYSQL_DATABASE=
MYSQL_USER=
MYSQL_PASSWORD=
MYSQL_ROOT_PASSWORD=

Make sure to fill in all required values before running your application in production.