Services
The services object is the core of a FlowLayer config.
Each entry defines one runtime service keyed by its service name.
Shape
{
"services": {
"db": {
"cmd": ["postgres", "-D", "./var/db"],
"port": 5432,
"ready": {
"type": "tcp"
}
},
"api": {
"cmd": ["go", "run", "./cmd/api"],
"dependsOn": ["db"],
"env": {
"PORT": "3000"
},
"port": 3000,
"logView": {
"maxEntries": 300
}
}
}
}
services.<name>
The object key is the service identifier. FlowLayer uses it in multiple places:
dependsOnreferences- runtime commands such as
start_serviceandstop_service - log entries and projected filenames such as
api.jsonl
The runtime does not normalize service names. Use one stable spelling everywhere.
dependsOn
Use dependsOn to declare service-to-service dependencies:
{
"services": {
"db": {
"cmd": ["postgres", "-D", "./var/db"]
},
"api": {
"cmd": ["go", "run", "./cmd/api"],
"dependsOn": ["db"]
}
}
}
Confirmed behavior:
- every dependency must reference another service in the same config
- empty dependency entries are rejected
- a service cannot depend on itself
- duplicate dependencies are removed during validation
- dependency order in the file does not control startup order
FlowLayer computes startup waves from the dependency graph. See Waves.
env
env is a map of environment variables for the service process:
{
"services": {
"api": {
"cmd": ["go", "run", "./cmd/api"],
"env": {
"PORT": "3000",
"APP_ENV": "dev"
}
}
}
}
FlowLayer starts from its own process environment, then applies services.<name>.env on top. A service value overrides an inherited value with the same key.
The same merged environment is used for cmd and stopCmd.
port
port is an optional integer hint with runtime consequences:
- it must be
>= 0 - if
port > 0, FlowLayer checks that the port is free before start - if
port > 0, FlowLayer verifies that the port is released before declaring stop complete - if
ready.typeistcpandready.portis omitted, FlowLayer usesservice.port
A missing or zero port means FlowLayer does not do port-based start/stop checks for that service.
logView
services.<name>.logView.maxEntries sets the default log limit for service-scoped get_logs requests:
{
"services": {
"api": {
"cmd": ["go", "run", "./cmd/api"],
"logView": {
"maxEntries": 300
}
}
}
}
When provided, maxEntries must be greater than 0.
For limit resolution rules, see Logs.
Other service fields
Other confirmed service fields are documented on dedicated pages:
cmdandstopCmd: Commandsready: Readinesskind:daemonby default, oroneshotfor services that are expected to exit after successful start
Naming guidance
Good service names are operational identifiers, not display labels.
Prefer names that are:
- short and stable
- descriptive in logs and commands
- safe to reuse in filenames and scripts
Typical names are api, db, users, or billing-worker.
Avoid spaces, punctuation-heavy names, or casual renames. In FlowLayer, the name is what other services depend on and what operators type into runtime commands.
For process fields, continue with Commands. For readiness gates, continue with Readiness.