Deploy to Build Button
The Deploy to Build button lets anyone deploy a running copy of your app to Build with one click, with no dashboard setup. It’s a good fit for open-source projects, starter templates, and any README where visitors should be able to try the app rather than just read about it.
The button follows Heroku’s Button conventions. If your project already has a Heroku button, see Moving a Heroku button to Build.
Before you start
Section titled “Before you start”- A GitHub repository. Build deploys the repository’s default branch. Visitors need a Build account with GitHub connected, and their GitHub account must be able to read the repository, so for an open-source project the repository must be public.
- An
app.jsonat the repository root, with abuildpacksarray. See Writing app.json. - A Procfile that declares how to run the app, plus a
releaseprocess if the app needs database migrations. See Running migrations.
Adding the button to your README
Section titled “Adding the button to your README”In Markdown:
[](https://app.build.io/deploy?template=https://github.com/your-username/your-repo)In HTML:
<a href="https://app.build.io/deploy?template=https://github.com/your-username/your-repo"> <img src="https://build.io/deploy-to-build-button.svg" alt="Deploy to Build"></a>Replace your-username/your-repo with your repository. The button image is 128×32 px, so no width is needed.
Always include template. Without it, Build tries to detect the repository from the GitHub page the visitor came from, but that only works if they’re already signed in to Build.
URL parameters
Section titled “URL parameters”The deploy endpoint, https://app.build.io/deploy, accepts these query parameters:
| Parameter | Description | Example |
|---|---|---|
template | The GitHub repository to deploy. Accepts a full URL, a github.com/... path, or owner/repo. | template=https://github.com/myorg/myapp |
app[name] | Suggested app name. Build appends a short random suffix to keep names unique, so the app is named something like my-app-a1b2c3d4. Defaults to the repository name. | app[name]=my-app |
app[region] | The region to deploy into. | app[region]=us-east-1 |
env[NAME] | Sets a config var on the new app. Repeat the parameter for each variable. | env[GREETING]=Hello&env[LOG_LEVEL]=info |
express | true skips the confirmation page and deploys immediately into the visitor’s personal team. | express=true |
A complete example:
https://app.build.io/deploy?template=https://github.com/myorg/myapp&app[name]=myapp&app[region]=us-east-1&env[NODE_ENV]=productionBuild always deploys the default branch, even when the button is clicked on another branch’s page or template points at one. There’s currently no way to deploy a specific branch or tag.
Anything you put in the URL is visible to everyone who reads your README, so never put real secrets in env[...]. See Config vars and secrets.
Writing app.json
Section titled “Writing app.json”Build reads app.json from the root of the default branch to set up the app. The file is required: a button deploy against a repository without one fails with a message asking you to add it.
A minimal app.json for a Rails app with a PostgreSQL database:
{ "name": "My Application", "description": "A sample application", "repository": "https://github.com/myorg/myapp", "addons": [ "schema-to-go:basic" ], "buildpacks": [ { "url": "heroku/ruby" } ]}buildpacks is required. Unlike a normal deploy, the button doesn’t detect a buildpack automatically, so list every buildpack the app needs, each with a url. See Buildpacks.
Supported fields
Section titled “Supported fields”Build follows Heroku’s app.json schema, with these differences:
| Field | On a button deploy |
|---|---|
buildpacks | Required. Each entry needs a url. |
formation | Applied. size must be a dyno size, e.g. standard-1x. |
stack | Applied. Defaults to heroku-24. |
name, description, keywords, website, repository, logo | Stored as app metadata. The app’s name comes from app[name] or the repository name, not from name. |
success_url | Stored but not used. After deploying, visitors land on the app’s new pipeline. |
env | Not applied. See Config vars and secrets. |
scripts | Stored but not executed, including postdeploy. See Running migrations. |
environments | Not used for the app the button deploys. |
Any other field is ignored.
Add-ons
Section titled “Add-ons”Build provisions an add-on only when both the service and the plan exist in Build’s catalog. Heroku add-on names such as heroku-postgresql aren’t in the catalog, and neither is a name without a plan, such as schema-to-go. Either one is skipped silently: the app deploys without the add-on and without an error.
Use the Build add-on for the service you need, with a plan from Add-on Services:
| Service | Heroku add-on | Build add-on | Smallest plan |
|---|---|---|---|
| PostgreSQL | heroku-postgresql | schema-to-go | schema-to-go:basic |
| Redis | heroku-redis | cache-to-go | cache-to-go:mini |
| MySQL / MariaDB | jawsdb, cleardb | ave-to-go | ave-to-go:basic |
| Elasticsearch / OpenSearch | bonsai, searchbox | spandex-to-go | spandex-to-go:dachs |
| Transactional email | mailgun, sendgrid | mailertogo | mailertogo:micro |
Each entry in addons can be a "service:plan" string or an object with a plan key, e.g. { "plan": "schema-to-go:basic" }.
Once provisioned, an add-on sets its connection config vars on the app, e.g. DATABASE_URL for schema-to-go. After your first test deploy, check the app’s Resources tab to confirm every add-on was created.
Config vars and secrets
Section titled “Config vars and secrets”The env block in app.json doesn’t reach the deployed app: the button replaces the app’s config vars after creating it from app.json. Only env[...] URL parameters and add-on config vars are set. Build also doesn’t prompt visitors for required values and doesn’t support Heroku’s "generator": "secret".
So:
-
Non-secret defaults: have the app fall back to a default when the variable is unset, or set them with
env[...]on the button URL. -
Secrets: don’t put them in the button URL. Generate a fallback at boot when the app can tolerate one, or tell visitors in your README to set the value after deploying:
bld config:set SECRET_KEY_BASE=$(openssl rand -hex 64) -a <app-name>
You can keep an env block in app.json to document the variables your app reads, as long as nothing depends on Build applying it.
Running migrations
Section titled “Running migrations”Build doesn’t run scripts.postdeploy. Run migrations in the release phase instead, by adding a release process to your Procfile:
release: bundle exec rails db:migrateweb: bundle exec puma -C config/puma.rbThe release command runs after every build, before the new version goes live, with the app’s config vars (including DATABASE_URL) available. If it fails, the deploy stops.
Heroku runs postdeploy once, but the release phase runs on every deploy. Anything you move over from postdeploy, such as seeding data, must be safe to run repeatedly.
Moving a Heroku button to Build
Section titled “Moving a Heroku button to Build”- Change the button URL. Replace
https://heroku.com/deploywithhttps://app.build.io/deployand the button image withhttps://build.io/deploy-to-build-button.svg. Thetemplate,app[...],env[...], andexpressparameters carry over unchanged. - Add
buildpackstoapp.jsonif it doesn’t have one. - Rename add-ons to their Build names, with a plan. See Add-ons.
- Replace
generator: "secret"andrequiredconfig vars, since Build applies neither. See Config vars and secrets. - Move
scripts.postdeployinto areleaseprocess in your Procfile. See Running migrations. - Test the button from your README and check the deployed app’s add-ons and config vars.
Before:
[](https://heroku.com/deploy?template=https://github.com/myorg/myapp)After:
[](https://app.build.io/deploy?template=https://github.com/myorg/myapp)What happens when someone clicks the button
Section titled “What happens when someone clicks the button”- The visitor must be signed in to Build with GitHub connected. If GitHub isn’t connected, Build sends them to the dashboard to connect it first.
- Unless
express=trueis set, a confirmation page lets the visitor change the app name, team, and region, and lists the config vars set byenv[...]. - Build creates a new pipeline and app, named from
app[name]plus a random suffix, and readsapp.jsonfrom the latest commit on the default branch. - Build provisions the add-ons, builds the app, runs the release phase, and starts the app.
- The visitor lands on the new pipeline, where they can follow the build and open the app.
