# D-Force (d4s) D4S (pronounced *D-Force*) brings the power and ergonomics of [K9s](https://github.com/derailed/k9s) to the local Docker ecosystem. Stop wrestling with verbose CLI commands and start managing your containers like a pro. ## Quick install ```bash curl -fsSL https://d4scli.io/install.sh | sh -s -- ~/.local/bin ``` ## Screenshots
## Features - **Fancy UI**: Modern TUI with Dracula theme, smooth navigation, and live updates. - **Keyboard Centric**: Vim-like navigation (`j`/`k`), shortcuts for everything. No mouse needed. - **Full Scope**: Supports **Containers**, **Images**, **Volumes**, **Networks**. - **Compose Aware**: Easily identify containers belonging to **Compose Projects**. - **Swarm Aware**: Supports **Nodes**, **Stacks**, **Services**, **Tasks**, **Secrets**, **ConfigMaps**. - **Docker Settings**: Supports **Contexts**, **Plugins**. - **Remote via SSH Tunnel**: Manage remote Docker daemons over SSH with port-forwarding to localhost. - **Powerful Search**: Instant fuzzy filtering (`/`) and command palette (`:`). - **Live Stats**: Real-time CPU/Mem usage for containers and host context. - **Advanced Logs**: Streaming logs with auto-scroll, fullscreen, timestamps toggle, wrap mode, marks and save to file (`ctrl-s`). - **Quick Shell**: Drop into a container shell (`s`) in a split second. - **Contextual Actions**: Inspect, Restart, Stop, Prune, Delete with safety confirmations. ## Installation > ### Generic
Binary Releases > Automated ```bash curl -fsSL https://d4scli.io/install.sh | sh -s -- ~/.local/bin ``` *The script installs downloaded binary to `$HOME/.local/bin` directory by default, but it can be changed by setting DIR environment variable.* > Manual Grab a release from the [releases page](https://github.com/jr-k/d4s/releases) and install it manually.
Docker ```bash docker run --rm --pull always -it -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/jr-k/d4s:latest ``` **You might want to create an alias for quicker usage. For example:** ```bash echo "alias d4s='docker run --rm --pull always -it -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/jr-k/d4s:latest'" >> ~/.zshrc ``` *After running this, either restart your terminal or run `source ~/.zshrc` (or `source ~/.bashrc` for Bash) to enable the alias.*
Go Install >Requirement: Go 1.25+ ```bash go install github.com/jr-k/d4s@latest ``` The binary lands in `$(go env GOBIN)` (or `$(go env GOPATH)/bin`). Make sure that directory is on your `PATH`. To upgrade later, just re-run the same command, or use [`gup`](https://github.com/nao1215/gup) to bulk-update all your `go install`-managed binaries: ```bash gup update ```
From Source >Requirement: Go 1.25+ ```bash git clone https://github.com/jr-k/d4s.git cd d4s go build -o d4s . sudo mv d4s ~/.local/bin/ ``` ```bash # Make the binary accessible then run it mv d4s ~/.local/bin/ d4s # Quickly run from source go run . ```
> ### macOS
Homebrew ```bash brew install jr-k/d4s/d4s ```
> ### Linux
APT (Debian/Ubuntu) ```bash sudo apt install -y gpg && curl -fsSL https://apt.d4scli.io/d4s.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/d4s.gpg echo "deb [signed-by=/usr/share/keyrings/d4s.gpg] https://apt.d4scli.io stable main" | sudo tee /etc/apt/sources.list.d/d4s.list sudo apt update sudo apt install d4s ```
RPM (Fedora/RHEL) ```bash sudo tee /etc/yum.repos.d/d4s.repo <
Zypper (openSUSE) ```bash sudo zypper addrepo https://zypper.d4scli.io d4s sudo zypper refresh sudo zypper install d4s ```
> ### Windows
Scoop ```powershell scoop bucket add d4s https://github.com/jr-k/scoop-d4s scoop install d4s ```
## Usage ```bash d4s d4s version d4s --context my-remote-ctx ``` ## Configuration D4S uses a YAML configuration file located at `$XDG_CONFIG_HOME/d4s/config.yaml` (defaults to `~/.config/d4s/config.yaml`). ### Context Selection Precedence When deciding which Docker context to use, D4S applies the following precedence: 1. `--context` / `-c` 2. `DOCKER_HOST` 3. `DOCKER_CONTEXT` 4. `d4s.defaultContext` from `config.yaml` 5. Docker CLI's own current/default context behavior If you select the literal `default` context from `tab`, D4S uses Docker's normal default context resolution rather than a named custom context. All settings are optional and have sensible defaults. Below is a fully documented example: ```yaml d4s: # Refresh interval in seconds. Minimum 2.0 — values below are capped. Default: 2.0 refreshRate: 2 # Docker API server request timeout. Default: 120s apiServerTimeout: 15s # Disable all modification commands (delete, kill, restart, etc.). Default: false readOnly: false # Default Docker context for d4s when --context, DOCKER_HOST, and DOCKER_CONTEXT are not set. Default: "" defaultContext: "" # Default view on startup (containers, images, volumes, networks, services, nodes, compose, aliases, secrets, configs, stacks, tasks, contexts, plugins). Default: "" (containers) defaultView: "" # When true, Ctrl+C won't exit — use :quit instead. Default: false noExitOnCtrlC: false # Skip checking GitHub for new releases on startup. Default: false skipLatestRevCheck: false # Optional visible columns and their order for each resource view. # Omit a view to keep its default columns. views: containers: columns: [ID, NAME, STATUS, CPU, MEM, AGE] # UI settings ui: # Enable mouse support. Default: false enableMouse: false # Hide the entire header bar (stats + shortcuts + logo). Default: false headless: false # Hide the D4S ASCII logo from the header. Default: false logoless: false # Hide breadcrumb trail in the status bar. Default: false crumbsless: false # Invert all theme colors (dark↔light), preserving hue. Default: false invert: false # Skin name, loads from $XDG_DATA_HOME/d4s/skins/.yaml. Default: "default" (builtin: default, dracula, monokai, nord, gruvbox, tokyonight) skin: "default" # Log viewer settings logger: # Number of tail lines to fetch initially. Default: 100 tail: 200 # How far back to go in the log timeline (seconds). -1 = tail mode. Default: -1 sinceSeconds: -1 # Enable line wrapping in log viewer. Default: false textWrap: false # Disable auto-scroll when new log lines arrive. Default: false disableAutoscroll: false # Show timestamps on each log line. Default: false showTime: false # Shell pod used for volume browsing and secret decoding shellPod: image: ghcr.io/jr-k/nget:latest ``` View names are `containers`, `images`, `volumes`, `networks`, `services`, `nodes`, `compose`, `aliases`, `secrets`, `tasks`, `stacks`, `configmaps`, `contexts`, `plugins`, and `portforwards`. Column names are case-insensitive. Unknown or duplicate columns are ignored with a warning; an empty list or a list with no valid columns falls back to the view defaults. Example: pin D4S to a preferred remote context by default: ```yaml d4s: defaultContext: "my-remote-ctx" defaultView: "containers" ``` ## Skins ### Built-in Skins Set skin using `--skin` (or `-s`) flag when running `d4s` or set `d4s.ui.skin` option in the configuration file. D4S comes with a few built-in skins: - `default` - `dracula` - `monokai` - `nord` - `gruvbox` - `tokyonight` ### Custom Skins D4S supports custom skins. Skins are stored in `$XDG_DATA_HOME/d4s/skins/.yaml` (defaults to `~/.local/share/d4s/skins`). The inspector (describe, env, compose files...) takes its syntax colors from the optional `views.inspect` section: ```yaml d4s: views: inspect: keyColor: "#ff79c6" # keys, variable names stringColor: "#f1fa8c" # strings numberColor: "#bd93f9" # numbers keywordColor: "#ff79c6" # true, false, null punctuationColor: "#f8f8f2" # brackets, colons, commas commentColor: "#6272a4" # comments ``` Any color left out is derived from the rest of the skin and adjusted, if needed, to stay readable on `body.bgColor`. ## Remote Management (SSH Tunnel) D4S can manage remote Docker daemons over SSH. No agent or extra binary is needed on the remote host. From the Contexts view (`:o`), press `Shift+A` to add an SSH context (key or password auth). Credentials are stored in your OS keychain with an encrypted-file fallback for headless systems. SSH ControlMaster keeps the connection fast. ### Port-Forwarding | Shortcut | Action | |----------|--------| | `Shift+F` | Create a port-forward (container, service, or compose project) | | `f` | Show active port-forwards for the selected resource | | `:portforward` | Global view of all active tunnels | Port-forwards expose a remote container port on your local machine (`localhost:`). They persist across view switches and can be stopped or deleted from the `:portforward` view. ### Limitations in SSH mode - Volume "Open in Finder" is unavailable (data lives on the remote host, use `s` shell instead) - Dive runs against the remote daemon but may not support SSH depending on its version ## Command Palette Use `tab` to open the Docker context picker, switch the current d4s session to a different context, and save that selection as the default context for future d4s launches. If `DOCKER_HOST` or `DOCKER_CONTEXT` is set in your shell, those environment variables still override the saved D4S default for that launch. In a container log view, press `ctrl-s` to save the full log of that container to `~/.config/d4s/logs/..log` (or the equivalent `$XDG_CONFIG_HOME/d4s/logs/...` path). ## Contributing There's still plenty to do! Take a look at the [contributing guide](CONTRIBUTING.md) to see how you can help. ## Discussion / Need help ? ### Open an Issue [](https://github.com/jr-k/d4s/issues/new/choose) --- *Built with Go & [Tview](https://github.com/rivo/tview). Inspired by [K9s](https://github.com/derailed/k9s).* *D4s uses several open source libraries. Thanks to the maintainers who make this possible.*