Deep-dive on the Next Gen Platform. Join the Webinar!

Skip Navigation
Show nav
Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • Documentation
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Visit the Heroku Blog

    Find news and updates from Heroku in the blog.

    Visit Blog
  • Log inorSign up
Hide categories

Categories

  • Heroku Architecture
    • Compute (Dynos)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
  • Developer Tools
    • Command Line
    • Heroku VS Code Extension
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery & Integration (Heroku Flow)
    • Continuous Integration
  • Language Support
    • Node.js
      • Working with Node.js
      • Troubleshooting Node.js Apps
      • Node.js Behavior in Heroku
    • Ruby
      • Rails Support
      • Working with Bundler
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Background Jobs in Python
      • Python Behavior in Heroku
      • Working with Django
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Working with Maven
      • Working with Spring Boot
      • Troubleshooting Java Apps
    • PHP
      • PHP Behavior in Heroku
      • Working with PHP
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Getting Started
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
      • Migrating to Heroku Postgres
    • Heroku Key-Value Store
    • Apache Kafka on Heroku
    • Other Data Stores
  • AI
    • Working with AI
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
      • Single Sign-on (SSO)
    • Private Spaces
      • Infrastructure Networking
    • Compliance
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Teams
    • Heroku Connect (Salesforce sync)
      • Heroku Connect Administration
      • Heroku Connect Reference
      • Heroku Connect Troubleshooting
  • Patterns & Best Practices
  • Extending Heroku
    • Platform API
    • App Webhooks
    • Heroku Labs
    • Building Add-ons
      • Add-on Development Tasks
      • Add-on APIs
      • Add-on Guidelines & Requirements
    • Building CLI Plugins
    • Developing Buildpacks
    • Dev Center
  • Accounts & Billing
  • Troubleshooting & Support
  • Integrating with Salesforce
  • Continuous Delivery & Integration (Heroku Flow)
  • Managing Multiple Environments for an App

Managing Multiple Environments for an App

English — 日本語に切り替える

Last updated August 06, 2020

Table of Contents

  • Creating and linking environments
  • Managing staging and production configurations
  • Advanced: Linking local branches to remote apps

Your Heroku app runs in at least two environments:

  • On your local machine (i.e., development).
  • Deployed to the Heroku platform (i.e., production)

Ideally, your app should run in two additional environments:

  • Test, for running the app’s test suite safely in isolation
  • Staging, for running a new build of the app in a production-like setting before promoting it

You can help prevent buggy code from being deployed to production by maintaining these separate environments as different Heroku apps, and by using each environment only for its intended purpose.

This strategy is particularly important because Heroku’s Linux stacks likely differ from your development machine’s operating system. This means you can’t be sure that the code that works in your local development environment will work exactly the same way in production.

Heroku provides helpful tools (namely pipelines, Heroku CI, and review apps) for creating and maintaining your app’s staging and test environments.

Creating and linking environments

Creating a staging environment

Let’s say you have an application running on your local (development) machine and you’re ready to push it to Heroku. You can create a new Heroku app to represent your staging environment with the Heroku CLI:

$ heroku create --remote staging
Creating strong-river-216.... done
http://strong-river-216.heroku.com/ | https://git.heroku.com/strong-river-216.git
Git remote staging added

By default, the Heroku CLI adds a Git remote named heroku to your repo. The command above uses the --remote flag to specify a different name for the remote (in this case, staging). Therefore, you use the following command to push your code to your app’s new staging environment:

$ git push staging master
...
$ heroku ps --remote staging
=== web: `bundle exec puma -C config/puma.rb``
web.1: up for 21s

Creating a production environment

Once your staging app is up and running properly, you can create your production environment and push to it with the same commands:

$ heroku create --remote production
Creating fierce-ice-327.... done
http://fierce-ice-327.heroku.com/ | https://git.heroku.com/fierce-ice-327.git
Git remote production added
$ git push production master
...
$ heroku ps --remote production
=== web: `bundle exec puma -C config/puma.rb``
web.1: up for 16s

You will need to do some work to keep these apps in sync as you continue to develop them. You’ll need to add contributors, config vars, buildpacks, and add-ons to each individually, for instance.

You now have the same codebase running as two separate Heroku apps, one for staging and one for production.

Specifying an environment with the Heroku CLI

When a Git repo has more than one associated Heroku remote, the Heroku CLI’s commands require you to specify which app you’re interacting with by including the -r (or --remote) option. To simplify your workflow, you can edit your Git config to indicate a default Heroku remote.

For example, you can make staging your default Heroku remote with the following command:

$ git config heroku.remote staging

This adds the following section to your project’s .git/config file:

[heroku]
  remote = staging

After you make this change, all Heroku CLI commands you run from your repo will default to managing your staging app. To run a command against your production app, simply include -r production in the command.

Linking environments with pipelines

Heroku pipelines make it easy to link your app’s environments and promote code from staging to production.

Create a new pipeline from the Heroku Dashboard and add your staging and production environments to it by following these steps.

Managing staging and production configurations

Many languages and frameworks support flipping a development/production switch. For example, when in development mode, you may use a different database, have increased logging levels, and send all emails to yourself instead of to end users.

You should use RAILS_ENV=production or RACK_ENV=production for your staging applications to minimize surprises while deploying to production. Read Deploying to a custom Rails environment for more information.

The services and libraries that your application uses may also need their own configuration variables set, mirroring those on production. For example, you may use a different S3 bucket for staging than you do on production, so you will use different values for the keys:

$ heroku config:set S3_KEY=XXX --remote staging
$ heroku config:set S3_SECRET=YYY --remote staging

Advanced: Linking local branches to remote apps

It’s simple to type git push staging master and git push production master when you’ve followed the steps above. Many developers like to take advantage of git’s branches to separate in-progress and production-ready code, however. In this sort of setup, you might deploy to production from your master branch, merging in changes from a development branch once they’ve been reviewed on the staging app. With this setup, pushing is a littler trickier:

$ git push staging development:master

This command tells git that you want to push from your local development branch to the master branch of your staging remote. (It might look a little disorderly, but there’s a lot more going on - take a look at the git book for a very in-depth exploration of refspecs.)

If you want to simplify your git commands, you can make things easier by forcing your local git branches to track your remote applications. Assuming you’ve got git remotes for staging and production, you can do the following:

If you want to set push.default for all git repositories (instead of just this one), add --global to the command.

$ git config push.default tracking
$ git checkout -b staging --track staging/master
Branch staging set up to track remote branch master from staging.
Switched to a new branch 'staging'

Now, you’re in the staging branch and you’re set up so that git pull and git push will work against your staging environment without any further arguments. Change some code, commit it, and push it up:

$ git commit -a -m "changed code"
$ git push
Counting objects: 11, done.
...

Notice that you said git push, not git push staging staging:master. The push.default setting is what makes this possible; with that set to tracking, your local branches will automatically push changes to the remote repositories that they track.

If you’d like your local master branch to point to your production remote (and you’re running git 1.7 or later), you can do the following:

$ git fetch production
$ git branch --set-upstream master production/master

And with that, git push from master will update your production app on Heroku.

Keep reading

  • Continuous Delivery & Integration (Heroku Flow)

Feedback

Log in to submit feedback.

Releases Pipelines

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2025 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices