4. Configuration
Every application needs configuration—database credentials, API keys, feature flags, and environment-specific settings. Build keeps configuration separate from your code, so you can deploy the same codebase to different environments without changes.
This section covers how to manage your app's configuration through environment variables, app settings, and best practices for keeping secrets secure.
4.1 Environment variables (config vars)
Config vars are the primary way to configure your Build applications. They're exposed to your app as environment variables at runtime, keeping sensitive data out of your codebase and making it easy to change settings without redeploying.
How Config Vars Work
When your app starts, Build injects all config vars into the environment. Your code reads them like any other environment variable.
Ruby:
database_url = ENV['DATABASE_URL']
Node.js:
const apiKey = process.env.API_KEY;
Python:
import os
stripe_key = os.environ.get('STRIPE_SECRET_KEY')
Config vars are available to all process types (web, worker, etc.) and persist across deploys and restarts.
Setting Config Vars
From the dashboard, navigate to your app's Settings tab and find the Config Vars section. Click "Reveal Environment" to view existing values, then add or edit as needed.
From the CLI:
$ bld config:set STRIPE_KEY=sk_live_xxx123 -a my-app
You can set multiple variables at once:
$ bld config:set API_URL=https://api.example.com RETRY_COUNT=3 -a my-app
To view your current configuration:
$ bld config:list -a my-app
To remove a variable:
$ bld config:unset OLD_API_KEY -a my-app
When Config Vars Change
Updating a config var triggers a restart of your app's dynos. The new values take effect immediately—no redeploy required. Keep this in mind if you're updating multiple related variables; consider setting them all in a single command to avoid multiple restarts.
4.2 App settings
Beyond config vars, your app has several settings that control how Build deploys and runs it. You'll find these in your app's Settings tab in the dashboard.
Stack
The stack determines how your app is built. For most apps, leave this set to the default, which uses Cloud Native Buildpack, kept up-to-date with the latest security patches. If your app includes a Dockerfile and you want to use it instead, set the stack to "dockerfile".
Buildpacks
Buildpacks transform your source code into a runnable application, typically you would add buildpacks that match the tech stack of your application. You can add multiple buildpacks for apps that need them (for example, a Ruby app that also needs Node.js for asset compilation). The order matters—buildpacks run in sequence, and each can make executables available to subsequent ones.
Region
Your app's region determines where your dynos run. Choose a region close to your users or your database for the best performance. Once set, the region can be changed, but there are implications of doing so, so be sure to pick the most suitable one from the start.
App Policies
Several policies control your app's runtime behaviour and security. You'll find these in the Policies section of your app's Settings tab.
Allow WebSockets — Enable or disable WebSocket connections for your app.
Provision Temporary Certificates — Generates self-signed certificates before your ACM (Automated Certificate Management) certificate is issued. This is helpful when setting up a new deployment, as it gives your app a working HTTPS endpoint while you wait for your domain's DNS to resolve and the real certificate to be provisioned.
Response Timeout — How long a request can take before Build terminates it. Increase this for apps that handle long-running requests, but keep in mind that long timeouts tie up dyno resources.
Web Application Firewall (WAF) — Enables a built-in firewall that transparently proxies all incoming traffic at near line-speed. The WAF uses the OWASP Core Rule Set to block common web attacks like SQL injection and cross-site scripting. Note that WAF cannot inspect traffic if TLS Passthrough is enabled.
TLS Passthrough — Allows your app to handle SSL/TLS termination directly, rather than having Build terminate it at the routing layer. Use this if your app requires custom certificate validation or a service that needs to perform its own TLS termination. Be aware that enabling this disables WAF and other HTTP-level inspection, since the routing layer can no longer read the traffic.
Share Process Namespace — Shares the process namespace across containers on the same dyno. This allows Build's built-in process manager to aggressively clean up orphaned processes that their parent process left behind.
Erosion Resistance — Sets a time limit after which a process is automatically restarted, regardless of whether it has encountered errors. This acts as a safeguard against memory leaks and other gradual degradation that can make a process unresponsive over time.
Build Cache — Caches the results of previous builds to speed up subsequent ones. Particularly useful for projects with large dependency trees or slow compilation steps. If you run into build issues caused by stale cache, you can disable this temporarily to force a clean build.
4.3 Secrets management
Config vars are the right place for secrets like API keys, database passwords, and encryption keys. Build encrypts config vars at rest and in transit, and they're never exposed in build logs or your app's source code.
Keeping Secrets Out of Your Code
Never commit secrets to your repository, even in private repos. Use config vars instead. If you accidentally commit a secret, rotate it immediately—Git history is permanent, and the secret should be considered compromised.
For local development, use a .env file and add it to your .gitignore. Tools like dotenv (available for most languages) load these values into your environment during development, mimicking how config vars work in production.
Rotating Secrets
Periodically rotating secrets limits the damage if one is ever exposed. For credentials you control (like your own API keys), update the config var with the new value:
$ bld config:set API_KEY=new_key_value -a my-app
Your app restarts with the new value. For external services, check if they support multiple active keys simultaneously—this allows you to add the new key, deploy, verify it works, then revoke the old one without downtime.
