Environment Variables API with clinical:env


#1

Hi all,
I don’t usually announce individual packages when I publish them, but one came together last night that was particularly nice, and which I’ve been struggling with for the better part of the past two years: clinical:env.

It’s a package which basically swaps out Meteor.settings functionality with environment variables, which helps with creating 12 factor apps that can run between SaaS hosting providers, and is a mashup of all the best parts of the following packages:

pauldowman:dotenv
mrt:environment-hooks
mrt:allow-env
panphora:environment-template-helpers
jboulhous:dev

A big shout out to Mike Bannister, Tom Wijsman, Paul Dowman, David Miranda, Neil MacMunn, Jamal Boulhous, Gadi Cohen, and Arunoda. This package wouldn’t have happened without their work.

API includes:

  • Env.allow()
  • Env.isProduction
  • Env.isDevelopment
  • Env.isTraining
  • Env.isTesting
  • Env.isStaging
  • Isomorphisms across client and server
  • Template helpers

None of what’s in clinical:env is particularly new; but it’s now all in one place, in an expanded and unified API, and under a supported package (for those packages still in the mrt namespace).

Take it for a spin, and kick the tires. We’re still working out how NODE_ENV and METEOR_ENV should play together; and the template helpers were added last-minute. So, if there are any bugs, please let me know or submit a pull-request.

But otherwise, it seems to be working quite nicely on my apps; and I finally feel comfortable with what’s happening with environment variables.

Cheers,
Abigail


#2

Hi Abigail,

I can not really understood why someone will want to write down his complete settings in a ENV_VAR manner.

It is ok, if you are just transport a few settings but in case that Meteor.settings also could be filled in due to ENV_VAR there is no really addon for me in that package. Do I miss something? The only thing is missing by Meteor is a global Helper to access the Meteor.settings.public within a template.

I do not want to spam this with our packages but maybe you are interested in this:

https://atmospherejs.com/4commerce/pubsettings-template-helper

It is exactly for that above.

I am sure you know, that you also could fill the ENV for Meteor settings like that:

METEOR_SETTINGS="{ public: { isDevelopment: true, app: { name: 'Hello' } } }"

So with the above package you have full access to all values (also with hierachal objects) like

{{#if pubSettings.isDevelopment }}

{{ pubSettings.app.name }}

I am interested in what you think about that.

Cheers,
Tom


#3

Hi Tom,
Looks like you’ve been recently working on this general issue, too. :slight_smile:

The desire to put things in ENV_VARs is a dev/ops concern, related to encapsulation of the app, and portability between hosting platforms. A settings.json file works great if one has command line access to their server; or has post-deploy hooks ala Elastic Beanstalk. But if you’re using a SaaS provider such as Heroku or Modulus, then sometimes the only config options they provide are via environment variables.

Sure it’s possible to put everything in a long string in METEOR_SETTINGS; but sometimes we want to detect what the SaaS provider has configured (i.e. reporting the METEOR_URL, for example). So,if our cloud only gives us ENV_VARs to set, clinical:env lets us expose those vars throughout the app.

That being said, I think there would be a lot of value in getting the METEOR_SETTINGS variable integrated with the Env API. My initial thought would be to attach the Meteor.settings object to Env.settings. After which, I think most all of the pubsettings-template-helper package functionality could be included, if you’re interested.

Of course, if we do that, we then have a question of precedence… if NODE_ENV, METEOR_ENV, and METEOR_SETTINGS each report a different environment, what do we report to the client API and template helpers? Lets take a couple of examples:

Production Server
NODE_ENV: 'production’
METEOR_ENV: 'PRODUCTION’
METEOR_SETTINGS="{public:{isDevelopment: true}}"

Staging Server
NODE_ENV: 'development’
METEOR_ENV: 'production’
METEOR_SETTINGS="{public:{isDevelopment: false}}"

What’s the order of precedence? Should the template helpers on the production server show the isDevelopment blocks or not? How about the staging server that’s being brought up to be a new production server, but hasn’t hit production yet?

Thoughts?