devforge
Config-driven dev environment orchestrator for Rust workspaces. Define your Docker services, health checks, hooks, and process manager in a single TOML file.
Quick Start
1. Add the xtask crate to your workspace
# xtask/Cargo.toml
[]
= "xtask"
= "0.1.0"
= "2021"
= false
[]
= "0.2"
// xtask/src/main.rs
2. Add the cargo alias
# .cargo/config.toml
[]
= "run --package xtask --"
3. Create devforge.toml at your workspace root
= [".env"]
= ["docker", "cargo", "mprocs"]
[]
= "docker-compose.yml"
[[]]
= "postgres"
= ["docker", "compose", "exec", "-T", "postgres", "pg_isready", "-U", "myuser"]
= 30
[[]]
= "redis"
= "localhost:6379"
= 15
[]
= "mprocs.yaml"
[[]]
= "npm install"
= "web"
[]
= "web/node_modules"
4. Run it
Commands
| Command | Description |
|---|---|
dev |
Preflight checks, docker compose up, health checks, pre-launch hooks, process runner. Docker tears down automatically on exit. |
infra |
Docker compose up + health checks. Blocks until Ctrl+C, then tears down. |
| Custom | Any [[commands]] entry defined in your TOML. |
Configuration Reference
Top-level
# Files that must exist before starting (checked in order)
= [".env", "web/.env.local"]
# Commands that must be in PATH
= ["docker", "cargo", "node", "npm", "mprocs"]
Files listed in env_files are loaded into the process environment if they have no extension or a .env extension (e.g. .env, .env.local).
[docker]
[]
= "docker-compose.yml" # default
[[docker.health_checks]]
Three types of health checks (exactly one of cmd, url, or tcp must be set):
Command-based -- runs a command, success = exit code 0:
[[]]
= "postgres"
= ["docker", "compose", "exec", "-T", "postgres", "pg_isready", "-U", "myuser"]
= 30 # seconds, default 30
URL-based -- HTTP GET, success = 2xx response (must use http:// or https://):
[[]]
= "minio"
= "http://localhost:9000/minio/health/live"
= 30
TCP-based -- connects to a TCP socket, success = connection established:
[[]]
= "redis"
= "localhost:6379"
= 30
Health checks poll every 1 second until success or timeout. On failure, the error includes the service name, check type, and specific reason:
[devforge] ✗ health check failed: postgres (cmd: docker compose exec ...) — exit code 1: could not connect
[dev]
[]
= "mprocs.yaml" # default
[dev.runner]
Controls which process manager the dev command uses. Defaults to mprocs if omitted.
# Explicit mprocs (same as omitting the block entirely)
[]
= "mprocs"
# Run an arbitrary shell command instead of mprocs
[]
= "shell"
= "npm run dev"
# No process manager — just run hooks, then block until Ctrl+C
[]
= "none"
[[dev.hooks]]
Hooks run before the process runner launches. They execute via sh -c.
[[]]
= "npm install"
= "web" # optional, relative to workspace root
[]
= "web/node_modules" # only run if this path doesn't exist
[[commands]]
Define custom commands accessible via cargo xtask <name>:
[[]]
= "migrate"
= ["cargo", "run", "--release", "--package", "my-api", "--", "migrate"]
= "Run database migrations"
= true # start docker infra first (default: false)
How It Works
cargo xtask dev
|
v
Preflight: check env files, load .env, verify tools
|
v
docker compose up -d
|
v
Health checks (poll until ready or timeout)
|
v
Pre-launch hooks (conditional)
|
v
Process runner (mprocs TUI / shell cmd / Ctrl+C wait)
|
v (on exit)
docker compose down
License
MIT