Revali reads configuration in two ways. Pick one by asking when the value is known:
| Kind | Set with | Read with | Changing it requires |
|---|---|---|---|
| Runtime (deployment) | The process environment (export, Docker, Kubernetes) |
Env.current |
A restart |
| Compile time (build) | --dart-define, --dart-define-from-file |
String.fromEnvironment and friends |
A rebuild |
Secrets and anything that differs between staging and production belong at runtime. That way one build can be promoted from one environment to the next unchanged.
Env: Runtime Values#
import 'package:revali_router/revali_router.dart';
@App()
final class MainApp extends AppConfig {
MainApp() : super.fromEnv();
@override
Future<void> configureDependencies(DI di) async {
final env = Env.current;
di.registerLazySingleton<Database>(
() => Database(
host: env.string('DB_HOST', orElse: 'localhost'),
port: env.integer('DB_PORT', orElse: 5432),
password: env.require('DB_PASSWORD'), // fails at startup, by name
),
);
}
}
DB_PASSWORD=secret dart run revali dev
| Method | Returns | When unset | When invalid |
|---|---|---|---|
env['NAME'] | String? | null | |
env.has('NAME') | bool | false | |
env.string('NAME', orElse: …) |
String |
orElse |
|
env.require('NAME') |
String |
throws | |
env.integer('NAME', orElse: …) |
int |
orElse |
throws |
env.boolean('NAME', orElse: …) |
bool |
orElse |
throws |
env.uri('NAME', orElse: …) |
Uri |
orElse, or throws if there is no orElse |
throws |
-
An empty or blank value counts as unset. Orchestrators often inject
""for variables nobody configured. -
A malformed value throws instead of falling back. For example,
PORT=eightystops the server rather than silently using8080. -
booleanacceptstrue/1/yes/onandfalse/0/no/off, in any case. -
In tests, pass a map instead of changing the real environment:
Env({'PORT': '9000'}).
AppConfig.fromEnv#
AppConfig.fromEnv reads host and port from the environment, so the same build runs on any platform:
MainApp() : super.fromEnv();
| Parameter | Default |
|---|---|
hostVariable | 'HOST' |
portVariable | 'PORT' |
defaultHost | '0.0.0.0' |
defaultPort | 8080 |
prefix, workers, backlog |
same as AppConfig |
env | Env.current |
-
The host defaults to
0.0.0.0, notlocalhost. Inside a container, a server bound tolocalhostrefuses every connection from outside the container. -
The port comes from
PORT. Cloud Run, Heroku, Render and Fly setPORT, and so dorevali upandrevali compose. -
The constructor isn't
const, so your app's constructor can't beconsteither.
Compile-Time Values#
dart run revali dev --dart-define=APP_NAME=orders
dart run revali build --dart-define-from-file=.env.production
APP_NAME=orders
MAX_CONNECTIONS=50
const appName = String.fromEnvironment('APP_NAME', defaultValue: 'app');
const maxConnections = int.fromEnvironment('MAX_CONNECTIONS', defaultValue: 100);
Both flags can be repeated. The values are compiled into the program, and with a build: section
they are compiled into the executable. Don't use them for secrets, and keep .env files out of source control.