Search code examples
node.jsherokuheroku-cli

Download or set Heroku app config variables while running the app locally


I have an app which I have downloaded from GitHub and after pushing it to Heroku it works perfectly fine. however when I use the heroku local command to run it locally it throws an error regarding configuration variables missing.

How can I download these config files to my local folder (do I even need to)? Do I need to create an .env file manually in order to make it work?

Here is the app:

const assert = require('assert');
const Provider = require('oidc-provider');

assert(process.env.HEROKU_APP_NAME, 'process.env.HEROKU_APP_NAME missing');
assert(process.env.PORT, 'process.env.PORT missing');
assert(process.env.SECURE_KEY, 'process.env.SECURE_KEY missing, run `heroku addons:create securekey`');
assert.equal(process.env.SECURE_KEY.split(',').length, 2, 'process.env.SECURE_KEY format invalid');

// new Provider instance with no extra configuration, will run in default, just needs the issuer
// identifier, uses data from runtime-dyno-metadata heroku here
const oidc = new Provider(`https://${process.env.HEROKU_APP_NAME}.herokuapp.com`, {
  clients: [
    {
      client_id: 'foo',
      redirect_uris: ['https://jwt.io'], // using jwt.io as redirect_uri to show the ID Token contents
      response_types: ['id_token'],
      grant_types: ['implicit'],
      token_endpoint_auth_method: 'none',
    },
  ],
  cookies: {
    keys: process.env.SECURE_KEY.split(','),
  },
});

// Heroku has a proxy in front that terminates ssl, you should trust the proxy.
oidc.proxy = true;

// listen on the heroku generated port
oidc.listen(process.env.PORT);

and here is the error I get when I run "heroku local":

3:44:57 AM web.1 |  assert.js:383
3:44:57 AM web.1 |      throw err;
3:44:57 AM web.1 |      ^
3:44:57 AM web.1 |  AssertionError [ERR_ASSERTION]: process.env.HEROKU_APP_NAME missing
3:44:57 AM web.1 |      at Object.<anonymous> (C:\Users\hmffa\Desktop\my-provider\src\index.js:4:1)
3:44:57 AM web.1 |      at Module._compile (internal/modules/cjs/loader.js:1063:30)
3:44:57 AM web.1 |      at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
3:44:57 AM web.1 |      at Module.load (internal/modules/cjs/loader.js:928:32)
3:44:57 AM web.1 |      at Function.Module._load (internal/modules/cjs/loader.js:769:14)
3:44:57 AM web.1 |      at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
3:44:57 AM web.1 |      at internal/main/run_main_module.js:17:47 {
3:44:57 AM web.1 |    generatedMessage: false,
3:44:57 AM web.1 |    code: 'ERR_ASSERTION',
3:44:57 AM web.1 |    actual: undefined,
3:44:57 AM web.1 |    expected: true,
3:44:57 AM web.1 |    operator: '=='
3:44:57 AM web.1 |  }
[DONE] Killing all processes with signal  SIGINT
3:44:57 AM web.1 Exited with exit code null

Solution

  • These variables often vary between environments. Some things, like your database connection string and security keys, should be different locally and in production.

    However, Heroku documents an easy way to copy a config var from Heroku to a local .env file:

    Sometimes you may want to use the same config var in both local and Heroku environments. For each config var that you want to add to your .env file, use the following command:

    heroku config:get CONFIG-VAR-NAME -s  >> .env
    

    Do not commit the .env file to source control. It should only be used for local configuration. Update your .gitignore file to exclude the .env file.

    Note that .env files aren't magic. Node.js won't use the values in there out of the box.

    If you use heroku local to run your app locally (as you appear to be) you should find that your .env file gets used. If you run it another way, you may need to do additional work, e.g. perhaps by adding dotenv.