Container suite for the whole lifecycle: authoring → run → ship.
A galleon carries containers across long routes. This one does the same with your Docker images — it scaffolds them, runs them, and ships them to every port that matters.
Most Docker tooling sits in one of three places:
- Authoring — handwritten Dockerfiles, copy-pasted across projects.
- Run/inspect —
docker ps,docker logs, or a TUI like lazydocker. - Release — ad-hoc scripts that build and push to one registry.
galeon covers all three with one opinionated CLI:
| Phase | What galeon gives you |
|---|---|
| Authoring | A tailored Dockerfile per language, generated from what's actually in the project (Rust, Go, Node, Python) |
| Run/inspect | A CLI (and a TUI) to list, inspect and control containers, grouped by project |
| Ship | Multi-arch build, push to N registries, SBOM, remote deploy |
From an empty checkout to a running stack, without writing a Dockerfile:
$ galeon init
rust 1.85 · axum on :8080 · cargo
wrote Dockerfile, .dockerignore, compose.yaml, .env.example
$ galeon up --build
$ galeon ps
myapp up 12s healthy :8080
myapp-db up 12s healthy postgres:16
$ galeon logs -p myapp -f # every service of the project, prefixed
$ galeon ship --to ghcr.io/me --sbomThe same project then goes to a cluster without a second toolchain:
galeon k8s generate --ingress --with postgres writes the Deployment, the
Service and the StatefulSet for the database, wired to each other; galeon k8s apply puts it there.
galeon init # detect stack(s); scaffold Dockerfile + .dockerignore + compose.yaml + .env.example
galeon init --with postgres,redis,nginx # also wire those services into compose
galeon tui # interactive TUI — the fleet at the helm
galeon up [--build] [-f] # bring the compose stack up (detached; -f to stream)
galeon down [-v] # tear the stack down (-v also removes volumes)
galeon ps [-a] [-w] # containers grouped by project; health-aware; -w to watch
galeon stats [-p <project>] [-w] # live CPU / memory usage, grouped by project
galeon status [-p <project>] # per-project rollup: up count, health, total CPU / memory
galeon inspect <name> # curated details: state, image, networks, ports, mounts, env
galeon exec [-it] <name> <cmd> # run a command in a container (-it for a shell)
galeon cp <src> <dst> # copy files host↔container (container:path)
galeon events [-p <project>] # stream Docker daemon events (optionally per project)
galeon logs <name> [-f] # a container's logs (or -p <project> for aggregated, prefixed)
galeon start|stop|restart <name>... # lifecycle (or -p <project> for the whole stack)
galeon rm <name>... [-f] # remove containers (or -p <project>)
galeon swarm deploy [--build] # deploy the compose stack to Docker Swarm
galeon swarm ls|ps|rm|scale … # manage the Swarm stack
galeon k8s generate [--ingress] [--with pg,redis] # k8s manifests: app + services
galeon k8s apply|delete # kubectl apply/delete the manifests
galeon k8s pods [-n <ns>] # list pods natively via the Kubernetes API
galeon provision <tenant> [--with pg,redis] [--image ref] \
[--replicas N] [--cpu 500m] [--memory 512Mi] [--env K=V] # deploy a tenant
galeon deprovision <tenant> # delete a tenant's namespace
galeon tenants # list provisioned tenants + pod counts
galeon nomad generate # generate a Nomad job (HCL)
galeon nomad run|stop|status # nomad job run/stop/status
galeon titus generate # generate a Titus (Netflix) job descriptor
galeon build [--tag T] [--platform P] # build the image (buildx for multi-arch)
galeon ship --to <reg>... [--sbom] [--sign] # push (+ syft SBOM, cosign sign)
galeon <plugin> ... # dispatch to galeon-<plugin> binary on PATH
Auto-detection covers the common case; a .galeon file at the project root lets
you override and extend it. It is optional — without it, nothing changes.
[stack]
kind = "rust" # force the stack instead of auto-detecting
[services]
with = ["postgres", "redis"] # attach catalog services (same ids as --with)
[compose]
port = 9090 # publish/expose this instead of the detected port
env = { RUST_LOG = "info" } # extra environment on the app service
[inspect]
ports = ["src/main.rs"] # scan these files for the port the app bindsPrecedence is --stack flag > .galeon > auto-detect; --with and
[services].with are unioned. Port precedence is [compose].port >
[inspect] scan > stack detection — a port found by [inspect] is written
into both the Dockerfile EXPOSE and compose.
Plugins are standalone binaries discovered on PATH, in the style of
git-lfs or cargo-watch. If you run galeon foo and galeon-foo exists,
galeon hands off to it.
Planned official plugins:
| Plugin | Purpose |
|---|---|
galeon-torii |
Image ↔ Torii snapshot traceability, blame, reproducible tags |
galeon-gate |
Generate and validate the .gate CI workflow for the project |
galeon-svitrio |
Svitrio-specific templates and deploys to Svitrio Cloud |
galeon-rumb |
Binary releases: cross-compilation, per-platform packaging, signing |
Plugins are not bundled with the core. Install only what you use:
cargo install galeon-rs # the package is galeon-rs; the binary is galeon
cargo install galeon-torii # opt-in
Pre-alpha: the interface still moves between versions, and the depth is uneven on purpose. Docker and Kubernetes are where the work went — those two are used daily. Swarm runs the same compose. Nomad and Titus are authoring only: galeon writes the job, their own CLI submits it.
Working:
- Plugin dispatch (
galeon <unknown> ...→galeon-<unknown>on PATH). galeon initfor Rust, Go, Node, Python, Java, .NET, Ruby, PHP and C/C++ — inspects the project (versions, package manager, native libraries, web framework) and writes the full set to run and manage it: a tailoredDockerfile,.dockerignore,compose.yaml(wired with the detected port and the galeon project label), and.env.example. Polyglot repos are detected and ask you to pick with--stack.- OS bases (
--stack ubuntu|debian|alpine|fedora) for hand-rolled images. --withattaches catalog services to the compose:postgres,mysql,mariadb,redis,mongo,nginx,caddy— databases get wired into the app with a connection-URL env anddepends_on.
- OS bases (
- Container CLI over the local Docker daemon, grouped by project:
ps(health-aware,-wto watch),stats(-w),status(per-project rollup),inspect,events,logs,start,stop,restart,rm(via the API), plusup/down/exec/cpwhich wrap thedockerCLI where it's the right tool (compose orchestration, interactive TTY, file copy).logs/start/stop/restart/rmandstats/status/eventstake-p/--projectto act on a whole project at once. The whole loop stays in galeon:init → up → ps → logs → down. - Orchestration (multi-target, via an
Orchestratortrait):- Docker Swarm —
galeon swarm deploy/ls/ps/rm/scaleruns the generated compose as a stack (the compose is portable betweencompose upanddocker stack deploy). - Kubernetes —
galeon k8s generatewrites the app's Deployment + Service (+ optional Ingress) plus, per--withservice, a StatefulSet + headless Service (for stateful services with a volume) or a Deployment + Service, with the app'sDATABASE_URL/etc. wired to the in-cluster Service names.galeon k8s apply/deletewrapkubectl, andgaleon k8s podslists pods natively via the Kubernetes API (kube-rs). The same manifests serve the whole k8s family —--variant openshiftemits aRouteinstead of an Ingress,--variant rancheradds a Fleet bundle; k3s uses them as-is. - Nomad —
galeon nomad generatewrites a Docker-driver job (HCL);galeon nomad run/stop/statuswrap thenomadCLI. - Titus —
galeon titus generatewrites a Netflix Titus job descriptor (authoring only; submit it to your Titus gateway).
- Docker Swarm —
galeon buildbuilds the project image (docker build;--platformswitches to buildx, pushing for multi-arch), defaulting to the<project>:latesttag compose / k8s reference.galeon ship --to <reg>...tags and pushes it to one or more registries, optionally generating a CycloneDX SBOM (--sbom, via syft) and signing the pushed image (--sign, via cosign).
The full lifecycle runs in galeon: init → build → up | swarm deploy | k8s apply → ps/logs/stats → down, and ship to any registries.
galeon tuiis an interactive terminal UI on top of the same engine — the fleet grouped by project, live CPU/mem telemetry for the selected vessel, scrollable and syntax-highlighted live logs (log levels + embedded SQL), a/filter, and lifecycle actions, with a nautical two-sail motif. Press⇥to switch between Docker containers and Kubernetes pods (live pod list across namespaces via kube-rs, following your current kubeconfig context);⏎streams a pod's logs into the same scrollable, highlighted log view, andddeletes the selected pod (with confirmation). In the k8s view,nopens a deploy panel: it detects your app, you set its image (i, e.g. a registry ref) and target namespace (N, auto-created), toggle backing services (postgres/redis/…) and an ingress, and⏎deploys the whole ecosystem into that namespace (kubectl applyof the generated manifests);xtears the same stack back down.- A third view (
⇥again) is the tenant control plane: it lists namespaces labelledgaleon.tenantas tenants (with live pod counts).nprovisions a new tenant — deploys the template into its own labelled namespace;ddeprovisions it (deletes the namespace);⏎drills into that tenant's pods. The same provisioning engine is also available headlessly —galeon provision <tenant>/deprovision <tenant>/tenants— so a billing webhook or CI can drive it, sharing one code path with the TUI. Plans stay the product's business: galeon takes product-agnostic knobs (--replicas,--cpu,--memory,--env K=V,--with,--image), and your automation maps each plan to them.
The core CLI is open source, licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
galeon follows an open-core model: the galeon CLI is and stays open, while
commercial functionality (e.g. Svitrio Cloud deploys) may live in separate
plugins under their own terms.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.