Skip to content

Latest commit

 

History

49 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

komposer

CI

A terminal UI for putting together a compose.yaml fast — either service by service, or as a ready-made multi-service stack (a database plus its admin UI, a blog platform plus its database, and so on) in a single keystroke. Built with Bubble Tea and Lipgloss.

It also validates what you build as you go — not just YAML syntax, but common Docker footguns: ports quietly published on every network interface, an empty or hardcoded secret, a database with no volume (so its data disappears the moment the container is recreated).

It's also safe to use as a viewer/editor on a compose.yaml (or docker-compose.yml) you already have. Import keeps every field verbatim, including ones this tool's form can't edit (command, networks, container_name, labels, env_file, secrets, x-* extensions, and so on) — editing one service through the form and saving never drops the rest of the file.

Features

  • 3-pane TUI: services list, service config, live YAML preview — the preview updates as you type, so you always see the file you're about to save.

  • First-launch screen: an empty config shows a small button menu (add a service / browse presets & stacks / import a file) instead of three empty panes — navigable by arrow keys, Enter, or a mouse click.

  • Presets — drop in a single well-configured service (Postgres, Redis, Nginx, MySQL, MongoDB) instead of typing out image:, ports:, etc. by hand.

  • Stacks — drop in several services at once, already wired together (depends_on, matching hostnames, shared env vars). Covers common combinations like a database with its admin UI (Postgres + PgAdmin, MySQL + phpMyAdmin, Mongo + Mongo Express, Adminer + Postgres), a CMS or app platform with its database (WordPress + MySQL, Ghost + MySQL, Nextcloud + Postgres, Nextcloud + Redis + MariaDB, Directus + Postgres), and common infra pairings (Prometheus + Grafana, Elasticsearch + Logstash + Kibana, Redis + RedisInsight, Gitea + Postgres, Metabase + Postgres, n8n + Postgres, Portainer + Watchtower). If a stack's default service name is already taken, it's renamed automatically (dbdb-2) rather than refusing or silently overwriting anything.

  • Validation (Ctrl+V, scrollable) — three separate reports, so "komposer thinks this is risky" and "Docker Compose would reject this outright" never get confused with one another:

    • Errors — komposer's own required-field, port-format, restart-policy, and depends_on-reference checks (including a depends_on: condition: service_healthy that points at a service with no healthcheck configured — Compose refuses to start that stack, so this is an Error rather than a Warning),
    • Warnings — non-blocking advisories: a port published on every network interface (Docker's default) with a suggested 127.0.0.1:... fix, an environment variable that looks like a secret (by name) with an empty or hardcoded value, a recognized database/stateful image with no volume configured or no healthcheck configured, Postgres published on the network with no POSTGRES_PASSWORD set, an image with no tag (or an explicit :latest) — either resolves to whatever latest happens to point to right now, which can pull a different image on every docker compose pull with no change to the file itself; a digest reference (image@sha256:...) doesn't trigger this, since it's already fully pinned, a bind-mounted Docker socket (/var/run/docker.sock), cap_adding a capability that meaningfully widens host access (ALL, SYS_ADMIN, NET_ADMIN, SYS_PTRACE, SYS_MODULE), network_mode: host, pid: host, and a security_opt that disables seccomp/AppArmor confinement,
    • Compose specification — checked against the official Compose Specification JSON Schema (vendored under pkg/composer/schema/), independent of the two checks above.

    Warnings never block saving — they're advisory, shown separately from hard errors.

  • Import (Ctrl+O) an existing compose.yaml or docker-compose.yml — parses the raw YAML tree rather than a fixed struct, so any field this tool doesn't have explicit support for is captured and re-emitted untouched on export instead of being silently dropped. Both depends_on forms (short list and long map-with-condition) are understood.

  • Explicit save (Ctrl+S) — prompts for a path (defaulting to compose.yaml) and asks before overwriting an existing file. If you quit (q or Esc) with unsaved changes, you get the same prompt instead of losing them silently.

  • Editing a service: Esc discards your edits (asking for confirmation only if you actually changed something) rather than saving automatically; Ctrl+S saves explicitly.

  • Mouse wheel and keyboard both scroll the services list, the YAML preview, and the validation report.

Install

Download a prebuilt binary (Linux, macOS, Windows)

Grab the archive for your platform from the Releases page, then:

Linux / macOS

tar -xzf komposer_*_<os>_<arch>.tar.gz
chmod +x komposer
sudo mv komposer /usr/local/bin/   # or anywhere on your $PATH

macOS will refuse to run the binary the first time because it isn't notarized (Gatekeeper). Either right-click it in Finder and choose "Open" once, or clear the quarantine flag from a terminal:

xattr -d com.apple.quarantine komposer

Windows

Unzip komposer_*_windows_<arch>.zip and run komposer.exe from a terminal (PowerShell or Windows Terminal — it's a TUI, it needs a real terminal, not double-clicking from Explorer). Put it somewhere on your PATH (e.g. %LOCALAPPDATA%\Microsoft\WindowsApps) if you want to run it as just komposer from anywhere.

Windows SmartScreen may warn about an unsigned binary the first time — click "More info" → "Run anyway". This is expected for an unsigned open-source binary; there's no code-signing certificate behind these builds.

<arch> is amd64 for regular 64-bit Intel/AMD machines and arm64 for Apple Silicon Macs or ARM64 Windows/Linux.

Via go install (any platform with Go 1.24.2+)

go install github.com/casablanque-code/komposer@latest

This puts a komposer binary in $(go env GOPATH)/bin — make sure that's on your PATH. Installs a specific version instead of the latest with @vX.Y.Z (e.g. @v0.1.0).

From source

git clone https://github.com/casablanque-code/komposer.git
cd komposer
go build -o komposer .

Requires Go 1.24.2+. Run it directly without a separate build step with go run . instead, if you'd rather not produce a binary.

Usage

./komposer

First launch (no services yet)

Key Action
/ move between the 3 buttons
Enter, or a mouse click activate the highlighted/clicked button
a / Ctrl+P / Ctrl+O jump straight to add / presets & stacks / import, same as their buttons

Navigation (once at least one service exists)

Key Action
/ switch focus between the three panes
/ , mouse wheel services list: move selection · YAML preview: scroll
a add a new service (prompts for a name)
d delete the selected service (prompts for confirmation)
Enter / e edit the selected service (center pane must be focused)

Editing a service

Key Action
/ move within a multi-line field (ports/environment/volumes); at the top/bottom edge, switches to the previous/next field
Tab / Shift+Tab switch field directly
Enter insert a new line, in ports/environment/volumes
Ctrl+S save the service and return to the normal view
Esc discard changes and return — asks for confirmation only if anything actually changed

Presets, stacks, validation, import

Key Action
Ctrl+P open the preset/stack picker — / switches between the Presets and Stacks tabs, / navigates, Enter adds the selection
Ctrl+V run validation — shows errors and warnings for the current config, scrollable with / or the mouse wheel
Ctrl+O import an existing compose.yaml or docker-compose.yml

Saving and quitting

Key Action
Ctrl+S save — prompts for a path (default compose.yaml), asks before overwriting an existing file
q / Esc quit — if there are unsaved changes, opens the same save prompt with an explicit "quit without saving" option; quits immediately otherwise
Ctrl+C quit immediately, no prompt

Project layout

  • pkg/composer — the domain model: services, presets, stacks, YAML import/export, and validation. No TUI dependencies — usable as a library on its own.
  • internal/tui — the Bubble Tea/Lipgloss terminal UI.

Development

go build ./...
go vet ./...
go test ./... -race

CI (.github/workflows/ci.yml) runs go vet, a gofmt check, and the test suite (with -race) on Linux, macOS, and Windows for every push and pull request against main.

Tagged releases (vX.Y.Z) are built and published automatically by .github/workflows/release.yml via GoReleaser — see .goreleaser.yaml for the build/archive configuration.

About

tui for building, validating and editing Docker Compose files

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages