hubfly build and hubfly.build.json
The hubfly build commands let you inspect and control the build plan used byhubfly deploy. The config file is optional, but keeping it in your repository makes the selected source, commands, resources, ports and runtime behavior reviewable and repeatable.
Build config is separate from Compose config
hubfly.build.json describes one deployable container. UseComposeSpec orhubfly stack when you are deploying multiple services.What Build Commands Do
| Command | What it does | Writes the config? |
|---|---|---|
hubfly build init | Creates a version-2 config with safe defaults, or normalizes the existing file. | Yes |
hubfly build validate | Resolves the effective Dockerfile or builder plan and reports warnings. | Yes, after normalization or inspection |
hubfly build edit | Normalizes the file and opens it with $EDITOR. | Yes, before opening the editor |
hubfly build explain | Shows what the builder detected, including runtime, framework, commands and port. | No, unless normalization is needed to load the file |
All four commands accept --config <path>. The value can be the path to a JSON file or a project directory; a directory resolves tohubfly.build.json inside it.
hubfly build init
Create a config for the current project, optionally selecting Dockerfile mode.
terminal
| Flag | Meaning |
|---|---|
--config <path> | Config file or project directory. |
--dockerfile <path> | Sets build.mode to dockerfile and records the path. |
--force | Replace the current config with defaults. Review the file first; this removes its current values. |
--print | Print the resulting JSON instead of the short summary. |
hubfly build validate
Validation loads or creates the config, applies defaults, resolves the build source, and checks the Dockerfile or the downloaded hubfly-builder. It does not deploy an image.
terminal
| Flag | Meaning |
|---|---|
--config <path> | Config file or project directory. |
--dockerfile <path> | Use Dockerfile mode for this validation without first editing the file. |
--builder-version <tag> | Pin the builder release used for auto/manual inspection. |
--json | Print machine-readable output containing config, builderVersion, dockerfilePath, buildSource, buildSourcePath and warnings. |
hubfly build edit
This command opens the normalized config in the editor named by EDITOR. For example:
terminal
The editor must be configured
EDITOR is empty or its executable cannot be found, the command fails. Set it in your shell or CI environment before using build edit.hubfly build explain
Explain is the fastest way to answer “what will Hubfly space build from this directory?” In Dockerfile mode it prints the resolved Dockerfile. Otherwise it runs the builder inspection and reports the detected runtime, framework, version, working directory, context directory, exposed port, build arguments and the number of configured build secrets.
terminal
With --json, auto mode returns builderVersion and aninspect object. Dockerfile mode returns mode,dockerfile and config. Secret values are not printed.
hubfly.build.json Structure
The current schema version is 2. This is a complete representative file; omit optional properties you do not need. The CLI fills defaults for omitted values.
{
"version": 2,
"project": {
"id": "proj_123",
"name": "my-api",
"region": "rw-kigali-1"
},
"container": {
"id": "cnt_123",
"name": "my-api"
},
"build": {
"mode": "auto",
"dockerfilePath": "deploy/Dockerfile",
"workingDir": ".",
"contextDir": ".",
"runtime": "node",
"framework": "next",
"version": "22",
"installCommand": "npm ci",
"setupCommands": ["npm run db:generate"],
"buildCommand": "npm run build",
"postBuildCommands": [],
"runCommand": "npm run start",
"runtimeInitCommand": "",
"exposePort": "3000"
},
"deploy": {
"tier": "dedicated",
"resources": { "cpu": 1, "ram": 800, "storage": 1 },
"runtime": { "autoSleep": false, "autoScale": false, "is24x7": true },
"networkPrimaryAlias": "api",
"networkAliases": ["backend"],
"ports": [
{ "container": 3000, "protocol": "HTTP" }
],
"volumes": [
{ "name": "postgres-data", "mountPath": "/var/lib/postgresql/data" }
],
"process": {
"command": ["npm", "run", "start"],
"entrypoint": [],
"workingDir": "/app"
},
"healthcheck": {
"test": ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"],
"interval": "30s",
"timeout": "5s",
"startPeriod": "20s",
"retries": 3
},
"restartPolicy": { "name": "unless-stopped" },
"labels": { "app": "my-api" }
},
"env": [
{ "name": "NODE_ENV", "value": "production", "scope": "runtime" },
{ "name": "NPM_TOKEN", "value": "secret", "secret": true, "scope": "build" }
],
"remove": {
"environmentKeys": [],
"portIds": [],
"volumeIds": []
},
"metadata": {
"builderVersion": "v1.7.1",
"lastBuildId": "build_123",
"lastImageTag": "build_123-20260819T120000Z",
"lastImageDisplay": "registry.example/my-api:build_123",
"lastDeployedAt": "2026-08-19T12:00:00Z"
}
}Build Fields
| Field | Values / example | Purpose |
|---|---|---|
mode | auto, manual, dockerfile | Choose builder detection, explicit commands, or a Dockerfile. |
dockerfilePath | Dockerfile | Dockerfile path relative to the build context. |
workingDir | apps/api | Application/root directory for monorepos. |
contextDir | . | Directory sent as the build context. |
runtime | node, bun, python, go, java, php, static | Runtime used by manual or detected builds. |
framework | next, fastapi | Optional framework hint or detected framework. |
version | 22, 3.12 | Runtime version requested by the builder. |
installCommand | npm ci | Dependency installation command. |
setupCommands | array of strings | Commands run before the main build. |
buildCommand | npm run build | Compilation or asset build command. |
postBuildCommands | array of strings | Commands run after the build completes. |
runCommand | node dist/server.js | Default application process command. |
runtimeInitCommand | shell command | Optional initialization command at runtime. |
exposePort | 3000 | Port detected or advertised by the builder. Published ports belong under deploy.ports. |
Deploy Fields
| Section / field | Meaning |
|---|---|
tier | shared fixes the shared runtime limits and enables sleep. Any other value normalizes to dedicated. |
resources.cpu | Requested vCPU capacity. |
resources.ram | Requested RAM in MB. |
resources.storage | Ephemeral container disk in GB; persistent volumes are separate. |
resources.maxCpu, maxRam | Upper bounds for vertical auto-scaling. |
runtime.autoSleep | Allow the service to sleep while idle. It is mutually exclusive with auto-scale and 24/7 mode. |
runtime.autoScale | Enable vertical auto-scaling; the CLI sets 24/7 mode and defaults autoScaleMode to vertical. |
runtime.is24x7 | Keep a dedicated service always on. |
networkPrimaryAlias, networkAliases | Private project-network names other services can use. |
ports | Published container ports with container, protocol, and optional host mapping. |
volumes | Named persistent volumes and their in-container mountPath. |
process | Optional command, entrypoint and working directory overrides. |
healthcheck | Docker-style test, interval, timeout, start period and retry count. |
restartPolicy | Restart behavior, with an optional maximum retry count. |
labels | String key/value metadata attached to the deployment. |
Environment and Metadata
Each env entry has name, value, optionalsecret, optional scope, and optional from. Scope isruntime by default; use build for build-only values orboth when the same value is needed in both phases. Mark credentials assecret: true and do not print them in CI logs.
project.id, container.id, and the metadata fields are normally maintained by the CLI after a successful binding or deploy. Review them, but avoid hand-editing generated IDs and image metadata. The remove lists are used by the deploy diff when you intentionally remove existing environment keys, ports or volume mounts.
Recommended Workflow
terminal
- Run
initonce and inspect the generated defaults. - Use
explainto verify detection before changing commands manually. - Commit the config when you want reviewable, repeatable deploy behavior.
- Run
validate --jsonin CI as a preflight check. - Use
hubfly deploy --yesonly after reviewing the deploy diff; add--detachwhen the job should return after upload.
Migrating an old config
hubfly config migrate --config ./hubfly.build.json; the CLI creates a timestamped.v1.<timestamp>.bak backup before writing version 2.