Overview
QIMEM uses environment variables for configuration. All settings are validated at startup and documented in .env.example.
Environment Variables
Core Configuration
QIMEM_MODE
Controls the key storage backend.
Options:
stateless (default): In-memory key storage
stateful: PostgreSQL-backed key storage
Stateless mode stores keys in memory only. Keys are lost when the process restarts. Use for development or ephemeral workloads.
QIMEM_BIND
Socket address for the HTTP server.
Default: 0.0.0.0:8080
Format: <IP>:<PORT> (must be a valid SocketAddr)
Examples:
# Listen on all interfaces
QIMEM_BIND=0.0.0.0:8080
# Listen on localhost only
QIMEM_BIND=127.0.0.1:8080
# Custom port
QIMEM_BIND=0.0.0.0:3000
DATABASE_URL
PostgreSQL connection string. Required when QIMEM_MODE=stateful.
DATABASE_URL=postgres://postgres:postgres@postgres:5432/qimem
Format: postgres://<user>:<password>@<host>:<port>/<database>[?<options>]
Options:
sslmode=disable - Disable TLS (development only)
sslmode=require - Require TLS (production)
QIMEM will fail to start if QIMEM_MODE=stateful and DATABASE_URL is not set.
RUST_LOG
Controls log verbosity.
Levels: trace, debug, info, warn, error
Examples:
# Default logging
RUST_LOG=info
# Debug mode
RUST_LOG=debug
# Module-specific logging
RUST_LOG=qimem=debug,sqlx=warn,hyper=info
Configuration Struct
Configuration is loaded from environment variables in src/config.rs:32:
pub struct Config {
/// Runtime mode (stateless or stateful)
pub mode: Mode,
/// Database URL when stateful
pub database_url: Option<String>,
/// Bind address
pub bind: SocketAddr,
}
impl Config {
pub fn from_env() -> Result<Self> {
let mode = std::env::var("QIMEM_MODE")
.unwrap_or_else(|_| "stateless".to_string());
let mode = match mode.as_str() {
"stateless" => Mode::Stateless,
"stateful" => Mode::Stateful,
_ => return Err(QimemError::Config(
"QIMEM_MODE must be stateless|stateful".to_string(),
)),
};
let bind_raw = std::env::var("QIMEM_BIND")
.unwrap_or_else(|_| "0.0.0.0:8080".to_string());
let bind = bind_raw.parse::<SocketAddr>()
.map_err(|err| QimemError::Config(format!("invalid QIMEM_BIND: {err}")))?
let database_url = std::env::var("DATABASE_URL").ok();
if mode == Mode::Stateful && database_url.is_none() {
return Err(QimemError::Config(
"DATABASE_URL is required for stateful mode".to_string(),
));
}
Ok(Self { mode, database_url, bind })
}
}
Validation Rules
QIMEM_MODE validation
Must be exactly stateless or stateful (case-sensitive)
QIMEM_BIND validation
Must parse as a valid SocketAddr (IP:PORT format)
DATABASE_URL validation
Required when mode == Mode::Stateful, optional otherwise
Feature Flags
Compile-time features control optional functionality. Defined in Cargo.toml:26:
stateful
Enables PostgreSQL-backed key storage.
[features]
stateful = ["dep:sqlx"]
Dependencies:
sqlx with postgres, uuid, migrate, tls-rustls features
Build:
cargo build --release --bin qimem-api --features stateful
Enables:
PostgresKeyStore in src/keystore/postgres.rs
- Database migrations in
migrations/
- Persistent key lineage and rotation
chacha
Enables ChaCha20-Poly1305 encryption algorithm.
[features]
chacha = ["dep:chacha20poly1305"]
Build:
cargo build --features chacha
Enables:
Algorithm::ChaCha20Poly1305 variant
- ChaCha20-Poly1305 AEAD cipher
By default, QIMEM uses AES-256-GCM. The chacha feature is optional and not included in Docker builds.
Database Connection (Stateful Mode)
Connection Pooling
When using stateful mode with PostgreSQL, QIMEM uses sqlx with connection pooling:
use sqlx::postgres::PgPoolOptions;
let pool = PgPoolOptions::new()
.max_connections(5)
.connect(&database_url)
.await?;
TLS Configuration
DATABASE_URL=postgres://user:pass@localhost:5432/qimem?sslmode=disable
Migrations
Database migrations are applied automatically at startup:
sqlx::migrate!("./migrations")
.run(&pool)
.await?;
Migration files are located in migrations/ and copied into the Docker image.
Example Configurations
QIMEM_MODE=stateless
QIMEM_BIND=127.0.0.1:8080
RUST_LOG=debug
Configuration Errors
Invalid QIMEM_MODE
Error: QIMEM_MODE must be stateless|stateful
Fix: Set QIMEM_MODE to either stateless or stateful.
Invalid QIMEM_BIND
Error: invalid QIMEM_BIND: invalid socket address syntax
Fix: Ensure QIMEM_BIND uses IP:PORT format (e.g., 0.0.0.0:8080).
Missing DATABASE_URL
Error: DATABASE_URL is required for stateful mode
Fix: Set DATABASE_URL when using QIMEM_MODE=stateful.
Security Considerations
- Never commit
.env files with production credentials
- Use secret management (Vault, AWS Secrets Manager) for
DATABASE_URL
- Set
sslmode=require for production database connections
- Rotate database passwords regularly
- Use read-only replicas for analytics workloads
Loading Configuration
QIMEM uses dotenvy to load .env files:
use dotenvy::dotenv;
#[tokio::main]
async fn main() -> Result<()> {
dotenv().ok(); // Load .env if present
let config = Config::from_env()?;
// ...
}
Priority (highest to lowest):
- System environment variables
.env file in working directory
- Default values (if applicable)