A fast, extensible CLI for managing local and remote development environments. Works with any Bazel-managed monorepo.
Local development tooling tends to collapse under three forces:
- Complexity accumulates — custom Bash scripts, Python wrappers, and hand-maintained Docker Compose files become a second codebase that nobody owns. 30+ configuration combinations and 2+ minute cold starts follow.
- Environments drift — local, remote, and CI each have their own setup path. The same service behaves differently in each target.
- Shared clusters become load-bearing — engineers stop trusting their local stack and validate changes against shared test environments, creating queues, flakiness, and tight coupling.
DevDock replaces all of this with a single profile and a single command:
devdock start <profile>Sub-30 second cold start. No scripts. No manual configuration. The same profile runs your stack locally, on a remote cloud workspace, and in CI sandboxes — same commands, same behavior, everywhere.
Used by 400+ engineers across 50+ services in a polyglot monorepo. Environment-related issues reduced by 75%. Onboarding time: under 10 minutes.
- Docker Compose — works for simple stacks but doesn't compose across teams, has no remote mode, and requires hand-authoring configs for every service. No profile inheritance or plugin model.
- Telepresence — excellent for intercepting live cluster traffic, but presupposes a running cluster and doesn't help spin one up reproducibly per developer or per CI run.
- Garden — powerful, but introduces a large new abstraction layer with its own graph model and significant operational complexity.
DevDock's approach: generate Tiltfiles and defer orchestration to Tilt, which already solves dependency ordering, live reload, and service health. DevDock adds the profile layer, remote/CI modes, and plugin system on top of a proven foundation rather than replacing it.
DevDock uses an explicit lifecycle state machine to drive startup. Each state transition fires plugin hooks, making the pipeline fully extensible:
devdock start <profile>
│
├── Initializing ─── Parse CLI args, find workspace root
│
├── ProfileLoaded ── Load profile YAML, validate, resolve dependencies
│ └── hook: after_profile_loaded
│
├── PluginsReady ─── Load devdock.toml, spawn plugin processes
│ └── hook: before_infra_ready (auth, cloud credentials)
│
├── InfraReady ───── Docker check, networks, port allocation
│ └── hook: before_config_generated (fetch remote configs)
│
├── ConfigReady ──── Generate temp_profile.yaml, devdock.ini
│ └── hook: after_config_generated (enrich configs)
│
├── TiltfileReady ── Discover services, resolve deps, generate Tiltfile
│ └── hook: before_tilt (last-minute config)
│
├── TiltRunning ──── Spawn `tilt up`, extract Starlark libs
│ └── hook: after_tilt (telemetry: session started)
│
├── ResourcesStarting ── Per-resource startup with hooks:
│ │ hook: before_resource_start(name, kind)
│ │ hook: after_resource_start(name, kind)
│ └── e.g., sql-hydrator runs after SQL becomes healthy
│
├── Running ──────── All resources healthy, steady state
│ └── hook: after_ready (notifications: "DevDock ready in 3m")
│
├── Stopping ─────── Ctrl+C or Tilt exits
│ └── hook: before_stop (final telemetry flush)
│
└── Stopped ──────── Cleanup complete
└── hook: after_stop
Any state → Failed → hook: on_error → Stopping
YOUR REPO (committed): DEVDOCK BINARY (shipped):
├── .devdock/devdock.toml ├── Starlark libraries
├── devdock/config/services/ │ ├── service.Tiltfile
│ ├── api/devdock_config.json │ ├── docker.Tiltfile
│ └── worker/devdock_config.json │ ├── bazel.Tiltfile
├── devdock/config/infra/ │ └── templates/*.tpl
│ ├── sql/docker-compose.yaml ├── Default infra compose
│ └── redis/docker-compose.yaml │ ├── sql, redis, opensearch
├── devdock/profiles/ │ ├── memcached, pubsub
│ ├── default.yaml │ └── nginx
│ └── minimal.yaml └── Plugin SDK
└── source code (anywhere)
# From source
git clone https://github.com/aryan-agrawal-glean/devdock.git
cd devdock
cargo install --path crates/devdock-clicd my-monorepo
devdock init
# Edit .devdock/devdock.toml with your project settingsmkdir -p devdock/config/services/apidevdock/config/services/api/devdock_config.json:
{
"type": "python",
"bazel_target": "//services/api:api",
"binary_mount": "services/api",
"port": "8080",
"dependencies": ["sql", "redis"],
"env": { "PORT": "8080" },
"healthcheck": {
"test": ["CMD", "curl", "-f", "http://localhost:8080/health"]
}
}devdock/profiles/default.yaml:
project: my-project
infra:
sql:
type: local
redis:
type: local
services:
api:
type: localdevdock start default
# → Lifecycle machine runs through all states
# → Generates configs, builds with Bazel, starts Docker containers
# → Tilt UI at http://localhost:10350[project]
name = "my-project"
domain = "localhost"
services_dir = "devdock/config/services"
infra_dir = "devdock/config/infra"
[cloud]
platform = "google" # google, aws, azure, none
project = "my-gcp-project"
region = "us-central1"
[telemetry]
enabled = true
backend = "stdout" # stdout, bigquery, datadog, external
[remote]
provider = "ssh" # ssh, coder
[diagnostics]
reporter = "stdout" # stdout, jira
[plugins.hooks]
before_infra_ready = ["my-auth-plugin"]
after_config_generated = ["my-config-plugin"]
after_tilt = ["devdock-plugin-bigquery-sync"]
after_ready = ["devdock-plugin-slack-notifier"]
before_stop = ["devdock-plugin-bigquery-sync"]
on_error = ["devdock-plugin-jira-reporter"]
on_report = ["devdock-plugin-jira-reporter"]
[plugins.resource_hooks.sql]
after_start = ["devdock-plugin-sql-hydrator"]
[plugins.resource_hooks.opensearch]
after_start = ["devdock-plugin-opensearch-hydrator"]| Field | Required | Description |
|---|---|---|
type |
No | python, go, java, custom (default: custom) |
bazel_target |
No | Bazel build target (e.g., //services/api:api) |
binary_mount |
No | Path to built binary relative to repo root |
port |
No | Service port |
dependencies |
No | Other services/infra this service needs |
env |
No | Environment variables |
healthcheck |
No | Docker healthcheck config |
project: my-project
infra:
sql:
type: local # local: Docker container, remote: kubectl port-forward
redis:
type: local
services:
api:
type: local # local: Bazel build + Docker, remote: port-forward
env:
DEBUG_MODE: "true"
hot_reload: enable
worker:
type: localDevDock fires 14 plugin hooks at state transitions. Plugins only need to handle hooks they care about.
| Hook | When | Example Use |
|---|---|---|
after_profile_loaded |
Profile YAML loaded | Validate custom fields |
before_infra_ready |
Before Docker/ports | Cloud auth, credentials |
after_infra_ready |
After Docker/ports | Custom network setup |
before_config_generated |
Before config files | Fetch remote configs (GCS/S3) |
after_config_generated |
After config files | Write devdock.ini, enrich configs |
before_tilt |
Before Tilt spawns | Last-minute config |
after_tilt |
After Tilt is up | Telemetry: session started |
before_resource_start |
Before resource starts | Per-resource setup |
after_resource_start |
After resource healthy | SQL hydration, search reindex |
after_ready |
All resources healthy | Slack: "DevDock ready in 3m" |
before_stop |
Ctrl+C / exit signal | Final telemetry flush |
after_stop |
After cleanup | Post-cleanup actions |
on_error |
Unrecoverable error | Create Jira ticket |
on_report |
devdock report |
Create bug report |
DevDock includes an MCP (Model Context Protocol) server for AI agent integration. This lets Claude Code, Cursor, Codex, and other AI tools control DevDock directly.
Add to your project's .mcp.json:
{
"mcpServers": {
"devdock": {
"command": "devdock",
"args": ["mcp", "serve"]
}
}
}| Tool | Description |
|---|---|
devdock_start |
Start a profile (dry-run or real) |
devdock_stop |
Stop current instance |
devdock_status |
Get all resource health from Tilt API |
devdock_resource_status |
Get health of a specific resource |
devdock_logs |
Get recent logs for a service |
devdock_profile_list |
List available profiles |
devdock_profile_show |
Show profile details |
devdock_validate |
Validate a profile |
devdock_plugin_create |
Scaffold a new plugin |
devdock_plugin_list |
List installed plugins |
devdock_lifecycle_state |
Get current lifecycle state |
devdock_config_show |
Show devdock.toml contents |
DevDock uses external plugins for cloud integrations. Plugins are standalone executables that communicate via JSON over stdin/stdout.
| Plugin | Location | Hooks |
|---|---|---|
bigquery-sync |
plugins/telemetry/ |
after_tilt, after_ready, before_stop |
slack-notifier |
plugins/notifications/ |
after_ready, on_error |
jira-reporter |
plugins/diagnostics/ |
on_error, on_report |
Community-maintained plugins are available in the devdock-plugins-library — a curated collection of plugins for common infrastructure (databases, queues, caches, observability stacks, notification systems). See the plugin library for the full catalog and contribution guide.
Organization-specific plugins live in separate repos. For example, your org's plugins can live in a private devdock-plugins repo and be installed via cargo install.
cargo install --path plugins/telemetry/bigquery-syncdevdock plugin create my-metrics --type telemetry --language pythonPlugin templates available for Rust, Python, Go, and Bash.
devdock binary plugin executable
│ │
├─ {"method":"initialize", │
│ "config":{...}} ──────────────→│
│ ←────────────────────────────── {"status":"ok"}
│ │
├─ {"method":"after_tilt", │
│ "params":{...}} ──────────────→│
│ ←────────────────────────────── {"status":"ok"}
│ │
├─ {"method":"shutdown"} ─────────→│
│ ←────────────────────────────── {"status":"ok"}
DevDock is bring-your-own-infra. You define infrastructure components in your profile YAML and provide either a devdock_config.json or a docker-compose.yaml for each one.
For each infra component in your profile, DevDock checks (in order):
- Custom Tiltfile —
devdock/infra/{name}/Tiltfile(full control) - Custom compose —
devdock/infra/{name}/docker-compose.yaml(your own image/config) - Config-generated — auto-generated from
devdock_config.jsonwith"kind": "infra" - Built-in default — shipped with the devdock binary (extracted at runtime)
DevDock ships default compose files for common infrastructure. These are compiled into the binary and used as a fallback when you don't provide your own:
| Component | Image | Port |
|---|---|---|
| MySQL | mysql:8.0 |
3306 |
| Redis | redis:7-alpine |
6379 |
| OpenSearch | opensearch:2.11 |
9200 |
| Memcached | memcached:1.6 |
11211 |
| PubSub | GCP emulator | 8085 |
| Nginx | nginx:alpine |
8321 |
To override a default, add your own docker-compose.yaml to devdock/infra/{name}/ in your repo. The infra directory location is configurable via infra_dir in devdock.toml.
# Core
devdock init # Initialize project
devdock start <profile> # Start development environment
devdock start <profile> -s svc # Start specific services only
devdock stop # Stop everything
devdock status # Check service health
devdock list # List all instances
devdock cleanup # Clean containers and files
devdock validate <profile> # Validate profile config
# Remote development
devdock start <profile> -m remote # Start on remote workspace
devdock sync start # Start file sync
devdock ports forward --all # Forward remote ports
# Plugins
devdock plugin list # Show installed plugins
devdock plugin create <name> # Create external plugin
# MCP server
devdock mcp serve # Start MCP server (stdin/stdout)
# Diagnostics
devdock report # Generate and submit bug report
devdock docker check # Check Docker status
devdock profile list # List available profiles
devdock monitor # Monitor startup healthdevdock/
├── crates/ # Rust source (12 crates, zero cloud-specific code)
│ ├── devdock-cli/ # CLI entry point, commands
│ ├── devdock-lifecycle/ # Lifecycle state machine, hooks, contexts
│ ├── devdock-mcp/ # MCP server for AI agent integration
│ ├── devdock-core/ # Core types, Tiltfile generator, plugin manager
│ ├── devdock-config/ # Profile loading, validation, watch patterns
│ ├── devdock-state/ # SQLite instance tracking
│ ├── devdock-codegen/ # Config code generation
│ ├── devdock-remote/ # Remote dev (SSH, Coder)
│ ├── devdock-sync/ # File sync daemon
│ ├── devdock-monitor/ # Startup health monitoring
│ ├── devdock-telemetry/ # Telemetry collection + file emitter
│ └── devdock-diagnostics/ # Bug reporting
├── plugins/
│ ├── sdk/ # Plugin SDK (Rust crate, JSON protocol)
│ ├── telemetry/
│ │ └── bigquery-sync/ # Telemetry → BigQuery
│ ├── notifications/
│ │ └── slack-notifier/ # Slack notifications
│ ├── diagnostics/
│ │ └── jira-reporter/ # Jira bug reports
│ ├── templates/ # Plugin scaffolding (Rust, Python, Go, Bash)
│ └── examples/ # Example plugins (Prometheus, Slack)
├── skills/ # Claude Code skills
│ ├── devdock-start.md
│ ├── devdock-debug.md
│ ├── devdock-plugin-create.md
│ └── devdock-profile-create.md
├── lib/ # Shipped Starlark libraries
│ ├── service.Tiltfile
│ ├── docker.Tiltfile
│ ├── bazel.Tiltfile
│ └── templates/ # Dockerfile templates
├── infra/ # Default infra compose files
├── tests/fixtures/ # Test repos
├── docs/ # Documentation
├── .mcp.json # MCP server config for AI agents
├── CLAUDE.md # Claude Code development guide
└── CONTRIBUTING.md
DevDock ships with Claude Code skills for agentic development:
| Skill | What it does |
|---|---|
/devdock-start |
Start a profile, validate, check health |
/devdock-debug |
Diagnose failing services via Tilt API + logs |
/devdock-plugin-create |
Scaffold a plugin targeting a lifecycle hook |
/devdock-profile-create |
Create a profile interactively |
The MCP server (devdock mcp serve) provides 12 tools for AI agents. See .mcp.json for configuration.
cargo build # Build all crates
cargo test --workspace # Run tests (132 tests)
cargo clippy --workspace # Lint (0 warnings required)
cargo fmt --check # Format check
cargo install --path crates/devdock-cli --debug --force # Install dev buildcd plugins/telemetry/bigquery-sync && cargo buildThe devdock binary has zero cloud-specific code. It contains:
- Core CLI commands + lifecycle state machine
- MCP server for AI agent integration
- Telemetry collection (sync via external plugins)
- Shipped Starlark libraries
- Default infra compose files
- Plugin SDK protocol handler
# Install from source (OSS)
cargo install --path crates/devdock-cli
# Or download pre-built binary from GitHub Releases
curl -L https://github.com/aryan-agrawal-glean/devdock/releases/latest/download/devdock-$(uname -s)-$(uname -m) -o devdock
chmod +x devdockCloud integrations ship as separate plugin binaries:
# Install devdock (same binary for everyone)
cargo install devdock
# Install organization plugins
cargo install --git https://github.com/your-org/devdock-plugins devdock-plugin-bigquery-sync
cargo install --git https://github.com/your-org/devdock-plugins devdock-plugin-config-fetcherThe plugin binaries go to ~/.cargo/bin/ (in PATH). DevDock finds them by name.
See CONTRIBUTING.md for development setup, code style, and how to add new backends.
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.