Open-source Hubfly CLI written in Go.
Repo: https://github.com/hubfly-space/hubfly-cli
Linux/macOS:
curl -fsSL https://raw.githubusercontent.com/hubfly-space/hubfly-cli/main/install.sh | bashThen verify:
hubfly version- Token-based auth (
login,logout,whoami) - Persistent Bubble Tea TUI for project/container/tunnel workflow (
projects) - Single and multiple tunnel connect flows
- SSH, one-shot command exec, and log streaming for containers
- Local-first stack orchestration for Compose-style apps (
stack) - Local tunnel status screens while sessions are active
- Local
hubfly deployflow with reusablehubfly-builder,hubfly.build.json, deploy diffs, and resumable image uploads - Build config helpers:
hubfly build init|validate|edit|explain - Debug mode for API requests/responses (
--debugorHUBFLY_DEBUG=1) - Built-in version and self-update commands
- Tunnel service mode (
service) - GitHub Pages documentation page in
index.html
hubfly login [--token <TOKEN>]
hubfly logout
hubfly whoami
hubfly projects
hubfly deploy [advanced|--advanced] [--project <id|name|new>] [--region <region>] [--yes]
[--config <path>] [--detach] [--dockerfile <path>] [--builder-version <tag>]
hubfly stack plan [--file <compose-file>]
hubfly stack up [--file <compose-file>] [--project <id|name|new>] [--region <region>] [--yes] [--remove-orphans] [--no-build]
hubfly stack status [--file <compose-file>]
hubfly stack logs [service...] [--follow|-f]
hubfly stack exec <service> -- <cmd> [args...]
hubfly stack ssh <service>
hubfly stack down [--file <compose-file>] [--volumes] [--yes]
hubfly build init [--config <path>] [--dockerfile <path>] [--force] [--print]
hubfly build validate [--config <path>] [--dockerfile <path>] [--builder-version <tag>] [--json]
hubfly build edit [--config <path>]
hubfly build explain [--config <path>] [--dockerfile <path>] [--builder-version <tag>] [--json]
hubfly tunnel <containerIdOrName> <localPort> <targetPort>
hubfly ssh <containerIdOrName> [-- <cmd> [args...]]
hubfly exec <containerIdOrName> -- <cmd> [args...]
hubfly logs <containerIdOrName> [--follow|-f]
hubfly orgs
hubfly version
hubfly update --check
hubfly update
hubfly service [--port <port>]By default the CLI talks to:
https://api.hubfly.spaceOverride it for local or staging environments:
HUBFLY_API_URL=http://127.0.0.1:3000 hubfly whoamiAPI errors include the backend trace ID when the dashboard returns one, for example:
Authentication required (status 401, trace err_...)
Use that trace ID to find the matching backend log.
↑/↓orj/k: moveenter: select/confirmesc: backq: quit from top-level- Type text in filterable lists to search
Multi-tunnel selection:
space: toggle tunnela: toggle allenter: continue
hubfly version shows:
- version tag
- commit SHA
- build date
- OS/arch
hubfly update --check checks latest release.
hubfly update downloads the latest release for your OS/arch and replaces the local binary (Linux/macOS).
hubfly deploy works directly from your project directory. The CLI:
- creates or reuses
hubfly.build.json - checks for the latest
hubfly-builderrelease before deploy unless--builder-versionpins a specific version - runs builder inspection for auto-detected stacks
- builds the Docker image locally on your machine
- uploads a compressed image archive to the regional builder with retryable chunk uploads
- reports local build/upload failures back to the authenticated CLI deploy session endpoint
- waits for the deploy by default, or returns early with
--detach
Common examples:
hubfly deploy
hubfly deploy advanced
hubfly deploy --project new --region rw-kigali-1 --yes
hubfly deploy --project my-api --dockerfile ./deploy/Dockerfile --yes
hubfly deploy --config ./ops/hubfly.build.json --builder-version v1.7.1 --yesImportant flags:
--project: existing project id/name, ornew--region: required for non-interactive new-project deploys--yes: required in non-interactive/scripted deploys after reviewing the diff--config: customhubfly.build.jsonpath or project directory--detach: stop after upload and let Hubfly finish the deploy asynchronously--dockerfile: force Dockerfile mode for this run--builder-version: pin a specifichubfly-builderrelease
Before deploy, the CLI shows a diff for:
- image source
- resources
- ports
- volumes
- runtime environment variables
- healthcheck
- bound-container replacement behavior
Non-interactive deploys should provide enough information up front:
hubfly deploy --project my-api --region eu-1 --config ./hubfly.build.json --yesUse --detach when a script only needs to upload the image and let Hubfly finish deployment in the background.
hubfly deploy does not require any manual setup, but the build helpers are useful when you want to inspect or adjust the config explicitly.
hubfly build init
hubfly build validate
hubfly build edit
hubfly build explainWhat they do:
hubfly build init: create or refreshhubfly.build.jsonhubfly build validate: resolve the effective build plan and verify Dockerfile/builder inputshubfly build edit: openhubfly.build.jsonin$EDITORhubfly build explain: show whathubfly-builderdetected and why
Useful JSON output:
hubfly build validate --json
hubfly build explain --jsonThose commands are meant for CI and for comparing the local build plan against what the dashboard will deploy.
Enable debug:
hubfly --debug projects
# or
HUBFLY_DEBUG=1 hubfly projectsWhen debug mode is enabled:
- Non-TUI commands print debug lines to stderr.
- During TUI mode (
projects), debug lines are written to:~/.hubfly/logs/debug.log
Debug output includes:
- HTTP method/URL
- masked Authorization token
- request/response payloads
- tunnel route selection details
- backend error/request trace IDs when the API returns them
Runtime logs:
hubfly logs <containerIdOrName>
hubfly logs <containerIdOrName> --follow
hubfly stack logs api --followRemote command execution:
hubfly ssh <containerIdOrName>
hubfly ssh <containerIdOrName> -- ls -la /app
hubfly exec <containerIdOrName> -- printenv
hubfly exec <containerIdOrName> -- sh -lc "ls -la /app"
hubfly stack exec api -- printenv
hubfly stack ssh apihubfly stack reads a local Compose-style file, builds any build: services on the user machine, pushes them through the authenticated regional registry upload flow, and creates or updates each service as a normal Hubfly container.
Supported today:
imageandbuildservices- named volumes
environmentandenv_fileports,depends_on,healthcheck, andrestartx-hubflyoverrides for tier, resources, runtime, and volume size
Current behavior:
- build-backed services redeploy in place through the existing CLI deploy session path
- image-only services are recreated when their config changes
- bind mounts are ignored with warnings; use named volumes instead
Examples:
hubfly stack plan --file docker-compose.yml
hubfly stack up --project new --region eu-1 --yes
hubfly stack status
hubfly stack logs web --follow
hubfly stack down --volumes --yesFor tunnel connections, the CLI now uses a Hubfly-managed known_hosts file to avoid interactive host-key failures:
UserKnownHostsFile=~/.hubfly/known_hostsHostKeyAlias=hubfly-<tunnelId>StrictHostKeyChecking=accept-newBatchMode=yes
This prevents global ~/.ssh/known_hosts conflicts and avoids prompt-based failures in TUI sessions.
hubfly service
hubfly service --port 5600Endpoints:
GET /healthPOST /startPOST /stopGET /status
This is useful when a desktop app, editor extension, or local automation needs to manage Hubfly tunnels without controlling the interactive TUI.
This repository includes a standalone docs page:
index.html
It uses Tailwind through the CDN and can be shipped directly with GitHub Pages from the repository root.
git clone https://github.com/hubfly-space/hubfly-cli.git
cd hubfly-cli
go build -o hubfly .
./hubfly versionGitHub Actions workflow builds and publishes release assets on tag push (v*):
hubfly_linux_amd64.tar.gzhubfly_linux_arm64.tar.gzhubfly_darwin_amd64.tar.gzhubfly_darwin_arm64.tar.gzhubfly_windows_amd64.ziphubfly_windows_arm64.zip
Each release asset also has a .sha256 checksum file.
- Token:
~/.hubfly/config.json - Keys:
~/.hubfly/keys - Known hosts (Hubfly-managed):
~/.hubfly/known_hosts - Debug logs:
~/.hubfly/logs/debug.log
go build ./...
go test ./...