A keyboard-first Docker TUI with a command-driven workflow and real-time feedback.
Dawker is a terminal user interface for Docker that merges the visual feedback of a dashboard with the speed of a command-line interface. Built in Go using the Bubbletea framework, it replaces tedious mouse interactions and complex CLI flags with a Vim-inspired command engine.
Managing local Docker environments is often a fragmented experience. The standard Docker CLI requires excessive typing, context switching, and constantly looking up container IDs. Existing Docker TUIs or GUI tools typically rely on hidden menus, deeply nested popups, or mouse clicks, which break developer flow.
Dawker was built with a single philosophy: interaction should be immediate.
By treating the terminal as an integrated environment and utilizing a command buffer (:), Dawker allows you to navigate, monitor, and manipulate your Docker resources exactly like you edit code in Vim.
Dawker is best suited for:
- Inspecting running containers quickly
- Debugging services via real-time log streaming
- Performing routine lifecycle operations (start, stop, restart)
- Cleaning up local Docker environments
It is not intended for:
- Complex orchestration workflows
- Building images or managing CI/CD pipelines
- Replacing the Docker CLI entirely
| 1. Monitor Resources | 2. Real-time Pulls |
|---|---|
![]() |
![]() |
| 3. Command Engine | 4. Instant Execution |
|---|---|
![]() |
![]() |
| 5. Fuzzy Match Preview | 6. Bulk Action Success |
|---|---|
![]() |
![]() |
| 7. Live State Sync |
|---|
![]() |
Get up and running in under a minute.
- Go 1.21+
- A local Docker Daemon running at
/var/run/docker.sock - Docker Compose v2, available as the
docker composeCLI plugin
The fastest way to install Dawker on Mac or Linux:
curl -sSL https://raw.githubusercontent.com/rounakkraaj-1744/dawker/main/install.sh | bashgit clone https://github.com/rounakkraaj-1744/dawker.git
cd dawker
go build -o dawker cmd/main.go
./dawkerDownload the latest release and install:
curl -L https://github.com/rounakkraaj-1744/dawker/releases/latest/download/dawker-linux -o dawker
chmod +x dawker
sudo mv dawker /usr/local/bin/- Move: Use
jandkto scroll through your containers. - View Logs: Press
Enteron a running container to stream its logs. - Execute: Press
:to open the command buffer. Typestopand pressEnter. The highlighted container stops immediately.
Dawker's mental model is based on four pillars:
- Tabs (Resources): Resources are grouped into four primary views:
Containers,Images,Volumes, andNetworks. Switching tabs completely changes your operational context. - Selection (
▸): There is always an active, selected item in your list. Many commands default to targeting this specific item if no other arguments are provided. - Command Mode (
:): The core interaction model. Rather than mapping 50 different keyboard shortcuts for different actions, everything complex is handled through an interactive command buffer at the bottom of the screen. - Details / Logs Panel: The right half of the screen dynamically updates. If a container is streaming, it shows multiplexed stdout/stderr. Otherwise, it shows static metadata about the selected resource.
Dawker is designed around a simple interaction loop:
- Navigate to a resource (container, image, volume, or network)
- Inspect its state (status indicator or live logs)
- Execute an action using command mode (
:)
Most operations follow this pattern:
Select → Inspect → Act
The command system removes the need to remember exact Docker CLI syntax. Instead, actions are expressed in terms of intent:
:stop api → stop the container matching "api"
:rm exited → remove all stopped containers
:rmi node → remove the image matching "node"
This keeps interaction consistent across all resource types.
Dawker operates in a normal navigation mode by default.
| Key | Action |
|---|---|
j / k / ↓ / ↑ |
Move selection down / up |
1 / 2 / 3 / 4 |
Switch tab (Containers, Images, Volumes, Networks) |
Enter |
Stream logs (for containers) or view static metadata |
: |
Enter Command Mode |
Tab |
Auto-complete current suggestion (in command mode) |
↑ / ↓ |
Cycle command history (in command mode) |
r |
Force refresh resource data |
q / Esc |
Quit application or cancel active log stream |
When in the Containers tab, the TUI provides visual indicators for state (Green for running, Red for exited). Pressing Enter on a container allocates a background io.Pipe, separates multiplexed Docker logs via stdcopy, and streams them in real-time to the right panel. The log buffer is capped at 500 lines and auto-scrolls to the bottom, with line truncation to prevent horizontal overflow.
Press : to enter command mode. All input is captured by the command buffer until execution or cancellation. A -- COMMAND -- indicator appears in the footer, and a block cursor marks your position.
- Autocomplete: Press
Tabto auto-complete commands or resource names. - History: Use
UpandDownarrows to cycle through previous successful commands (up to 50 entries). - Inline Errors: If you type a typo (e.g.,
:sto), Dawker suggests the closest match (Did you mean: stop?).
:stop api Stop containers matching "api"
:restart all Restart all containers
:rm exited Remove all stopped containers
:prune Reclaim disk space from unused resources
Commands are evaluated using the following rules:
-
Explicit target takes priority
:stop api→ matches containers containing "api" in their name
-
No arguments → use current selection
:stop→ applies to the item highlighted by▸in the active tab
-
Keyword targets
all→ all resources in the current tabrunning→ containers currently runningexited→ containers that have stopped
-
Multiple matches
- Commands are applied to all matching resources sequentially
-
No matches
- Command fails with inline error feedback (no crash, no modal)
The command system is designed for fast, low-friction interaction.
- Commands are resolved using fuzzy matching against resource names
- Targets are inferred from the active tab and selection when omitted
- Batch operations are supported through keywords (
all,running,exited)
Context-Aware Execution: If you type :rm without arguments, Dawker inspects your current tab and active selection. If you are on the Images tab, it removes the selected image. If you are on the Volumes tab, it removes the selected volume.
Fuzzy Matching: You do not need to type full container hashes or names. If you have a container named production-api-server-1, typing :stop api matches it based on partial name.
Batch Keywords: Typing :rm exited removes all containers that are no longer running. :stop all halts every container in the list.
Live Previews: As you type, the UI renders a preview line above the input (e.g., Will stop: api-server, cache-db). You see exactly what the command will affect before pressing Enter.
All commands execute against the Docker SDK directly. [target] can be a partial name, a keyword (all, running, exited), or omitted to use the current selection.
| Command | Description |
|---|---|
:start [target] |
Starts the target container(s) |
:stop [target] |
Gracefully stops the target container(s) |
:restart [target] |
Restarts the target container(s) |
| Command | Description |
|---|---|
:rm [target] |
Removes containers (force removal) |
:rmi [target] |
Removes images |
:rmv [target] |
Removes volumes |
:rmn [target] |
Removes networks |
:prune |
System-wide prune of unused containers, images, volumes, and networks |
| Command | Description |
|---|---|
:logs [target] |
Trigger log stream (WIP) |
:stats [target] |
View resource utilization (WIP) |
Dawker also provides a Compose command passthrough. It invokes Docker Compose
v2 from the directory where Dawker was started, so the command uses the
current project's compose.yaml, compose.yml, or docker-compose.yml by
default. Arguments are passed directly to the Docker CLI; no shell is involved.
Use the following form from command mode:
:compose <subcommand> [options] [services]
Common workflows include:
| Dawker command | Equivalent Docker command | Purpose |
|---|---|---|
:compose up -d |
docker compose up -d |
Build and start the project in the background |
:compose up --build |
docker compose up --build |
Rebuild images and start services |
:compose down |
docker compose down |
Stop and remove project containers and networks |
:compose ps |
docker compose ps |
Show the project's service status |
:compose logs -f api |
docker compose logs -f api |
Follow logs for a service |
:compose restart api |
docker compose restart api |
Restart one or more services |
:compose stop |
docker compose stop |
Stop services without removing them |
:compose start |
docker compose start |
Start previously stopped services |
:compose build api |
docker compose build api |
Build a service image |
:compose pull |
docker compose pull |
Pull service images |
:compose exec api sh |
docker compose exec api sh |
Open a shell in a running service |
:compose run --rm api <command> |
docker compose run --rm api <command> |
Run a one-off service command |
:compose config |
docker compose config |
Render and validate the Compose configuration |
:compose top |
docker compose top |
Display service processes |
The complete Compose CLI is available through this passthrough, including
project/file options such as -f compose.prod.yaml, -p my-project, and
--profile. Standard Compose subcommands are suggested after typing
:compose , and interactive commands such as up, logs -f, and exec
retain their normal terminal behavior. Dawker refreshes its resource lists
after a Compose command exits.
- Notice a red
(exited)status on your API container. - Press
Enterto view the crash logs in the right panel. - Fix the code in your editor.
- Press
:, typerestart, pressEnter. The container restarts and the UI refreshes to show(running).
- Your local Docker environment is cluttered with stopped containers and dangling images.
- Press
:, typerm exited, pressEnterto clear dead containers. - Press
:, typeprune, pressEnterto reclaim disk space from all unused resources.
- You have 5 microservices running (
auth-api,billing-api,user-api, etc.). - You need to stop all of them.
- Press
:, typestop api. - The preview confirms: Will stop: auth-api, billing-api, user-api.
- Press
Enter.
Dawker is strictly layered to ensure the UI never blocks and the Docker daemon is never overwhelmed.
- TUI Layer (
internal/app): Built oncharmbracelet/bubbleteaandlipgloss. TheUpdateloop is decomposed intohandleNormalModeKeyandhandleCommandModeKeyto prevent state collision. UI rendering happens concurrently without blocking Docker operations. - Command System (
internal/command):parser.go: Tokenizes raw strings into command structs.selector.go: Fuzzy-matching logic and keyword filters (all,running,exited).executor.go: A registry pattern mapping parsed commands to Docker SDK actions.suggest.go: Evaluates the input buffer in real-time for autocomplete and typo corrections.
- Docker Layer (
internal/docker): Wraps the official Go Docker SDK. Uses a singleton*client.Clientviasync.Onceto eliminate repeated API version negotiation and connection overhead.
Execution Flow:
Input string → Parser → Fuzzy Target Resolution → Executor Registry → Docker SDK Action → UI State Reload
- Keyboard-First vs Modals: Traditional TUIs rely on pop-up modals (e.g., "Are you sure? [Y/n]"). Dawker replaces modals with a command preview line. Seeing Will stop: database is faster and more transparent than a generic confirmation prompt.
- Single Connection: Wrapping the Docker client in a singleton ensures commands execute without connection setup delay. This is critical for responsive command mode interaction.
- Minimal UI: There are no heavy borders or excessive colors. Color is used strictly for semantics (Green = running, Red = exited, Orange = Command Mode active).
- Only supports local Docker daemon via Unix socket (
/var/run/docker.sock) - Remote Docker hosts are not configurable
- Log streaming is capped at 500 lines and does not support filtering or search
- Docker Compose commands require Docker Compose v2 to be installed and use the current working directory's Compose project
- Does not support Swarm or Kubernetes
Contributions are welcome, particularly for expanding the executor.go registry with more Docker SDK actions.
- Fork the repository
- Create your feature branch (
git checkout -b feature/new-handler) - Commit your changes (
git commit -m 'feat: add stats handler') - Push to the branch (
git push origin feature/new-handler) - Open a Pull Request
MIT License






