A standalone, stack-agnostic TUI dashboard for local Docker Compose development environments. Replaces interleaved docker compose logs -f output with a multiplexed terminal UI showing log streams, container health, resource usage, and custom sidecar processes.
Think SST Dev Console, but decoupled from any cloud provider or package manager.
mirador (n.) — an observation tower or turret providing an extensive view. From Spanish mirar, "to look."
- Multiplexed log viewer — color-coded, filterable, searchable log streams from all containers and processes in one view
- Container overview — status, CPU/memory sparklines, uptime, and port mappings at a glance
- Custom processes — run sidecar processes (Tailscale, Stripe CLI, etc.) alongside your containers
- Per-container metrics — CPU, memory, and network I/O charts with rolling history
- Drill-down detail view — inspect individual containers or processes with dedicated log streams
- Keyboard-driven — vim-style navigation, fast and information-dense
- Curated themes — Catppuccin Mocha (default), Tokyo Night, Dracula
- Fast startup — ready before your containers are
cargo install --path .Or build from source:
cargo build --release
# Binary at ./target/release/mirador# Run from any directory with a docker-compose.yml — auto-discovers everything
mirador
# Point to a specific config
mirador --config path/to/mirador.tomlCreate a mirador.toml in your project root. All fields are optional — mirador auto-discovers your Compose file and infers the project name from the directory.
[compose]
file = "docker-compose.yml" # optional, auto-detected
project = "myapp" # optional, inferred from directory name
# Custom processes — things that need to run but aren't containers
[[process]]
name = "tailscale-funnel"
command = "tailscale funnel 3000"
color = "magenta" # optional, for log stream coloring
ready_pattern = "available at" # optional regex — marks process as "ready" when matched
[[process]]
name = "stripe-listen"
command = "stripe listen --forward-to localhost:3001/api/webhooks/stripe"
color = "yellow"
# Theme override
[theme]
palette = "catppuccin-mocha" # built-in: catppuccin-mocha, tokyo-night, draculaCustom processes are started on launch and their stdout/stderr is streamed into the log viewer alongside container logs. If a process exits, the panel shows the exit code — press r to restart.
| Key | Action |
|---|---|
j / k |
Navigate up/down |
h / l |
Focus prev/next |
Tab / Shift+Tab |
Switch tabs |
Enter |
Drill into selected item |
Esc |
Go back |
/ |
Search/filter logs |
s |
Toggle scroll lock |
r |
Restart selected process |
g / G |
Jump to top/bottom |
Ctrl+f / Ctrl+b |
Page down/up |
q / Ctrl+c |
Quit |
Top-level grid showing all containers and processes with status, CPU/memory sparklines, uptime, and port mappings.
Multiplexed, color-coded log stream with:
- Each source gets a distinct color
- Regex search/filter
- Auto-scroll with scroll lock
- Stderr lines highlighted in red
Drill into a single container or process — key-value info panel (image, status, ports, PID, exit code) with a dedicated log stream.
Per-container CPU and memory sparkline charts, memory used/limit, and network I/O rates.
src/
├── main.rs // CLI entry, config loading, app bootstrap
├── app.rs // App state, event loop, view routing
├── config.rs // mirador.toml parsing (serde + toml)
├── docker/
│ ├── client.rs // Bollard client wrapper, container enumeration
│ ├── logs.rs // Per-container log stream (tokio task + channel)
│ └── stats.rs // Stats polling + rolling history buffer
├── process/
│ ├── manager.rs // Spawn and manage custom processes
│ └── stream.rs // stdout/stderr capture into log channels
├── ui/
│ ├── overview.rs // Container + process grid view
│ ├── logs.rs // Multiplexed log viewer widget
│ ├── detail.rs // Container/process detail view
│ └── metrics.rs // CPU/memory/network charts
├── theme.rs // Color palettes + styling
└── input.rs // Keybinding handler (vim-style)
- Parse
mirador.toml, connect to Docker daemon via bollard - Enumerate containers filtered by Compose project label
- Spawn tokio tasks: one per container for logs, one per container for stats, one per custom process
- All streams feed into unified
tokio::sync::mpscchannels with tagged source - UI renders at ~30fps, consuming from channels
- App state via message passing (no
Arc<Mutex<>>)
| Crate | Role |
|---|---|
ratatui |
TUI framework |
bollard |
Docker Engine API client |
tokio |
Async runtime |
crossterm |
Terminal backend |
toml + serde |
Config parsing |
chrono |
Timestamps |
regex |
Log search/filter |
clap |
CLI argument parsing |
- Compose file parsing for service dependency graph
- Exec into container from TUI
- Desktop notifications on crash/restart
- Custom dashboard layouts via config
- HTTP request log panel (reverse proxy parsing)
- Auto-restart policy per process (configurable)
MIT