Your Coolify fleet, one keystroke away.
Deployments, logs, restarts and instance switching for Coolify - from the terminal you already have open.
No browser tab. No daemon. No token on screen. On purpose.
English · Čeština
Quick Start · Features · Fleet tail · MCP · Comparison · Keyboard Shortcuts · Installation · Configuration · Security · Contributing
Try the whole UI in one line - no Coolify instance, no token, no network:
brew install resetnak/tap/cooldeck && cooldeck --demo
curl -fsSL https://raw.githubusercontent.com/Resetnak/cooldeck/main/install.sh | sh && cooldeck --demo
Prefer Go? go install github.com/resetnak/cooldeck/cmd/cooldeck@latest
. Prefer a binary? Every
release ships Linux, macOS and Windows
archives plus .deb
/.rpm
/.apk
. --demo
runs against deterministic sample data - the same data the golden tests render - so you can judge the product before you hand it a token.
Checking whether a deploy went through should not cost you a browser tab, a login, and three clicks through a dashboard. CoolDeck puts the same fleet - statuses, deployment history, runtime logs and the deploy button - into a terminal window you can leave open next to your editor, and drives all of it from the keyboard.
It talks to the Coolify REST API directly. No proxy, no agent, no daemon: one static binary that reads your config, pulls a token out of your OS keyring, and renders.
COOLDECK Demo ● connected DEMO 12 apps | refreshed just now
────────────────────────────────────────────────────────────────────────────────────────────────
RESOURCES │ STATUS APPLICATION BRANCH DEPLOYED DOMAIN │ billing-api
│ ▲ Degraded billing-api main 47m ago api.billi… │ ▲ Degraded
> Applications 12│ ◐ Restarting ingest-dashboard feat/charts 1m 30s ago - │
Deployments 33│ ● Running landing-web main 21s landing.e… │ Branch main
Instances 1│ ○ Queued vault-web main 4s vault.exa… │ Commit 9f31c2e
Diagnostics │ ■ Stopped billing-worker main 2h ago - │ Deploy 47m ago
│ ● Running shipyard-api main 3m ago shipyard.… │
────────────────────────────────────────────────────────────────────────────────────────────────
↑↓ navigate enter details d deploy r restart s start/stop / filter ? more 1/12
Look before you connect:cooldeck --demo
- the full UI on deterministic fake data, offline.Create a Coolify API token: in Coolify,profile → API tokens. Give it the least privilege you can live with (
read
plus only the write scopes you actually want).Connect:cooldeck setup
walks you through URL, token and keyring storage.Use it:cooldeck
. Press?
for the key map,:
for the command palette,/
to filter.
One degraded app, start to finish: / to filter, enter for the detail, l for runtime logs, d to redeploy behind a confirmation, 2 a to watch it land in the active queue. Rendered from
🖥️ The whole fleet on one screen: status, branch, last deploy and domain for every application, with filtering (/
) and sorting (S
).🔎 Detail without a context switch: overview, deployment history, runtime logs and configuration as tabs on the same screen.🛰️ Fleet tail: mark applications withspace
, presst
, and read their runtime logs interleaved in one buffer, each line named and coloured by the application it came from - the view Coolify's web UI cannot give you.📜 Real log ergonomics: follow, , wrap, in-buffer search withn
/N
, copy the match, clear the buffer,+
/-
to widen or narrow the line window.🚀 Operations behind a confirmation: deploy, force deploy, restart, start/stop - every destructive action asks first, and only one mutation runs at a time.🛟 Honest about failure: a refresh that fails keeps the last good data on screen behind a stale banner instead of blanking the list. SeeWhen Coolify blinks.🔀 Several instances, one session: switch fleets with3
without restarting; add, edit and delete local instance entries from inside the TUI.⌨️ Keyboard-first, mouse-optional: vi-flavoured bindings borrowed fromlazygit
andk9s
, a command palette (:
/Ctrl+K
) for the day you forget one, and a?
overlay that always shows the truth - every hint is generated from a singleKeyMap
.🎨 Eight themes, responsive layout: auto, dark, light, Dracula, Catppuccin, Nord, Gruvbox, Tokyo Night; three-pane at 150+ columns, single column when the window is small.🔐 Tokens you never see: OS keyring by default, and tokens are kept out of the UI, the logs, the toasts and the diagnostics export by construction.🤖 An MCP server in the same binary:cooldeck mcp
hands your fleet to an agent - read-only until you say otherwise. SeeYour fleet, in your agent.🧪 Offline demo mode:--demo
is a full implementation of the same service interface, which is also what the golden snapshot tests render.
The one view Coolify's web UI cannot give you. Mark the applications you care about with
space
, press t
, and their runtime logs arrive interleaved in a single buffer - every line named and coloured by the application it came from. One incident, one screen, instead of a browser tab per service.
Three services marked, one buffer: space to mark, t to tail, / to search across all of them, w to wrap. Rendered from
f
follows, space
s, c
copies the merged buffer, esc
goes back. Coolify serves runtime logs as whole snapshots rather than a stream, so CoolDeck polls one request per marked application every 4 seconds, staggers them, and merges the replies by timestamp - up to five applications at a time, and it says so when it drops the rest. The concurrency model is ADR 0007.
cooldeck mcp
speaks the Model Context Protocol over stdin/stdout, so an agent can ask what is running, why a build failed, and what the logs say - through the same use cases the TUI uses. No second HTTP client, no separate token, no daemon.
A real JSON-RPC session against --demo - handshake, tool discovery, two calls, then the opt-in. Rendered from mcp.tape.
It cannot touch your production by default. The read-only surface is list_applications
,
get_application
, list_deployments
, get_runtime_logs
, get_deployment_logs
and
get_instance_info
. --allow-mutations
adds deploy_application
, restart_application
,
start_application
and stop_application
- and nothing behind them asks for confirmation, because an agent has no one to ask. Grant it deliberately, and prefer a token scoped to the instance you are willing to let it operate.
// Point any MCP client at the binary you already have:
{ "mcpServers": { "cooldeck": { "command": "cooldeck", "args": ["mcp"] } } }
Try it before you wire it up: cooldeck mcp --demo
serves the same tools against the offline demo fleet, so you can watch an agent work without a Coolify instance in the loop.
📖 ** Full guide: docs/mcp.md** - client setup, every tool and its arguments, what to decide before granting mutations, and troubleshooting.
CoolDeck is not a replacement for the Coolify web UI - it is the fast path for the handful of things you do twenty times a day.
| Tool | Great at | Where CoolDeck differs |
|---|---|---|
| Coolify web UI | ||
| Everything - creating resources, editing env vars, managing servers | CoolDeck is read-and-operate only, but gets you from "is it up?" to "redeployed" in a few keystrokes, with no tab switch | |
curl + jq |
||
| Scripting, one-off queries | CoolDeck gives you the same API with statuses, history and logs in one live view, and refuses to let a typo trigger a production deploy without confirming | |
| k9s / lazydocker | ||
| The container layer underneath | CoolDeck speaks Coolify's model - applications, projects, environments, deployments - not raw containers |
Everything it does is an ordinary Coolify API call, so nothing here locks you in or out of the web UI.
Dashboards that clear the screen the moment a request fails are worse than useless during an incident. A failed refresh in CoolDeck keeps the last good snapshot, flags it as stale, and tells you how old it is. When the instance comes back, the next refresh heals it - no restart, and you keep your place in the list.
Command palette, a simulated outage ( F2 in demo mode), and the recovery. Rendered from outage.tape.
Every API call is bounded by a 20-second timeout, every request kind is cancellable, and stale replies from a superseded request are dropped rather than rendered.
| Shortcut | Action |
|---|---|
j / k or ↑ / ↓ |
|
| Move selection | |
g / G |
|
| First / last item | |
Ctrl+D / Ctrl+U |
|
| Page down / up | |
Tab / Shift+Tab |
|
| Next / previous pane | |
Enter / Esc |
|
| Open / back | |
1 2 3 4 |
|
| Applications · Deployments · Instances · Diagnostics | |
q / Ctrl+C |
|
| Back or quit / force quit |
| Shortcut | Action |
|---|---|
d / D |
|
| Deploy / force deploy (confirms) | |
r |
|
| Restart (confirms) | |
s |
|
| Start or stop (confirms) | |
l / L |
|
| Runtime logs / build log | |
b / o |
|
| Open primary domain / repository in the browser | |
c |
|
| Copy application UUID | |
Space / t |
|
| Mark for the fleet tail / open the fleet tail | |
S |
|
| Cycle sort: status → name → last deploy | |
R |
|
| Manual refresh |
| Shortcut | Action |
|---|---|
/ |
|
Filter applications (status: , branch: , free text) - or search the log buffer |
|
: / Ctrl+K |
|
| Command palette; disabled commands show why | |
? |
|
| Help overlay with the complete key map | |
Ctrl+T / Ctrl+W |
|
| Cycle theme / toggle compact layout |
| Shortcut | Action |
|---|---|
Space |
|
/ resume polling (in the applications list, Space marks for the fleet tail instead) |
|
f / w |
|
| Follow tail / wrap long lines | |
/ · n · N |
|
| Search · next match · previous match | |
c |
|
| Copy the buffer, or the current match | |
+ / - |
|
| More / fewer lines fetched (this session) | |
Ctrl+L |
|
| Clear the local buffer |
Full map: press ?
in the app, or read docs/keybindings.md.
No runtime dependencies. Every option below leaves you with a single static binary; only building from source needs a toolchain (Go 1.26.6+, no CGO).
brew install resetnak/tap/cooldeck
cooldeck --demo
Upgrades come with brew upgrade
like anything else. The tap publishes a cask, which Homebrew on Linux does not support - on Linux, use the install script below.
curl -fsSL https://raw.githubusercontent.com/Resetnak/cooldeck/main/install.sh | sh
Detects your platform, verifies the checksum, and drops the binary in ~/.local/bin
. Override
with COOLDECK_INSTALL_DIR
, or pin a version with COOLDECK_VERSION=v0.2.1
. Read it first if you would rather not pipe a script into a shell - it is short.
VER=$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
https://github.com/Resetnak/cooldeck/releases/latest | sed 's|.*/v||')
BASE=https://github.com/Resetnak/cooldeck/releases/download/v$VER
curl -fsSLO "$BASE/cooldeck_${VER}_linux_amd64.deb"
sudo dpkg -i "cooldeck_${VER}_linux_amd64.deb"
sudo rpm -i "$BASE/cooldeck_${VER}_linux_amd64.rpm"
curl -fsSLO "$BASE/cooldeck_${VER}_linux_amd64.apk"
sudo apk add --allow-untrusted "cooldeck_${VER}_linux_amd64.apk"
.deb
, .rpm
and .apk
are built for amd64
and arm64
on every release - swap amd64
for
arm64
above if that is your machine.
Download an archive for your platform from Releases,
unpack it, and put cooldeck
on your PATH
:
tar xzf cooldeck_*_Darwin_arm64.tar.gz # or Linux_x86_64, Linux_arm64, Darwin_x86_64
sudo mv cooldeck /usr/local/bin/
cooldeck version
Windows ships as a .zip
. Every release carries a checksums.txt
; verify before you trust it:
shasum -a 256 -c checksums.txt --ignore-missing
Archives for Linux and macOS (amd64
& arm64
) and Windows (amd64
) are built by
GoReleaser from v*
tags.
go install github.com/resetnak/cooldeck/cmd/cooldeck@latest
git clone https://github.com/Resetnak/cooldeck.git
cd cooldeck
make build # -> bin/cooldeck, with version/commit/date baked in
./bin/cooldeck --demo
install -m 0755 bin/cooldeck ~/.local/bin/cooldeck
CoolDeck reads one TOML file. Find it - and check it - with:
cooldeck config path
cooldeck config validate
| OS | Default directory |
|---|---|
| Linux | |
$XDG_CONFIG_HOME/cooldeck or ~/.config/cooldeck |
|
| macOS | |
~/Library/Application Support/cooldeck |
|
| Windows | |
%AppData%\cooldeck |
version = 1 # schema version; a newer one is rejected, never guessed at
default_instance = "production"
theme = "auto" # auto|dark|light|dracula|catppuccin|nord|gruvbox|tokyo-night
refresh_interval = "10s" # dashboard poll (minimum 3s)
log_refresh_interval = "2s"
log_lines = 300 # default log window (10–10000)
confirm_destructive_actions = true
confirm_deploy = false # set true to confirm ordinary deploys too
[ui]
nerd_font = "auto" # auto|on|off
compact_mode = "auto"
mouse = true
[instances.production]
name = "Production"
url = "https://coolify.example.com"
token_source = "keyring" # keyring|command|env|plaintext
token_key = "production"
COOLDECK_CONFIG_DIR
moves the whole directory - handy for keeping experiments away from your real setup. Full reference: docs/configuration.md.
Resolved in this order: COOLDECK_TOKEN
in the environment always wins, otherwise the instance's
token_source
decides.
| Source | Behaviour |
|---|---|
keyring |
|
OS keychain, written by cooldeck setup or cooldeck auth add - recommended |
|
command |
|
Runs an external command and reads the token from stdout (e.g. ["op", "read", "op://…"] ) |
|
env |
|
| Reads a named environment variable | |
plaintext |
|
Token in the config file (mode 0600 ) - last resort |
cooldeck auth add production # store a token in the keyring
cooldeck auth status production # is one there? (never prints it)
COOLDECK_TOKEN=… cooldeck # one-shot, nothing written anywhere
cooldeck the TUI dashboard
cooldeck --demo offline demo data, no Coolify needed
cooldeck --instance production start on a specific instance
cooldeck --theme catppuccin theme override for this run
cooldeck --debug structured debug log (redacted)
cooldeck mcp serve the instance to an agent over MCP (read-only)
cooldeck mcp --allow-mutations ... and let it deploy, restart, start and stop
cooldeck setup first-run wizard: URL, token, keyring
cooldeck theme interactive theme picker with live preview
cooldeck auth add|status|delete <instance>
cooldeck config path|validate
cooldeck version version, commit, build date
Tokens stay out of sight: never rendered in the UI, never written to logs, toasts or the diagnostics export -enforces the log side, and the diagnostics dump is secret-free by construction.internal/logging/redact.go
Log output is sanitised: raw ANSI control sequences from a remote log stream cannot repaint your terminal.** Only**URLs are ever handed to the browser.http
/https
Deleting an instance removes thelocalconfig entry and its keyring item. It never touches anything in Coolify.Permissions degrade gracefully: Coolify has no permission-introspection endpoint, so CoolDeck assumes full capabilities and switches individual features off on a403
- showing them disabled with a reason rather than hiding them.What it does not protect you from: the config file is written
0600
but aplaintext
token source still puts the token on disk;insecure_skip_verify = true
really does disable TLS verification for that instance; and an MCP client started with--allow-mutations
can deploy, restart, start and stop without a confirmation, because an agent has nobody to ask. All three are opt-in, and all three are worth a second thought.
Reporting a vulnerability: SECURITY.md.
Layered so that the same use cases back the TUI, a CLI subcommand and the MCP server:
cmd/cooldeck → internal/cli cobra, flags, config, service construction
→ internal/tui Bubble Tea model + views (presentation only, no I/O)
→ internal/mcpserver MCP tools over stdio (no HTTP client, no TUI imports)
→ internal/app Service interface = the use cases
├── app/demo deterministic fake service (demo mode + golden tests)
└── coolify HTTP client + DTO → domain mapping
→ internal/domain, config, credentials, logging, platform, version
Built on Bubble Tea / Charm v2. Every TUI screen is covered by golden snapshots rendered from the demo service, so a layout regression fails CI instead of shipping.
| Doc | |
|---|---|
DecisionsCoolify APIMCP serverConfigurationKeybindingsTroubleshootingChangelog
make check # fmt-check + vet + lint + test + build - run this before every PR
make run # go run ./cmd/cooldeck --demo
make test-race
make test-update-golden # refresh the TUI snapshots, then *read the diff*
make lint # staticcheck + golangci-lint (same versions as CI)
make bench # view rendering benchmarks
make vuln # govulncheck
The four GIFs in this README are generated, not hand-recorded: vhs cassette.tape
, vhs tail.tape
,
vhs mcp.tape
and vhs outage.tape
rebuild the binary and re-record against --demo
, so they
cannot drift from the working tree. All of them run in a throwaway COOLDECK_CONFIG_DIR
under
/tmp
and touch nothing of yours.
Shipped: applications dashboard, detail with logs, confirmed mutations, deployments queue,
deployment outcome notifications, multi-instance management, diagnostics, eight themes, demo mode,
an MCP server on the same app.Service
, golden tests, multi-OS CI.
Next: richer in-TUI token sources beyond the keyring, optional read-only views for services, databases and servers, and a non-interactive CLI for scripts and CI.
Bug reports, feature requests and PRs are welcome - see CONTRIBUTING.md for the
local setup, the golden-test workflow and what make check
expects before review. Participation is covered by the Code of Conduct.
MIT © 2026 Alexandr Rešetňak