Environment Variables
Documentation / Environment Variables / Application, Server & Database

Application, Server & Database

Application

VariableDefaultDescription
RUNIQUE_ENVproddev or prod, whatever the case; unset or unknown means prod (with a warning for an unknown value). Read once at startup. In dev: session cookie without Secure, debug log level (unless RUST_LOG), templates read again on every request, no-cache headers on localhost, the default home page when / isn't declared, public URL set to http://127.0.0.1:{PORT} (.with_public_url() ignored), allowed hosts not validated, no upgrade-insecure-requests, no SRI and static files in no-cache, so edited CSS reloads without a restart. In prod: security checks at startup (SECRET_KEY, with_public_url, the reset's mailer, ACME).
DEBUGfalseShows the detailed error pages and changes nothing else — read once at startup. Accepts true/1/yes/on and false/0/no/off, whatever the case. Also works with RUNIQUE_ENV=prod to look into a problem on a live site: not recommended, as every visitor then sees those pages (a warning shows at startup).
BASE_DIR.Application root directory
TZUTCIANA timezone for the application (e.g. Europe/Paris, America/New_York). Accessible via config.timezone — parse it with chrono-tz in your project.
LANGsystem localeCLI language (fr, en, de, es, it, pt, ja, zh, ru). Priority: LANG / LC_ALL / LC_MESSAGES from .env > system locale > en. The app's language is set in code (set_lang(Lang::En))

Server

VariableDefaultDescription
IP_SERVER127.0.0.1Listening IP address
PORT3000Listening port
SECRET_KEYdefault_secret_keySecret key (CSRF, signatures, encryption of the sessions in the database: changing it signs their users out at restart). runique new writes a random one (64 hex characters) into the project's .env. To replace it: any random string of 32 characters or more (openssl rand -hex 32). In production (RUNIQUE_ENV=prod), startup fails when it is empty, equal to the default, or shorter than 32 characters; in development, a warning is shown when it is missing

Database

Connection

VariableDefaultDescription
DATABASE_URL—Full URL. Read first: when set, DB_ENGINE, DB_USER, DB_PASSWORD, DB_HOST, DB_PORT and DB_NAME are ignored, and the engine comes from the URL's scheme (postgres://, mysql://, mariadb://, sqlite://)
DB_ENGINEsqliteEngine, when DATABASE_URL is unset: postgres, mysql, mariadb, sqlite. Must match the compiled runique feature, or startup fails with "driver not enabled"
DB_USER—Username (required except for SQLite)
DB_PASSWORD—Password (required except for SQLite)
DB_HOSTlocalhostHost
DB_PORT5432 / 3306Port (default depends on engine)
DB_NAMElocal_base.sqlite (SQLite only)Database name — required for postgres/mysql/mariadb, startup fails if absent

Connection pool

VariableDefaultDescription
DB_MAX_CONNECTIONS100Maximum pool size
DB_MIN_CONNECTIONS20Minimum pool size

Timeouts

VariableDefaultUnitDescription
DB_CONNECT_TIMEOUT2secondsConnection establishment timeout
DB_ACQUIRE_TIMEOUT500millisecondsPool acquire timeout
DB_IDLE_TIMEOUT300secondsIdle connection lifetime
DB_MAX_LIFETIME3600secondsMaximum connection lifetime

SQL Logging

VariableDefaultDescription
DB_LOGGINGfalseEnable SQL query logging (true, 1, yes)

Secondary connections — `with_custom_db`

To attach an additional database connection (Redis pool, secondary PostgreSQL, MongoDB client, etc.), use .with_custom_db() on the builder. The value is stored in a HashMap<TypeId, Arc<dyn Any>> internal to RuniqueEngine — not injected as an Axum Extension. Access it in handlers via engine.custom_db::<T>() (or its alias engine.extension::<T>()), which returns Option<Arc<T>>.

// main.rs
let redis = redis::Client::open("redis://127.0.0.1/")?;
let db = DatabaseConfig::from_env()?.build().connect().await?;

RuniqueApp::builder(config)
    .with_database(db)
    .with_custom_db(redis)   // T: Any + Send + Sync + 'static
    .routes(url::routes())
    .build().await?
    .run().await
// handler
use redis::Client;

pub async fn my_handler(mut req: Request) -> AppResult<Response> {
    let redis = req.engine.custom_db::<Client>().expect("redis not configured");
    let mut conn = redis.get_async_connection().await?;
    // ...
}

Any type implementing Any + Send + Sync + 'static is accepted. Multiple secondary connections of different types can be registered with repeated .with_custom_db() calls.