A terminal UI for managing and monitoring Docker containers. Real-time stats, advanced log viewing, container lifecycle control, and full keyboard-driven workflow.
- Real-time stats — CPU, memory, network I/O, and disk I/O with parallel streaming collection
- Container control — Start, stop, pause, restart, exec shell, remove, and recreate (with docker-compose support)
- Advanced log viewer — Search, filter (AND/OR/NOT expressions), follow mode, time-range filtering, normalization, and export
- Container inspector — Tree and JSON views with search, expand/collapse, and path/value copy
- Keyboard-first — Every action has a shortcut; mouse is fully supported too
- Customizable columns — Adjust widths, set min/max, reorder via config or the built-in editor
- Preset + custom themes — Cycle presets or define fully custom palettes and semantic colors
- Responsive layout — Columns auto-size to terminal width based on weight
- Persistent config — Column settings saved to
~/.docker_tui.json - Legacy mode — Falls back to a curses interface with
--legacy
Requirements: Python 3.8+, Docker daemon running, access to /var/run/docker.sock
# PyPI (recommended)
pip install dtop
# Latest from GitHub
pip install git+https://github.com/StakeSquid/dtop.git
# Quick install script
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/StakeSquid/dtop/main/scripts/install.sh)"
# Development
git clone https://github.com/StakeSquid/dtop && cd dtop && pip install -e .If you have a previous version installed, make sure to upgrade:
pip install --upgrade dtopdtop # Textual UI (default)
dtop --legacy # Curses interface
dtop --debug # Debug mode with full tracebacks| Key | Action |
|---|---|
Enter |
Open actions menu for selected container |
L |
View logs |
I |
Inspect container |
S |
Stop / Start (toggle) |
P |
Pause / Unpause (toggle) |
R |
Restart |
E |
Exec shell |
F |
Recreate |
/ |
Search containers |
\ |
Filter containers |
N |
Next search match |
Escape |
Clear search/filter |
C |
Column settings |
D |
Cycle theme presets (includes custom theme when configured) |
T |
Open theme editor (edit/save custom theme in-app) |
? |
Help |
Q |
Quit |
Click any column header to sort. Click again to reverse.
When the modal is open, press any shortcut key directly:
| Key | Action |
|---|---|
L |
View logs |
I |
Inspect |
S |
Stop / Start |
P |
Pause / Unpause |
R |
Restart |
E |
Exec shell |
F |
Recreate |
Escape / Q |
Close menu |
| Key | Action |
|---|---|
F |
Toggle follow mode (auto-scroll) |
/ |
Search |
\ |
Filter (supports AND/OR/NOT expressions) |
N / P |
Next / previous match |
S |
Toggle case-sensitive search |
Shift+N |
Toggle log normalization |
W |
Toggle line wrapping |
T |
Set tail line count |
Shift+T |
Toggle Docker timestamps |
R |
Time-range filter |
E |
Export logs to file |
G / Shift+G |
Jump to top / bottom |
C |
Clear log display |
Escape |
Back (clears active filter first) |
| Key | Action |
|---|---|
/ |
Search keys and values |
\ |
Filter |
N / P |
Next / previous match |
C |
Copy current match path |
V |
Copy current match value |
E / Shift+E |
Expand / collapse all |
J |
JSON view |
T |
Tree view |
Escape |
Back |
The log viewer supports complex filter expressions:
error # lines containing "error"
+error # explicit include
-error or !error # exclude
"exact phrase" # quoted multi-word term
error AND warning # both terms required
error OR warning # either term
(error OR warning) AND -debug # grouped with exclusion
Settings are stored in ~/.docker_tui.json. Press C in the main view to open the column editor.
Each column has: name, width, min_width, max_width, weight, and align.
{
"columns": [
{ "name": "NAME", "width": 25, "min_width": 15, "max_width": null, "weight": 3, "align": "left" },
{ "name": "IMAGE", "width": 30, "min_width": 15, "max_width": 50, "weight": 2, "align": "left" },
{ "name": "STATUS", "width": 12, "min_width": 8, "max_width": 20, "weight": 1, "align": "left" },
{ "name": "CPU%", "width": 8, "min_width": 7, "max_width": 10, "weight": 0, "align": "right" },
{ "name": "MEM%", "width": 8, "min_width": 7, "max_width": 10, "weight": 0, "align": "right" },
{ "name": "NET I/O", "width": 20, "min_width": 16, "max_width": 26, "weight": 0, "align": "right" },
{ "name": "DISK I/O","width": 20, "min_width": 16, "max_width": 26, "weight": 0, "align": "right" },
{ "name": "CREATED AT","width": 21,"min_width": 19, "max_width": 30, "weight": 0, "align": "left" },
{ "name": "UPTIME", "width": 12, "min_width": 8, "max_width": 16, "weight": 0, "align": "right" }
]
}Columns with a higher weight expand first when the terminal is wide. Columns with weight: 0 stay at their minimum unless extra space allows growth.
You can define a fully custom Textual theme plus semantic runtime colors (status labels, search highlights, log severity colors, etc.) in the same config file.
Set "theme": "dtop-custom" to activate it, then provide custom_theme:
{
"theme": "dtop-custom",
"custom_theme": {
"primary": "#3b82f6",
"secondary": "#22c55e",
"warning": "#f59e0b",
"error": "#ef4444",
"success": "#10b981",
"accent": "#06b6d4",
"foreground": "#e5e7eb",
"background": "#0b1020",
"surface": "#121a2f",
"panel": "#1a2542",
"boost": "#0f172a",
"dark": true,
"luminosity_spread": 0.15,
"text_alpha": 0.95,
"semantic_colors": {
"status_running": "green",
"status_stopped": "red",
"status_paused": "yellow",
"connection_ok": "green",
"connection_error": "red",
"warning_text": "yellow",
"error_text": "red",
"info_text": "blue",
"muted_text": "dim",
"timestamp_text": "dim cyan",
"inspect_bool": "cyan",
"inspect_number": "magenta",
"inspect_string": "green",
"search_highlight": "reverse yellow",
"search_highlight_case": "reverse bold yellow"
}
}
}If custom_theme is invalid or missing required values, dtop safely falls back to built-in themes.
Tip: you can edit and save these values directly inside dtop with T.
# Docker not connecting
sudo systemctl status docker
ls -la /var/run/docker.sock
sudo usermod -aG docker $USER # then logout/login
# Terminal not restoring after exit
reset
# Textual UI issues — fall back to curses
dtop --legacyThe recreate feature supports two modes:
Docker-Compose mode — Automatically detects compose metadata from container labels (com.docker.compose.project, com.docker.compose.service, com.docker.compose.project.working_dir). Opens a file browser to select or confirm the compose file, then runs docker compose up -d --force-recreate --no-deps <service>.
Simple mode — For standalone containers without compose. Extracts the full container config (image, env vars, volumes, ports, network mode, restart policy, user, working directory, entrypoint) and recreates with identical settings.
Stats are collected via the Docker API using streaming mode (primary) with polling fallback. Up to 30 concurrent connections are maintained. Streams auto-refresh every 60 seconds and reconnect up to 3 times on failure. Stale data is cleaned up after 5 minutes. Rates (network, disk) are calculated from deltas between samples.
| Status | Color |
|---|---|
| Running | Green |
| Exited / Stopped | Red |
| Paused | Yellow |
The log header shows compact indicators:
N:Y/N— Normalization on/offW:Y/N— Wrap on/offF:ON/OFF— Follow modeL:nnn— Total raw log linesT:nnn— Tail limitF:nnn— Filtered line countM:x/y— Search match position[CS]— Case-sensitive search active[TIME]— Time filter active
Press E in the log viewer to export. The output file includes a metadata header (container name, export timestamp, active filters, total lines) followed by the log content. Files are saved as <container>_logs_<timestamp>.txt.
dtop/
├── dtop/
│ ├── __main__.py # Package entry point
│ ├── main.py # CLI entry point (--legacy, --debug)
│ ├── core/
│ │ ├── textual_docker_tui.py # Main Textual UI, table, modals, footer
│ │ ├── textual_stats.py # Async stats streaming/polling
│ │ ├── docker_tui.py # Legacy curses interface
│ │ └── stats.py # Legacy stats collection
│ ├── views/
│ │ ├── textual_log_view.py # Log viewer (search, filter, follow, export)
│ │ ├── textual_inspect_view.py # Container inspector (tree + JSON)
│ │ ├── log_view.py # Legacy log viewer
│ │ └── inspect_view.py # Legacy inspector
│ ├── actions/
│ │ └── container_actions.py # Legacy container operations
│ └── utils/
│ ├── config.py # Column config load/save
│ ├── utils.py # Formatting helpers
│ └── normalize_logs.py # Log normalization script
├── scripts/
│ ├── install.sh
│ └── uninstall.sh
├── pyproject.toml
└── requirements.txt
| Package | Version | Purpose |
|---|---|---|
docker |
>= 6.0.0 | Docker SDK |
textual |
>= 0.47.0 | TUI framework |
rich |
>= 13.0.0 | Terminal formatting |
aiohttp |
>= 3.8.0 | Async stats collection |
MIT — see LICENSE.