Skip to content
homeport

Docs · Start

Build settings

Build settings change what detection chose: how the app is built, what the build makes, and how it runs. Every field starts empty, and an empty field means “use what was detected”, shown as the field’s placeholder. Most apps never change one.

Where they are

  • In the dashboard: the environment’s Settings tab, under How it builds. When you create an app they are under Build and output settings. Saving changes the next build; what is live keeps running until then.
  • For one app, every environment: build settings belong to the app, so every environment of it builds the same way. The health check path is the exception: each environment has its own.
  • From the CLI: homeport deploy takes --run, --release and --process for one deploy, and --save keeps them for every deploy after it. See the CLI.
  • In the repo: most of them can also go in an optional homeport.yaml.

Which one wins

A one-off deploy override wins, then the saved build settings, then homeport.yaml, then detection. The homeport.yaml reference has the same order. Three things work a little differently:

  • Processes and packages are replaced as a whole. If the build settings name any, homeport.yaml’s are ignored, not merged. While the build settings name none, the dashboard shows homeport.yaml’s under the field.
  • Octane and the start command: a start command you set wins over the Octane switch. The Octane switch wins over homeport.yaml’s run.
  • Redeploy with changes: on the environment’s page, this changes the start command, release command, processes and Octane. Use once applies them to that deploy alone. Save saves them as the build settings, and a field you empty there goes back to detection.

Every setting

Build settings
Dashboard fieldhomeport.yamlCLIEmpty means
Root directory——The repo root
What it isstatic—Detected: app or static site
Install——Detected
Build commandbuild.command—Detected
Binary / Output folderbuild.artifact, static—Detected
Runtimeruntime—Detected, else Node
Start commandrun--runDetected
Release commandrelease--releaseDetected, else none
Octane (Laravel)——On if the app requires laravel/octane
Processesprocesses--processhomeport.yaml’s, else none
Health check path——/
Packagespackages—homeport.yaml’s, else none

A static site shows only the first five: nothing of it runs, so it has no start command, release command, processes, health check or packages.

How it builds

Root directory

The app’s folder in the repository, for a repo with more than one app in it. Detection and homeport.yaml are read from this folder. The dashboard lists the folders that look like apps. A folder that another app of your team was already made from is shown but can’t be chosen: add an environment to that app instead.

What it is

App is a server that runs, and sleeps when idle. Static site is a folder of files served as they are. Choose the other one when detection guessed wrong. For an rsc-kit app, the build itself says which one it made, unless you choose here.

Choosing a kind that detection didn’t pick turns off homeport’s own packaging for JavaScript and PHP apps. The build is then your build alone, and its output is a file to run (server unless you set Binary) or a folder to serve (dist unless you set Output folder).

Install

Replaces the detected install step, like bun install --frozen-lockfile. It runs before the build command. Anything the build image needs first, such as Bun in a Node image, is still set up before it.

Build command

Replaces your app’s own build, like bun run build. It runs with sh, after the install step. For a JavaScript or PHP app, homeport still packages what your build leaves into the release afterwards. A build command needs a toolchain, so the app’s folder must have a package.json, go.mod or composer.json. For a stack homeport doesn’t detect, use build.image in homeport.yaml.

For a Laravel app, setting a build command turns off Inertia’s server-side rendering bundle and the caching of views and config that homeport does for you, because your build replaces homeport’s.

Binary or Output folder

For an app, Binary is the file the build makes, which runs as your app. For a static site, Output folder is the folder the build leaves the site in. Either is a path inside the app’s folder. Setting it turns off the fallback that looks for a site in build, dist or out, and an rsc-kit app’s own marker.

Runtime

For a JavaScript app: Node or Bun. Left on Detected, it is what the project says, read in the order on the detection page, else Node. It isn’t shown when the build compiles the server into a binary, which runs on the Bun it was compiled with.

How it runs

The start command, release command and processes are all arguments to your app’s binary, not commands for a shell. For Laravel the binary is FrankenPHP, so artisan is php-cli artisan …. The characters each may use are listed under run and release in the homeport.yaml reference, and each is at most 1,000 characters.

Start command

The arguments your binary starts with, like serve --port $PORT. Only $PORT and $HOST may be used. Empty, it is what was detected: for a JavaScript app, what its start script runs; for a PHP app, php-server --root public --listen :$PORT, or Octane when it is on.

Release command

Runs once against the new release before it takes traffic, typically database migrations. If it fails, the deploy stops and the previous release keeps serving. Write the arguments only: migrate up, not ./server migrate up. No variables, so no $, and no &&.

When neither the build settings nor homeport.yaml set one, homeport detects it:

Release commands homeport detects
If the app isThe release command
Laravelphp-cli artisan migrate --force
rsc-kit, with src/commands/migrate.ts (or .tsx, .js, .mjs, .mts)migrate
Node or Bun, with a migrate or db:migrate script in package.jsonWhat that script runs, as arguments to the runtime
Node or Bun, with Prisma’s prisma/migrations foldernode_modules/prisma/build/index.js migrate deploy
Anything elseNone
  • A script that runs prisma or drizzle-kit is run from its file under node_modules. The release ships dependencies only, so the tool must be in dependencies, not devDependencies.
  • A script that needs a shell (&&, a variable) can’t be a release command. homeport says why in the build’s warnings, and you set the release command yourself.
  • For a Laravel app, homeport also caches its views as part of the release command.
  • To have no release command where one would be detected, write release: none in homeport.yaml.

Octane

Laravel apps only. Detected serves the app through Laravel Octane, in FrankenPHP’s worker mode, when it requires laravel/octane. On needs laravel/octane in composer.json. Off serves it with php-server. A start command you set wins over this switch.

Processes

Up to 4 long-running commands beside the web, like a queue worker (php-cli artisan queue:work). Each has a name and its arguments to the binary. A name is lowercase letters and digits, starting with a letter, up to 15 characters, and not web or release. A process may use $PORT and $HOST, and gets a port of its own.

  • Each runs once, beside however many copies of the web are running, and is billed for its memory while it runs.
  • Memory and CPU are the process’s own. Empty, it runs at the app’s size. A process can’t be larger than any of the app’s environments: make the app bigger in Resources first.
  • Processes run only in an environment with at least 1 copy always running, which needs a paid plan. An environment that sleeps skips them at each deploy. See always on.

Health check path

A deploy goes live once the app answers this path with a status below 400. Empty, it is /. Set it to a path that answers without signing in, like /api/health. If the app doesn’t answer in time, the deploy is rolled back: see what your app must do.

It is a path on the app: it starts with /, has letters, digits and . _ - / only, no query, no .., and is at most 200 characters. Unlike the other settings, each environment has its own.

Size

An app’s memory and CPU are not build settings. They are set per environment in Settings → Resources, and saving restarts the app without a rebuild. See sizes. A process with no size of its own runs at the environment’s size.

Packages

Executables from homeport’s curated list, shipped inside each release and on your app’s PATH. Nothing is installed on a server: the release carries them. Each adds its size to every release.

Packages
PackageVersionWhat it isSizeLicence
lightpanda1.0.0Lightpanda, a headless browser for scraping and automation, driven over the Chrome DevTools ProtocolAbout 190 MBAGPL-3.0
  • Up to 8 packages, each named once.
  • Static sites can’t have packages: nothing of them runs.
  • Choosing any in the dashboard replaces the ones homeport.yaml names. While none is chosen, the dashboard shows homeport.yaml’s.

Start Lightpanda from your app and drive it over localhost, with puppeteer-core or Playwright:

homeport.yaml
packages:
  - lightpanda
lightpanda serve --host 127.0.0.1 --port 9222