CLI
The Hubfly CLI is the local-first way to deploy apps, manage repeatable build configuration, automate deployments from scripts, and open private HubTunnels without doing everything through the dashboard.
Use the CLI when you want the speed of your terminal with the operational model of Hubfly Space: projects, regions, containers, runtime resources, persistent storage, environment variables, public endpoints, private tunnels, and deployment history.
The CLI is best for developers and teams that want fast local deploys, reproducible config files, scripted workflows, and private access to internal services. The dashboard remains the best place to inspect topology, costs, logs, domains, load balancers, Firewall rules, and team-level operations.
What the CLI is for
The CLI covers four main workflows:
| Workflow | What it does | Best for |
|---|---|---|
| Local deploys | Builds locally, uploads the image, and deploys it to a Hubfly project | Fast iteration from a developer machine |
| Build config management | Creates, validates, edits, and explains hubfly.build.json | Repeatable deployment settings |
| CI/CD deploys | Runs hubfly deploy non-interactively with flags | Automated deploy pipelines |
| HubTunnels | Creates local port forwards to private containers | Database access, internal dashboards, private APIs |
The CLI does not replace the full dashboard. It gives you a terminal-native path for the operations that are naturally local: building from a directory, deploying from a config file, and forwarding private ports to your laptop.
Install
Install the CLI globally with npm:
npm install -g hubfly-cli
Verify it is available:
hubfly --help
Recommended prerequisites:
- Node.js and npm available on your machine
- A Hubfly account
- Access to the target project
- Docker support or local build support expected by the CLI builder workflow
- Network access to Hubfly and the target region upload endpoint
Authenticate
The CLI uses a browser-based authentication flow and creates a personal access token for the CLI session.
Start login
hubfly loginComplete browser authentication
The browser opens a Hubfly CLI authentication page. After login, the token is returned to the CLI automatically when possible or displayed for copy/paste.
Keep the token private
The generated token starts with hf_ and grants API access as your user. Treat it like a secret.
The profile area also exposes CLI access management so you can review CLI tokens from your account settings.
Deploy From Your Machine
hubfly deploy is the main local deployment command.
When you run it from a project directory, the CLI prepares a deploy plan, builds the app locally, uploads the resulting image to the selected Hubfly region, and asks Hubfly to create or replace a container using the deployment config.
Typical command:
hubfly deploy
Advanced/config-first path:
hubfly deploy advanced
Non-interactive example:
hubfly deploy \
--project proj_123 \
--region eu-west-1 \
--config ./hubfly.build.json \
--yes
How CLI deploy works
A CLI deploy follows this high-level flow:
- The CLI loads or creates
hubfly.build.json. - It resolves the target project, region, container name, runtime settings, ports, env vars, and deployment mode.
- It uses a local Hubfly Builder version to build the image from your machine.
- It creates a deploy session in Hubfly.
- Hubfly returns a regional image upload endpoint and a one-time upload token.
- The CLI uploads the built image to the region.
- Hubfly records the uploaded image as a Hubfly-owned project image.
- Hubfly deploys the image as a new container or swaps it into the bound container.
- The project build/deployment history updates with the CLI build result.
This is why CLI deploys are fast for local iteration but still visible in Hubfly operations.
CLI deploy sessions
Behind the scenes, a CLI deploy creates a build session with metadata such as:
| Field | Purpose |
|---|---|
| Build ID | Tracks the CLI deploy in project build history |
| Upload token | Authorizes the image upload for that build session |
| Builder version | Records which local builder produced the image |
| Bound container ID | Tells Hubfly which existing container should be replaced |
| Project and region | Determines where the image is uploaded and deployed |
Upload tokens are checked when the build callback arrives. This prevents a random upload from being attached to the wrong CLI build session.
Bound container redeploys
The CLI stores the target container in hubfly.build.json after the first successful deploy. On the next deploy, Hubfly uses that binding to replace the same logical container instead of creating a brand-new service every time.
This behavior is important for production because it preserves the operational surface around the service:
- Same container identity where possible
- Same public endpoint intent
- Same project placement
- Cleaner build history
- Fewer duplicate services after repeated local deploys
If the bound container no longer exists, the CLI can clear the stale binding and continue by creating a new container.
Build Config File
The CLI stores deployment intent in hubfly.build.json.
This file is the bridge between local development and Hubfly operations. It tells the CLI what to build and tells Hubfly how the result should run.
It can include:
- Project ID, project name, and region
- Bound container ID and container name
- Build mode, working directory, context directory, and Dockerfile path
- Deployment tier and resources
- Runtime behavior such as auto-sleep, always-on, and scaling flags
- Ports and protocols
- Environment variables and scopes
- Volume definitions
- Builder metadata from previous deploys
Example:
{
"version": 1,
"project": {
"id": "proj_123",
"name": "edge-api",
"region": "eu-west-1"
},
"container": {
"id": "cont_456",
"name": "api"
},
"build": {
"mode": "auto",
"workingDir": ".",
"contextDir": "."
},
"deploy": {
"tier": "dedicated",
"resources": {
"cpu": 1,
"ram": 800,
"storage": 1
},
"runtime": {
"autoSleep": false,
"autoScale": false,
"is24x7": true
},
"ports": [
{
"container": 3000,
"protocol": "TCP"
}
]
},
"env": [
{
"name": "NODE_ENV",
"value": "production",
"scope": "runtime"
}
]
}
You do not need to run hubfly build init before hubfly deploy. The deploy command can create hubfly.build.json when needed. Use the helper commands when you want to manage the file deliberately.
Build Config Helpers
These commands work with the same hubfly.build.json file used by hubfly deploy.
hubfly build init
hubfly build validate
hubfly build edit
hubfly build explain
| Command | Use it when |
|---|---|
hubfly build init | You want to create or refresh a config before deploying |
hubfly build validate | You want to catch config shape issues before a deploy |
hubfly build edit | You want to open the config in your editor |
hubfly build explain | You want to understand what the builder detected and how it will run |
A good production workflow is to keep hubfly.build.json in version control when it describes stable deployment behavior, while keeping secrets out of it.
Build modes
The CLI can build from automatic detection or from an explicit Dockerfile.
| Mode | Best for | Watch out for |
|---|---|---|
| Auto | Common frameworks and conventional app layouts | Verify detected command, port, and working directory |
| Dockerfile | Teams with explicit container builds | Keep Dockerfile production-ready and avoid local-only assumptions |
| Advanced config | Nonstandard apps, monorepos, custom commands | Be explicit about context, working dir, env scopes, and runtime command |
Dockerfile support
If your project already has a Dockerfile, the CLI can use it directly. This is often the best option for teams that already build containers in CI or need precise runtime control.
Example Dockerfile config:
{
"build": {
"mode": "dockerfile",
"dockerfilePath": "./deploy/Dockerfile"
}
}
Use Dockerfile mode when you need:
- OS packages
- Multi-stage builds
- Custom system dependencies
- Exact runtime entrypoints
- Reproducible local/CI/prod images
- Framework behavior the auto-detection path should not guess
Runtime configuration
A CLI deploy does more than upload an image. The deploy config also tells Hubfly how to run the container.
Important runtime decisions include:
| Setting | Why it matters |
|---|---|
| Tier | Shared or dedicated runtime behavior |
| CPU/RAM/storage | Resource allocation and cost baseline |
| Auto-sleep | Whether idle services can sleep |
| Always-on | Whether a service should stay running continuously |
| Auto-scale | Whether vertical runtime scaling should be enabled |
| Ports | Which container ports Hubfly should expose or track |
| Env vars | Runtime and build-time configuration |
| Volumes | Persistent data attachments |
For production, do not treat these as defaults to skip. Review them like infrastructure configuration.
Environment variables
Environment variables in CLI config should be intentional.
Use them for:
- Runtime modes such as
NODE_ENV=production - API URLs
- Feature flags
- Database connection strings
- Service tokens
- Build-time settings when required
Avoid:
- Committing real production secrets to Git
- Mixing build-time and runtime variables accidentally
- Depending on local
.envfiles that CI will not have - Changing env vars without redeploying when the app reads them only at startup
Use Hubfly dashboard/project secret management patterns for sensitive production values when that is safer for your team.
Non-Interactive And CI
The CLI supports scriptable deploys for CI, automation, and headless environments.
Common flags:
| Flag | Purpose |
|---|---|
--project | Select the target project |
--region | Select the deployment region |
--config | Use a specific hubfly.build.json path |
--yes | Skip interactive confirmation |
--detach | Return after upload while deployment continues in Hubfly |
--dockerfile | Override Dockerfile path for the run |
--builder-version | Pin the Hubfly Builder version |
Example CI deploy:
hubfly deploy \
--project proj_123 \
--region eu-west-1 \
--config ./hubfly.build.json \
--builder-version v1.7.1 \
--yes
Use --yes only when the config has already been reviewed. CI should not be discovering production deployment settings for the first time.
CI/CD recommendations
For reliable CI deploys:
- Commit
hubfly.build.jsonif it represents stable deploy intent. - Store CLI tokens in CI secrets, not in the repository.
- Pin the builder version for repeatability when needed.
- Use a fixed project and region in CI.
- Avoid interactive prompts with
--yesonly after config validation. - Use
--detachwhen the pipeline should hand off deployment monitoring to Hubfly. - Check the project build history after deployment.
- Keep production env vars controlled outside the pipeline when they are sensitive.
A CI pipeline should not silently create a new production service every run unless that is intentional. Use bound container behavior for normal redeploys.
Local deploy vs Git deploy
Hubfly supports both local CLI deploys and Git-based deploys.
| Use CLI deploy when | Use Git deploy when |
|---|---|
| You want to deploy the current local workspace | You want Hubfly to build from a repository branch |
| You need quick manual iteration | You want branch/push-based deployment flow |
| Your build context includes local generated output | You want reproducible remote builds from source |
| You are testing a change before formal CI | You want build logs and retry behavior tied to Git |
| You prefer local builder control | You want the dashboard to own the build pipeline |
A common team pattern is to use CLI deploys for development and Git deploys or image deploy hooks for production.
CLI builds in project history
CLI deploys appear in the project build history as CLI-originated builds.
Operational notes:
- CLI builds are marked as local image upload deployments.
- The builder version can appear in the build details.
- Uploaded images are tracked as Hubfly-owned project images.
- CLI-originated builds may not keep the same remote builder logs as Git builds because the build happened on your machine.
- Re-running the CLI deploy normally targets the bound container from the config.
This gives teams visibility into deploys without pretending local builds are the same as remote Git builds.
Create A Tunnel
HubTunnels are the CLI path for private access to containers.
Use tunnels when the service should stay internal and you only need temporary local access for a database, admin panel, private API, or debugging endpoint.
Common commands:
hubfly tunnel create --project <project_id>
hubfly tunnel create --project <project_id> --container <container_id> --port 5432 --local 5432
hubfly tunnel create --project <project_id> --container <container_id> --port 8080 --local 3000
Database example:
hubfly tunnel create --project <project_id> --container <postgres_container_id> --port 5432 --local 15432
psql -h localhost -p 15432 -U postgres postgres
Private HTTP example:
hubfly tunnel create --project <project_id> --container <admin_container_id> --port 8080 --local 8080
Then open:
http://localhost:8080
List And Stop Tunnels
hubfly tunnel list
hubfly tunnel stop <tunnel_id>
Tunnels are temporary and should be stopped after the maintenance or debugging session is complete.
See HubTunnels for the full private access model.
Security best practices
Follow these practices when using the CLI:
- Treat CLI tokens like production credentials.
- Do not commit tokens,
.envfiles, or private tunnel keys. - Use least-privilege project access for team members running CLI deploys.
- Review
hubfly.build.jsonbefore using--yesin automation. - Keep production secrets in controlled secret storage.
- Prefer HubTunnels over public endpoints for databases and admin tools.
- Stop tunnels when you finish using them.
- Pin builder versions when deterministic deploys matter.
- Avoid deploying from a dirty local tree unless you deliberately want local-only changes in the image.
Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
hubfly login cannot complete | Browser callback or local auth flow did not finish | Retry login and copy the token manually if needed |
| Unauthorized API error | CLI token is missing, revoked, or not loaded | Re-run hubfly login and verify account context |
| Missing project error | Config does not include projectId or the project was deleted | Select the project again or update hubfly.build.json |
| Insufficient permissions | User lacks create/update permissions for the project | Ask the project owner for the required role |
| Bound container not found | The stored container ID no longer exists in the project | Clear or refresh the binding and deploy again |
| Unsupported deployment tier | Config has an invalid tier/resources shape | Use shared or dedicated settings supported by Hubfly |
| Upload fails | Network issue or regional upload endpoint unreachable | Retry, check connectivity, and verify region availability |
| Invalid upload token | Upload callback does not match the deploy session | Start a new deploy session by rerunning hubfly deploy |
| Build succeeds but app fails | Runtime command, port, env vars, or dependencies are wrong | Check container logs and runtime config |
| Local tunnel port is busy | Another process uses the local port | Choose a different local port |
| Tunnel connects but service refuses | Target service is not listening on the target port | Check container process, port, and logs |
Production checklist
Before using the CLI for production deploys, verify:
hubfly.build.jsonis reviewed and reproducible.- The target project and region are correct.
- The bound container behavior is intentional.
- Runtime resources match expected load.
- The exposed port is correct.
- Persistent paths use volumes.
- Secrets are not committed.
- CI uses a secure CLI token.
- Public services have domains, SSL, and Firewall where needed.
- Private services use HubTunnels instead of public ports.
- Build/deployment history is monitored after deploy.
FAQ
Does hubfly deploy build remotely or locally?
The CLI deploy flow builds on your machine with the Hubfly Builder, uploads the resulting image to the selected region, and then Hubfly deploys that image.
Do CLI deploys show in Hubfly?
Yes. CLI deploys appear in project build history as CLI/local image upload deployments, and uploaded images are tracked as project images.
Should I commit hubfly.build.json?
Commit it when it represents shared deployment intent. Do not commit secrets or machine-specific temporary values.
What happens on the second CLI deploy?
The CLI uses the bound container stored in the config so the deploy replaces the same logical service instead of creating duplicates.
Can I use the CLI in CI?
Yes. Use non-interactive flags such as --project, --region, --config, and --yes, and store the CLI token in CI secrets.
Should I use CLI deploy or Git deploy for production?
Use CLI deploy when local builds are part of your workflow. Use Git deploy when production should build from repository state. Many teams use CLI for development and Git or image deploy hooks for production.
Can the CLI access private databases?
Yes, through HubTunnels. Create a tunnel to the database container and connect using a local client against localhost:<local_port>.