hope

package module
v0.0.0-...-379fbb2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 14, 2026 License: MIT Imports: 1 Imported by: 0

README

hope

A clean, self-hostable manager for a Docker Compose cluster. One Go binary (sov backend) embeds a loom frontend, reads Docker Compose labels to group containers into stacks, and drives full stack lifecycle — all over the Docker API, so it works against a local socket or a remote daemon with no compose files on disk.

Docs: https://mininote.ink/s/dzW9c7aSbkHOGeD5-jH1qA

Screenshots below use a demo dataset — not a real cluster.

Mission-control overview

Stack control + replica grouping Streaming logs
Stack detail Logs

Features

  • Mission-control overview — every stack at a glance; trouble lights up, the rest stays quiet. A fleet ribbon + synthesized health verdict.
  • Stack control — start / stop / restart / pull / redeploy per stack, and per container, driven entirely through the Docker API (no docker compose shell-out, no mounted compose files). Redeploy pulls images and recreates containers in place, preserving config, networks, and compose labels.
  • Replica grouping — services with multiple containers collapse into one row with bulk actions; expand for per-replica control.
  • Live logs & stats — per container, per service (all replicas multiplexed and source-tagged), or the whole stack. Streamed as NDJSON; auto-scroll + wrap toggle.
  • Update detection — a background crawler compares each container's image against its registry (a manifest lookup — never pulls layers) and flags what's out of date: a dashboard "updates" section, per-row chips on the stack page, and an "update available" button on the container page that redeploys to the latest.
  • Host insight — the dashboard shows the Docker daemon's identity and capacity (version, OS/arch, CPUs, memory, container/image counts) plus cached disk usage (images / volumes / build cache) with an on-demand df refresh.
  • Images view — every local image at a glance (repo:tag, id, size, age) with in-use / unused / dangling tags, searchable, sorted largest-first.
  • Private registry pulls — reads a Docker config.json so pull/redeploy authenticate to private registries (e.g. ghcr).
  • Guarded destructive actions — stop / kill / redeploy require confirmation.
  • Single login — username/password from config; stateless HMAC bearer tokens.
  • Optional socket proxy — expose the Docker API to a trusted LAN behind a method/path allowlist.
  • Container plugins — any container can ship its own hope panel (tables, detail pages, images, charts, live streams, actions) by exposing a small JSON-RPC endpoint and a few labels. hope discovers it across the fleet, and — once enabled — renders it and proxies every call; the browser never touches the plugin. Extend hope in your own container, language, and release cadence — no hope recompile. See the plugin protocol, the Go SDK on pkg.go.dev, and the example plugins (hello-world, hope-postgres, kitchen-sink).

Quick start

cp config.example.toml config.toml   # then edit: username, password, token_secret
cp docker-compose.example.yml docker-compose.yml
docker compose up -d --build

Open http://<host>:8080 and sign in. hope reaches the daemon through the mounted /var/run/docker.sock.

Configuration

See config.example.toml. Every key can be overridden with a HOPE_* env var (e.g. HOPE_AUTH_PASSWORD). Key sections:

  • [auth]username, password (plaintext or a $2… bcrypt hash), and a long random token_secret.
  • [docker] hostunix:///var/run/docker.sock or a remote tcp://host:2375. config optionally points at a Docker config.json for registry credentials (defaults to ~/.docker/config.json). hope reads only inline auth entries — docker login writes those on Linux. Credential helpers / credsStore keep secrets outside the file and can't run in hope's minimal container. Podman works too — it serves the same API: run podman system service and point host at its socket (unix:///run/podman/podman.sock, or unix://$XDG_RUNTIME_DIR/podman/podman.sock rootless). hope groups stacks by the Docker or podman compose labels (io.podman.compose.*), so podman compose / podman-compose projects show up grouped.
  • [auth] api_keys — optional static keys for headless RPC (pass one as the bearer token). Enabling them also turns on the in-app API explorer at /api and sov's schema at /rpc/_introspect. Off by default. See the in-app API page for the calling convention.
  • [[registry]] — explicit registry credentials (server / username / password), the reliable way to authenticate pulls without mounting a config.json or running a helper. Use a Docker Hub account + access token so pulls aren't anonymous and rate-limited. Repeat per registry. An authenticated pull that the registry rejects (rate limit, bad creds) now fails the redeploy loudly instead of silently keeping the old image.
  • [updates] — the image-freshness crawler. enabled (default true), interval (default 6h; mind Docker Hub anonymous rate limits), and an optional cache_path that persists the freshness cache to disk so it survives restarts — mount that path to keep it across container recreates, e.g. cache_path = "/data/updates.json" with a /data volume.
  • [socketproxy] — opt-in LAN proxy; read-only by default.
  • [log]color / json.

