serviceconf
Environment variable configuration with file-based secrets support
Load configuration from environment variables with native support for file-based secrets (Kubernetes Secrets, Docker Secrets). This is the primary feature that distinguishes serviceconf from other environment variable configuration libraries.
Key Feature: File-based Secrets
The #[conf(from_file)] attribute allows reading secrets from files mounted by Kubernetes or Docker, avoiding the security risks of exposing secrets directly in environment variables:
use ServiceConf;
Why file-based secrets?
- ✅ More secure: Secrets stored in files, not environment variables (which can leak in logs, process lists, etc.)
- ✅ Kubernetes native: Works seamlessly with Kubernetes Secrets mounting
- ✅ Docker Secrets: Direct support for Docker Swarm secrets
- ✅ Flexible: Falls back to direct environment variables for local development
Loading priority:
- Direct env var (
API_KEY) - for local development - File path from env var (
API_KEY_FILE) - for production
Kubernetes Secret example:
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
stringData:
api-key: "prod-api-key-123"
db-password: "secure-password"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myservice
spec:
template:
spec:
containers:
- name: app
image: myservice:latest
env:
- name: API_KEY_FILE
value: /etc/secrets/api-key
- name: DATABASE_PASSWORD_FILE
value: /etc/secrets/db-password
volumeMounts:
- name: secrets
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secrets
secret:
secretName: app-secrets
items:
- key: api-key
path: api-key
- key: db-password
path: db-password
Local development (no files needed):
Installation
[]
= { = "https://github.com/lambdalisue/rs-serviceconf" }
Quick Start
use ServiceConf;
Local development (direct environment variable):
Production (Kubernetes/Docker with file-based secret):
Other Features
Default Values
Use #[conf(default)] for Default::default() or #[conf(default = value)] for explicit values.
Optional Fields
Use Option<T> for optional fields. Returns None if not set.
Prefix
Use #[conf(prefix = "...")] at struct level to prefix all environment variables.
Custom Environment Variable Names
Use #[conf(name = "...")] to override the auto-generated name.
Custom Deserializers
Use #[conf(deserializer = "function")] for complex types or custom parsing.
// Custom parser
Attribute Reference
Struct-level Attributes
| Attribute | Description |
|---|---|
#[conf(prefix = "PREFIX_")] |
Add prefix to all environment variable names |
Field-level Attributes
| Attribute | Description | When to Use |
|---|---|---|
#[conf(name = "VAR")] |
Override environment variable name | When field name differs from desired env var |
#[conf(default)] |
Use Default::default() if not set |
For optional fields with sensible defaults |
#[conf(default = value)] |
Use explicit default value | When you need a specific default |
#[conf(from_file)] |
Support {VAR}_FILE pattern |
For secrets stored in files |
#[conf(deserializer = "fn")] |
Use custom parser | For complex types (Vec, HashMap, etc.) |
Type Behavior
| Type | When Env Var Missing | When Env Var Set |
|---|---|---|
T (no attribute) |
Error | Parsed with FromStr |
T + #[conf(default)] |
Default::default() |
Parsed with FromStr |
T + #[conf(default = value)] |
Uses value |
Parsed with FromStr |
Option<T> |
None |
Some(parsed_value) |
T + #[conf(deserializer = "fn")] |
Error | Parsed with custom function |
Combining Attributes
Multiple attributes can be combined:
Invalid combinations (compile errors):
Option<T>+#[conf(default)]→ Option already defaults to None#[conf(deserializer = "...")]+#[conf(default)]→ Not supported
Examples
See the examples/ directory for complete working examples:
| Example | Features Demonstrated |
|---|---|
basic.rs |
Required fields, explicit default values |
optional_fields.rs |
Option<T> for optional fields |
default_trait.rs |
#[conf(default)] using Default trait |
prefix.rs |
#[conf(prefix = "...")] at struct level |
file_based_secrets.rs |
#[conf(from_file)] for Kubernetes/Docker secrets |
custom_names.rs |
#[conf(name = "...")] for custom env var names |
complex_types.rs |
Vec, HashMap with JSON deserializer |
custom_deserialize_fn.rs |
Custom deserializer functions |
comprehensive.rs |
Multiple features combined |
Run with: cargo run --example <name>
Error Handling
match from_env
Example errors:
Environment variable 'DATABASE_URL' is required but not setFailed to parse environment variable 'PORT' as u16: invalid digit found in stringFailed to read file '/etc/secrets/key' for environment variable 'API_KEY_FILE': No such file or directory
Testing
License
Licensed under MIT license (LICENSE or http://opensource.org/licenses/MIT).
Contribution
Contributions are welcome! Please feel free to submit a Pull Request.