hoststack.yaml
Keep a service's build and start commands, port, health check, default environment variables and persistent disk in a file next to your code. HostStack reads it on every deploy, so a change to it ships like any other commit.
How it works
Put a hoststack.yaml (or hoststack.yml) in the directory your service builds from — the repository root, or the service's root directory if you set one. On every deploy, after the clone and before the build, HostStack looks for the file and applies what it declares to that deploy.
- What the file declares wins. A build, start or install command in the file replaces the one stored on the service, for this deploy.
- What the file leaves out is untouched. Anything you don't declare keeps the value from the dashboard, so you can add a file to a service you created in the UI and declare only the parts you want in Git.
- The file does not create anything. The service must already exist — create it in the dashboard, or with the CLI, SDK or Terraform. There is no reconciler that reads the file and creates missing services or databases.
The deploy log shows what was applied, one line per setting, starting with Detected hoststack.yaml — applying configuration.
Add the file to a service
Generate a starter file
In the directory the service builds from, run
hoststack init. It writes a commentedhoststack.yaml, and refuses to overwrite an existing one unless you pass--force.Declare what you want in Git
Name the entry under
servicesafter your service. Keep only the keys you want the file to own:hoststack.yamlservices: web: type: web_service install: command: bun install --frozen-lockfile build: command: bun run build start: command: bun run start port: 8080 healthCheck: path: /health interval: 30 timeout: 5 disk: name: data mountPath: /var/data sizeGB: 10 env: NODE_ENV: production LOG_LEVEL: infoCheck it
Run
hoststack validate. It needs no API key and makes no network call; it exits0when the file passes and1with a list of problems when it doesn't.Commit and push
The next deploy picks the file up. Open the deploy's build log to see each setting it applied.
Which service entry is used
A deploy applies exactly one entry: the one under services whose key equals the service's name in HostStack. If no key matches, it uses the first entry in the file. That makes a single-entry file work for any service built from the repo — and means a monorepo with several services should name each entry exactly after its service, or give each service its own root directory with its own file.
What a deploy applies
These keys under services.<name> change what a deploy does:
install.command stringReplaces the service's install command.
build.command stringReplaces the service's build command.
build.multistage booleanTurns the multi-stage image build on or off for Bun and Node services: install and build in one stage, then copy a pruned result into a lean runtime image. Ignored when the service builds from your own
Dockerfile.start.command stringReplaces the service's start command.
portnumberThe port your app listens on, 1–65535. It becomes
PORTinside the container and the port HostStack routes to and health-checks. Unlike the command overrides, it is also saved back to the service's settings, so scaling and wake-from-sleep use the same port. An invalid value is skipped with a warning in the log.healthCheck. path stringThe path the health check requests. The two keys below are only read when
pathis set.healthCheck. interval numberSeconds between checks while the service runs.
healthCheck. timeout numberSeconds a single check may take.
envmap of KEY: valueDefault environment variables. Variables set on the service (dashboard, CLI, API) win over the file for the same key, so the file can't override a value your team set on purpose — or a secret.
runtimestringUsed only when the service has no runtime set yet. Once a runtime is stored on the service, change it in the service's settings instead.
diskobjectA persistent disk:
name(lowercase letters, digits and hyphens),mountPath(absolute path) andsizeGB(whole GB, 1–100, default 1). It is mounted on this deploy and recorded on the service, where it shows up with its other volumes. If a volume already mounts at the same path, the file's disk takes its place. Adiskblock without bothnameandmountPathis skipped with a warning.
Keys a deploy does not apply
The schema accepts more keys than a deploy acts on. These are read by hoststack validate or kept for compatibility with other tools, but changing them in the file changes nothing on HostStack — set them on the service instead:
| Key | Where to set it instead |
|---|---|
| type | Chosen when the service is created. |
| plan | The service's size, in its settings in the dashboard. |
| scaling.min / scaling.max | Autoscaling, or hoststack services scale svc_... 1:4. |
| domains | Custom domains |
| branch, rootDirectory | The service's source settings. |
| databases | Create databases in the dashboard or with hoststack db create — see Databases. |
Writing the file
HostStack reads hoststack.yaml with a small parser that handles the subset of YAML the schema uses: nested keys by indentation, one scalar value per line, and - item lists. Keep to that and the file behaves the same in hoststack validate and in a deploy.
- One line per value. Block scalars (
|and>) and flow syntax ([a, b],{ a: 1 }) are not supported. Chain long commands with&&on one line. - Quote values that contain
#. A space followed by#starts a comment, and everything after it is dropped. - Quote numbers and booleans you mean as text — for example
VERSION: "1.10", which would otherwise be read as the number 1.1.
Validate in CI
Fail a pull request before it deploys by running the validator in your pipeline:
npm install -g @hoststack.dev/cli # Node 18 or later
hoststack validate # run in the directory that holds hoststack.yamlhoststack validate looks for hoststack.yaml or hoststack.yml in the current directory only. It checks:
typeis one ofweb_service,worker,cron_joborstatic_site.portis a positive number.scaling.minandscaling.maxare at least 1, andminis not greater thanmax.- Every entry under
databaseshas anengineofpostgresorredis.
It does not check the other keys, so a typo in a key name passes validation and is then ignored by the deploy. Read the deploy log after changing the file to confirm each setting was applied.
Troubleshooting
- The file seems to be ignored
Look for
Detected hoststack.yamlin the build log. If it's missing, the file isn't in the directory the service builds from — check the service's root directory. If it's there, the next line names the entry that was applied; if that's the wrong one, rename the entry to match the service's name.- A command ran as something odd
The command was probably written as a block scalar (
command: |). Put it on one line.- An env value didn't change
The same key is set on the service, and the service's value wins. Change or delete it there.
Next steps
Was this page helpful?