Security

  • Mounting the Docker socket grants root-equivalent control of the host to the hope container. Run it only on a trusted network (LAN / overlay like ZeroTier), behind its login — not on a public interface.
  • The socket proxy is the same exposure to whoever reaches its port. It defaults to read-only (GET/HEAD); only allowlist writes deliberately, and never route it through a public tunnel.

Development

Backend (live reload with air):

air            # builds ./cmd/hope, restarts on change (uses ./config.toml)

Frontend (Vite dev server, proxies /rpc to the backend on :8080):

cd frontend && npm install && npm run dev

Build

cd frontend && npm run build      # outputs frontend/dist (embedded by the binary)
go build -o hope ./cmd/hope       # single self-contained binary

Or build the image: docker build -t hope .. If github.com/Toyz/sov is private, pass build credentials (see the Dockerfile header).

Architecture

  • Backend (cmd/hope, internal/*): sov gateway. internal/docker wraps the Docker SDK and groups containers by compose label; internal/stacks, internal/containers, internal/system are RPC routers; internal/auth is the sov AuthService; internal/plugins/logstream streams NDJSON logs/stats; internal/plugins/logger is the unified request logger; internal/socketproxy is the optional LAN proxy. The built SPA is embedded via go:embed.
  • Frontend (frontend/): loom + loom-rpc. A custom RpcTransport adds the bearer token and implements stream() over the NDJSON routes. Pages: login, dashboard (mission control), stack detail, container detail.

License

MIT — see LICENSE.

Documentation

Overview

Package hope embeds the built frontend so the binary can serve its own SPA. The embed lives at the module root because go:embed can only reach files in its own directory subtree, and the build output is frontend/dist.

Index

Constants

This section is empty.

Variables

View Source
var DistFS embed.FS

DistFS is the built frontend tree. The placeholder index.html is replaced by `npm run build` output in frontend/dist.

Functions

This section is empty.

Types

This section is empty.

Directories

Path Synopsis
cmd
hope command
Command hope is a Docker Compose cluster manager: a single Go binary (sov gateway) that embeds the loom frontend, reads compose labels to group containers into stacks, and drives full stack lifecycle.
Command hope is a Docker Compose cluster manager: a single Go binary (sov gateway) that embeds the loom frontend, reads compose labels to group containers into stacks, and drives full stack lifecycle.
hope-boot command
Command hope-boot is a tiny launcher + self-update helper shipped alongside `hope` in the same (scratch) image.
Command hope-boot is a tiny launcher + self-update helper shipped alongside `hope` in the same (scratch) image.
internal
agent
Package agent implements hope's remote-host model.
Package agent implements hope's remote-host model.
auth
Package auth provides hope's single-user login: an HMAC-signed, stateless bearer token plus a sov AuthService router that mints and verifies it.
Package auth provides hope's single-user login: an HMAC-signed, stateless bearer token plus a sov AuthService router that mints and verifies it.
batchstream
Package batchstream adds a STREAMING batch endpoint at /rpc/_batchstream, as a hope-owned sov RouteHandler (no change to the sov framework itself).
Package batchstream adds a STREAMING batch endpoint at /rpc/_batchstream, as a hope-owned sov RouteHandler (no change to the sov framework itself).
catalog
Package catalog is hope's installable-plugin catalog: the machine-readable descriptors that let hope DEPLOY a first-party plugin (pull the image, create the container with the right labels/env/volumes/networks), as opposed to merely DISCOVERING one an operator already ran.
Package catalog is hope's installable-plugin catalog: the machine-readable descriptors that let hope DEPLOY a first-party plugin (pull the image, create the container with the right labels/env/volumes/networks), as opposed to merely DISCOVERING one an operator already ran.
cloudflare
Package cloudflare is a thin, typed client for the slice of the Cloudflare API hope's tunnels domain needs: a remotely-managed tunnel's ingress configuration, tunnel status, and DNS records.
Package cloudflare is a thin, typed client for the slice of the Cloudflare API hope's tunnels domain needs: a remotely-managed tunnel's ingress configuration, tunnel status, and DNS records.
compose
Package compose drives stack-level lifecycle by shelling out to the `docker compose` CLI, using the project/working_dir/config_files metadata that Docker stamps as container labels.
Package compose drives stack-level lifecycle by shelling out to the `docker compose` CLI, using the project/working_dir/config_files metadata that Docker stamps as container labels.
config
Package config loads hope's configuration from a TOML file via viper.
Package config loads hope's configuration from a TOML file via viper.
containers
Package containers exposes the ContainersRouter: per-container inspect and lifecycle control.
Package containers exposes the ContainersRouter: per-container inspect and lifecycle control.
deploy
Package deploy is hope's write path: it turns a StackSpec into running containers (create, or diff-apply against the live stack), creates the networks/volumes a deploy needs, and persists the authored spec so a stack can be reopened and edited.
Package deploy is hope's write path: it turns a StackSpec into running containers (create, or diff-apply against the live stack), creates the networks/volumes a deploy needs, and persists the authored spec so a stack can be reopened and edited.
docker
Package docker wraps the official Docker SDK with the small surface hope needs: list containers grouped into compose stacks by label, control a single container, and open log/stat streams.
Package docker wraps the official Docker SDK with the small surface hope needs: list containers grouped into compose stacks by label, control a single container, and open log/stat streams.
events
Package events is hope's in-process event bus: producers across the daemon publish state-change events, and a single NDJSON RouteHandler (/rpc/_events) fans them out live to the frontend so the rail/sidebar and pages update without a manual refresh.
Package events is hope's in-process event bus: producers across the daemon publish state-change events, and a single NDJSON RouteHandler (/rpc/_events) fans them out live to the frontend so the rail/sidebar and pages update without a manual refresh.
hostguard
Package hostguard is the server-side backstop for host-scoped writes.
Package hostguard is the server-side backstop for host-scoped writes.
hosts
Package hosts tracks the Docker daemons hope can drive — the local socket plus any connected agents — and which one is currently active.
Package hosts tracks the Docker daemons hope can drive — the local socket plus any connected agents — and which one is currently active.
meme
Package meme is a joke.
Package meme is a joke.
pluginhost
Package pluginhost is hope's control plane for container plugins: it discovers containers across the fleet that declare a JSON-RPC endpoint (labels hope.plugin.*), tracks which the operator has trusted, and (in later phases) dials + renders them.
Package pluginhost is hope's control plane for container plugins: it discovers containers across the fleet that declare a JSON-RPC endpoint (labels hope.plugin.*), tracks which the operator has trusted, and (in later phases) dials + renders them.
plugins/accessauth
Package accessauth is a sov RouteHandler that turns a Cloudflare Access assertion into a hope session.
Package accessauth is a sov RouteHandler that turns a Cloudflare Access assertion into a hope session.
plugins/hosttarget
Package hosttarget is a sov ContextContributor that captures the per-request host override (the X-Hope-Host header) onto the RPC context, so a headless API caller can target a specific host per call without mutating the globally-active host.
Package hosttarget is a sov ContextContributor that captures the per-request host override (the X-Hope-Host header) onto the RPC context, so a headless API caller can target a specific host per call without mutating the globally-active host.
plugins/introspectfilter
Package introspectfilter trims hope's /rpc/_introspect (and thus the explorer) down to the public API surface.
Package introspectfilter trims hope's /rpc/_introspect (and thus the explorer) down to the public API surface.
plugins/logger
Package logger is hope's request-logging plugin.
Package logger is hope's request-logging plugin.
plugins/logstream
Package logstream is a sov RouteHandler plugin that streams container logs and stats as NDJSON (application/x-ndjson, one JSON object per line) over a chunked response.
Package logstream is a sov RouteHandler plugin that streams container logs and stats as NDJSON (application/x-ndjson, one JSON object per line) over a chunked response.
socketproxy
Package socketproxy is hope's opt-in, LAN-facing reverse proxy that forwards the Docker HTTP API to the unix socket behind a method/path allowlist.
Package socketproxy is hope's opt-in, LAN-facing reverse proxy that forwards the Docker HTTP API to the unix socket behind a method/path allowlist.
stacks
Package stacks exposes the StacksRouter: the dashboard listing plus stack lifecycle.
Package stacks exposes the StacksRouter: the dashboard listing plus stack lifecycle.
stackspec
Package stackspec is hope's structured deploy model: a StackSpec (a whole compose-style stack) and its ContainerSpec services.
Package stackspec is hope's structured deploy model: a StackSpec (a whole compose-style stack) and its ContainerSpec services.
store
Package store is hope's optional embedded state: a single bbolt file (pure Go, no external deps, CGO-free) at a mounted path.
Package store is hope's optional embedded state: a single bbolt file (pure Go, no external deps, CGO-free) at a mounted path.
system
Package system exposes the SystemRouter: daemon-wide info and disk usage.
Package system exposes the SystemRouter: daemon-wide info and disk usage.
tunnels
Package tunnels exposes the TunnelsRouter: manage a Cloudflare tunnel's public routes per stack.
Package tunnels exposes the TunnelsRouter: manage a Cloudflare tunnel's public routes per stack.
version
Package version exposes build information stamped into the binary at link time (-ldflags -X).
Package version exposes build information stamped into the binary at link time (-ldflags -X).
plugin module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL