Building your Node.js app for a local, staging and production pipeline in Heroku.
Getting your first production ready web app setup on Heroku can be a little confusing. This article highlights a way to setup your initial environments so that you can maintain a production version of your app hosted on Heroku and also build separate hosted and local testing environments that can be shared safely with a team.
What is a pipeline?
A pipeline can be thought of as the workflow for your app. Creating places that exist for development/staging and testing, without impacting the current production. It creates a path for versions of the app from development to production.
What does a good production and development environment look like?
What I am aiming for is the ability for team members to each manage their own local dev for personal testing and to also be able to share a hosted team dev/staging environment that can mimic the same details as the app being hosted on production, without impacting your users or your production business data. To do this I created a team owned pipeline rather than a personal owned pipeline and called it “Exist”, based on the brand of my production app.
The idea is coding an app that is variable independent and can be moved quickly between environments as it’s being developed. This means that while the apps environments(domains) will change at each stage of it’s workflow, its coded in a manner that makes it easy to work in each environment and on success pass it quickly to it’s next environment without having to constantly change parameters the app needs to alter in order to work correctly in each environment (or worse, forget to change the parameters).
What does that look like?
The following diagram shows a map for how this might be achieved using a Heroku Pipeline with a node.js app
Production App: The final product that has as close to 100% uptime for users as possible. This is where your domain is parked, and the version of the app that points at your production databases, facebook connections and other production dependencies as it’s own web stack separate from your development and staging environments.
Local Dev: Where each developer can fetch/download a working copy of the app to a folder on their personal machines and make code changes to improve upon it in their own local environment before pushing it to staging for testing.
Heroku Staging App: A shared environment that mimics the hosted production environment on Heroku.com where testing can occur in the cloud without impacting the production database. Note: Because the staging area needs a different URL than production, some custom application variables are going to need special attention, such as the callback url that the Facebook Login API discussed below.
Heroku’s Config Variables vs. ‘dotenv’ and local dev variables
As an app’s environment changes, so do the url’s it depends on as a domain name. This has to be taken into consideration when working with separate environments and coding for each of them in the same unified app. A prime example of this beyond connecting to your database is the Facebook Login app, which is created at developer.facebook.com.
If you want to use Facebook to manage user signups and login, the api has a critical need to register the calling application’s url within the connecting Facebook Login app for very real security reasons. This presents quite the issue if you want to build an app that can be tested locally at http://localhost:port, in your staging environment on heroku in the pipeline at http://blindsiding-features-9999.herokuapp.com or in production at http://myshinyproductionapp.com
Fortunately Heroku solves this business critical problem by providing an app feature called “Config Variables” that is unique to each hosted app’s settings and found under the settings menu for each app as a button labeled “reveal config vars’ found in each environment’s app settings.
To make my app successful with using a Heroku pipeline for streamlining push/pulls and testing in each environment as seamless as possible, I went through the process of creating 3 separate facebook developer apps, and 3 separate mongoDB’s; one of each per each of my 3 intended environments(domains: localhost:3000, heroku staging, heroku production). For my local app, I simply store the variables such as my local dev mongo db, local dev app id, key, and facebook call url as app variables in my dotenv(.env) file. For each app environment on facebook, I have replicated these same named variables to be configured to values unique to those environments.