Configuration
Complete reference for fuku.yaml – services, tiers, profiles, and more.
Generate a config template with fuku init, or create fuku.yaml manually in your project root.
Service definitions
Each service is defined with a name, directory, and optional settings:
services:
backend:
dir: backend # Path to service directory
command: go run cmd/main.go # Custom start command (optional)
tier: platform # Startup tier (optional)
readiness: # Health check (optional)
type: http
url: http://localhost:8080/health
timeout: 30s
interval: 500ms
logs: # Log output filter (optional)
output: [stdout, stderr]
watch: # Hot-reload config (optional)
include: ["**/*.go"]
ignore: ["**/*_test.go"]
shared: ["pkg/common"]
debounce: 1s
env: # Files surfaced in the TUI info aside (optional)
files: [.env, .env.local, .env.development, .env.development.local]| Field | Description |
|---|---|
dir | Path to the service directory |
command | Custom start command (default: make run, which requires a Makefile with a run target in the service directory). Runs via sh -c, so shell features like pipes and env vars work |
tier | Startup tier for ordering. A service without one gets defaults.tier when set, else the default tier (runs last) |
readiness | Health check configuration (see Readiness Checks) |
logs.output | Output streams to capture: stdout, stderr, or both (default: both) |
watch | Hot-reload file watching configuration (see Hot-Reload) |
env.files | List of .env files (relative to dir) parsed and shown in the TUI info aside's env tab. Defaults to .env, .env.local, .env.development, .env.development.local. Values are display-only — fuku does not export them to the child process |
Tiers
Tiers control startup ordering. Services in earlier tiers start (and become ready) before later tiers begin. The order is determined by the first occurrence of each tier name in your config.
Common tier naming pattern:
- foundation – core services (auth, config, gateway)
- platform – business logic services
- edge – client-facing services
Set a project-wide fallback tier with defaults.tier:
defaults:
tier: foundation # Tier for a service that sets noneKey points:
- Tier order is defined by first appearance in the YAML file
- Services within each tier are sorted alphabetically by name
- A service without a tier gets
defaults.tierwhen it's set, else it's placed in adefaulttier that runs last - Tier names are case-insensitive and whitespace is trimmed
- You can use any tier names you want –
infrastructure,middleware,api,frontend, etc.
Profiles
Profiles group services for batch operations:
profiles:
default: "*" # All services
backend: [auth, backend] # Named list of services"*"– selects all defined services- A list of service names – selects only those services
- The
defaultprofile runs when you just typefuku
Concurrency
concurrency:
workers: 5 # Max concurrent service starts (default: 5)Controls how many services can start in parallel within a single tier.
Retry
retry:
attempts: 3 # Max retry attempts (default: 3)
backoff: 500ms # Initial backoff duration (default: 500ms)Log Streaming
logs:
buffer: 1000 # Broadcast channel depth for socket log streaming (default: 1000)
history: 5000 # Number of recent log messages kept in memory for replay (default: 5000)Logging
logging:
format: console # "console" or "json"
level: info # debug, info, warn, errorServer
Built-in REST API for external control. It listens on 127.0.0.1:3858 by default. Set server.listen to "" or none, or FUKU_API_DISABLED=1, to turn it off. A missing listen keeps the default. The token is optional. When server.auth.token is set, every endpoint except the probes (/api/v1/live, /api/v1/ready) requires a bearer token.
server:
listen: "127.0.0.1:3858" # loopback address, default; "" or none turns the API off
auth:
token: "my-dev-token" # optional, requires a bearer token when setLocal overrides
Create fuku.override.yaml (or fuku.override.yml) next to your base config to add local customizations without modifying the shared project config. Override files are typically .gitignored.
services:
api:
command: "dlv debug ./cmd/main.go" # override start command
watch:
include: ["*.templ"] # appended to base includes
debug-tool:
dir: tools/debug # add a local-only service
exclude:
- heavy-worker # skip this service locally
logging:
level: debug # override log levelMerge Rules
| Type | Behavior |
|---|---|
| Scalar | Override replaces base |
| Map | Deep merge recursively (base key order preserved) |
| Array | Override items appended after base items (no deduplication) |
| Null | Removes the key from merged config (e.g. watch: null) |
| Mismatched types | Override replaces base |
Important Notes
- Override loading is automatic when using default config discovery (
fuku.yaml/fuku.yml) - Explicit
--configskips the override merge - Fuku still checks for the override file under
--config. An error other than a missing file, such as a permission error, fails the load - An override file without a base config is ignored
- Null removal applies to the merged YAML – some removed keys may still have runtime defaults (e.g.
logging: nullstill gets default log level) - If both
fuku.override.yamlandfuku.override.ymlexist,.yamlwins
Excluding services
Use the top-level exclude list to skip services at discovery time without mutating the service catalog. Excluded services keep their definitions in services: – so profile lists referencing them still pass config validation – and fuku run silently drops them at startup. This is the recommended way to disable services locally via fuku.override.yaml.
exclude:
- heavy-worker
- flaky-integration- Entries are trimmed of whitespace and deduplicated
- Names that aren't defined in
services:are ignored at runtime - Profile references to excluded services remain valid – they're filtered out before startup
YAML anchors
Use YAML anchors (&) and merge keys (<<: *) to avoid repeating common configuration. Top-level keys prefixed with x- are ignored by fuku and serve as anchor definitions.
x-readiness-http: &readiness-http
type: http
timeout: 30s
interval: 500ms
x-watch: &watch
include: ["**/*.go"]
ignore: ["**/*_test.go"]
debounce: 1s
services:
api:
dir: ./api
readiness:
<<: *readiness-http
url: http://localhost:8080/health
watch:
<<: *watchFull example
version: 1
x-readiness-http: &readiness-http
type: http
timeout: 30s
interval: 500ms
x-readiness-log: &readiness-log
type: log
pattern: "Service ready"
timeout: 30s
x-logs: &logs
output: [stdout, stderr]
x-watch: &watch
include: ["**/*.go"]
ignore: ["**/*_test.go"]
shared: ["pkg/common"]
debounce: 1s
services:
auth:
dir: auth
tier: foundation
command: go run cmd/main.go
readiness:
<<: *readiness-http
url: http://localhost:8081/health
backend:
dir: backend
tier: platform
command: go run cmd/main.go
readiness:
<<: *readiness-http
url: http://localhost:8080/health
logs:
<<: *logs
watch:
<<: *watch
web:
dir: frontend
tier: edge
readiness:
<<: *readiness-http
url: http://localhost:3000/health
profiles:
default: "*"
backend: [auth, backend]
concurrency:
workers: 5
retry:
attempts: 3
backoff: 500ms
logs:
buffer: 1000
history: 5000
logging:
format: console
level: info
server:
listen: "127.0.0.1:3858"
auth:
token: "my-dev-token"