Examples
Real-world configuration patterns for common project setups.
E-commerce Platform
A Go microservices platform with 5 tiers, readiness checks, hot-reload, and multiple profiles. Uses YAML anchors to keep the config DRY.
YAML Anchors
Define reusable readiness, logging, and watch blocks at the top of your config. Services reference them with *anchor or merge with <<: *anchor to override specific fields.
version: 1
# ── Reusable anchors ──
x-readiness-http: &readiness-http
type: http
timeout: "30s"
interval: "500ms"
x-readiness-tcp: &readiness-tcp
type: tcp
timeout: "30s"
interval: "500ms"
x-readiness-log: &readiness-log
type: log
pattern: "Server started"
timeout: "60s"
x-logs: &logs
output: [stdout, stderr]
x-watch: &watch
include:
- "**/*.go"
- "**/*.yml"
- "**/*.yaml"
ignore:
- ".git/**"
- ".idea/**"
- "vendor/**"
- "**/*_test.go"
- "**/*_mock.go"
shared:
- "pkg/common/**"
- "pkg/rpc/**"
debounce: 1s Services
Services are organized into tiers. fuku starts all services in a tier, waits for readiness, then moves to the next tier.
services:
# Foundation — auth, users, shared infrastructure
auth-service:
dir: auth-service
tier: foundation
readiness:
<<: *readiness-tcp
address: "localhost:3001"
logs: *logs
users-service:
dir: users-service
tier: foundation
readiness:
<<: *readiness-tcp
address: "localhost:3002"
logs: *logs
watch: *watch
inventory-service:
dir: inventory-service
tier: foundation
readiness:
<<: *readiness-tcp
address: "localhost:3003"
logs: *logs
# Core — main business entities
catalog-service:
dir: catalog-service
tier: core
readiness:
<<: *readiness-tcp
address: "localhost:3004"
logs: *logs
watch: *watch
orders-service:
dir: orders-service
tier: core
readiness:
<<: *readiness-tcp
address: "localhost:3005"
logs: *logs
cart-service:
dir: cart-service
tier: core
readiness:
<<: *readiness-tcp
address: "localhost:3006"
logs: *logs
# Platform — payments, shipping, notifications
payments-service:
dir: payments-service
tier: platform
readiness:
<<: *readiness-tcp
address: "localhost:3007"
shipping-service:
dir: shipping-service
tier: platform
readiness:
<<: *readiness-tcp
address: "localhost:3008"
notifications-service:
dir: notifications-service
tier: platform
readiness:
<<: *readiness-tcp
address: "localhost:3009"
search-service:
dir: search-service
tier: platform
readiness:
<<: *readiness-http
url: "http://localhost:3010/health"
# Background — workers, async processing
worker:
dir: worker
tier: background
readiness:
<<: *readiness-log
pattern: "Worker started"
logs: *logs
# Edge — client-facing API gateways
storefront-api:
dir: storefront-api
tier: edge
readiness:
<<: *readiness-http
url: "http://localhost:3000/health"
logs: *logs
watch: *watch
backoffice-api:
dir: backoffice-api
tier: edge
readiness:
<<: *readiness-http
url: "http://localhost:3100/health"
logs: *logs
storefront-web:
dir: storefront-web
tier: edge
command: npm run dev
readiness:
<<: *readiness-http
url: "http://localhost:4000"
logs: *logs
watch:
include: ["src/**"]
debounce: 500ms
backoffice-web:
dir: backoffice-web
tier: edge
command: npm run dev
readiness:
<<: *readiness-http
url: "http://localhost:4100"
logs: *logs Profiles
Profiles let you run subsets of services. Use "*" to include everything, or list specific services.
profiles:
default: "*"
# Storefront and its direct dependencies
storefront:
- storefront-web
- storefront-api
- auth-service
- users-service
- catalog-service
- cart-service
- inventory-service
- search-service
# Checkout flow
checkout:
- storefront-web
- storefront-api
- auth-service
- users-service
- cart-service
- orders-service
- payments-service
- shipping-service
- inventory-service
- notifications-service
- worker
# Backoffice
backoffice:
- backoffice-web
- backoffice-api
- auth-service
- users-service
- orders-service
- inventory-service
- catalog-service
concurrency:
workers: 10
retry:
attempts: 5
backoff: 1s
logs:
buffer: 1024
logging:
level: info
format: console Running
# Start everything
fuku
# Start only the storefront profile
fuku run storefront
# Start checkout without TUI
fuku run checkout --no-ui Key Patterns
YAML Anchors for DRY Config
Prefix anchor names with x- to keep them separate from fuku config keys. Use <<: *anchor to merge and override individual fields like address or url.
Tier Ordering
Think about which services other services depend on. Put those in earlier tiers. A common pattern:
- foundation — auth, users, inventory
- core — main business entities (catalog, orders, cart)
- platform — payments, shipping, notifications, search
- background — workers, async processors
- edge — APIs, frontends
Custom Commands
By default, fuku runs make run in each service directory. The command option lets you override this with any shell command — useful for running the same codebase in a different mode, spinning up tooling, or wrapping a service with extra steps.
For example, you can add a Swagger UI alongside your backend without changing the backend code. Define a second service pointing at the same directory with a custom command:
services:
backend:
dir: backend
tier: core
readiness:
type: http
url: "http://localhost:3000/health"
backend-swagger:
dir: backend
tier: edge
command: >-
make swagger &&
docker run --rm --name backend-swagger
-p 8080:8080
-v $(pwd)/docs/swagger.json:/usr/share/nginx/html/swagger.json
-v $(pwd)/docs/nginx.conf:/etc/nginx/conf.d/default.conf
nginx:alpine
readiness:
type: http
url: "http://localhost:8080"
profiles:
default: [backend]
docs: [backend, backend-swagger]
Run fuku run docs and you get your backend plus live Swagger UI at localhost:8080 — all managed by fuku.
Single containers work well with command because fuku owns the process — it can stop, restart, and check readiness of each container individually. Avoid running Docker Compose inside fuku: compose manages its own process tree, so fuku loses visibility into individual container health, logs get duplicated, and hot-reload restarts the entire stack instead of a single service.
For infrastructure like databases and queues, run docker compose up separately and let fuku manage your application services on top.
Selective Watch
Only enable watch on services you actively modify. Watching all services causes unnecessary restarts during branch switches or pulls. See Troubleshooting for details.
Readiness Check Types
- TCP — best for gRPC services. Checks if the port is accepting connections.
- HTTP — best for REST APIs. Hits a health endpoint.
- Log — best for workers and services without a network interface. Matches a log pattern.