Download or set Heroku app config variables while running the app locally - node.js

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

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.

Related

create-react-app react-scripts start - ajv-errors: NOT SUPPORTED: option jsonPointers. Deprecated jsPropertySyntax can be used instead

Seeing this error after coming back to a project after a few weeks. Changed/updated nothing, everything was working fine last time I had this laptop open. The following error happens in a container when I'm running docker-compose up.
yarn run v1.22.17
client | $ react-scripts start
client | NOT SUPPORTED: option jsonPointers. Deprecated jsPropertySyntax can be used instead.
client | /app/node_modules/ajv-errors/index.js:4
client | if (!ajv._opts.allErrors) throw new Error('ajv-errors: Ajv option allErrors must be true');
client | ^
client |
client | TypeError: Cannot read properties of undefined (reading 'allErrors')
client | at module.exports (/app/node_modules/ajv-errors/index.js:4:18)
client | at Object.<anonymous> (/app/node_modules/webpack-dev-server/node_modules/schema-utils/src/validateOptions.js:22:1)
client | at Module._compile (node:internal/modules/cjs/loader:1103:14)
client | at Object.Module._extensions..js (node:internal/modules/cjs/loader:1155:10)
client | at Module.load (node:internal/modules/cjs/loader:981:32)
client | at Function.Module._load (node:internal/modules/cjs/loader:822:12)
client | at Module.require (node:internal/modules/cjs/loader:1005:19)
client | at require (node:internal/modules/cjs/helpers:102:18)
client | at Object.<anonymous> (/app/node_modules/webpack-dev-server/node_modules/schema-utils/src/index.js:7:25)
client | at Module._compile (node:internal/modules/cjs/loader:1103:14)
client | error Command failed with exit code 1.
client | info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
client exited with code 1
So posting my own question I changed how I was looking at the problem.
I came across this question/answer AJV and ajv-formats latest must be broken in React
I found the answer from #Tsar Bomba about installing
npm install ajv#7.2.3 ajv-errors#2.0.1 ajv-formats#2.1.1 --save
Worked for me and I was able to serve my project again
The following also worked for me.
npm install ajv#7.2.3 ajv-errors#2.0.1 ajv-formats#2.1.1 --save

PM2 crashes while using ES modules in nodejs

Ive enabled ES modules in pacakage.json with this key value pair "type": "module" i dont have to use the 'experimental' flag with the latest version of node
when i run pm2 start app.js --watch the app crashes with the error message
0|app | Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only file and data URLs are supported by the default ESM loader
0|app | at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:781:11)
0|app | at Loader.resolve (internal/modules/esm/loader.js:85:40)
0|app | at Loader.getModuleJob (internal/modules/esm/loader.js:229:28)
0|app | at Loader.import (internal/modules/esm/loader.js:164:28)
0|app | at importModuleDynamically (internal/modules/cjs/loader.js:1194:27)
0|app | at exports.importModuleDynamicallyCallback (internal/process/esm_loader.js:30:14)
0|app | at Object.<anonymous> (C:\Users\username\AppData\Roaming\npm\node_modules\pm2\lib\ProcessContainerFork.js:29:24)
0|app | at Module._compile (internal/modules/cjs/loader.js:1251:30)
0|app | at Object.Module._extensions..js (internal/modules/cjs/loader.js:1272:10)
0|app | at Module.load (internal/modules/cjs/loader.js:1100:32) {
0|app | code: 'ERR_UNSUPPORTED_ESM_URL_SCHEME'
0|app | }
the app works perfectly fine without pm2. im guessing pm2 does not support ESM yet!
any workarounds or am i missing some configurations?
Try to pass harmony as node arguments as it will enable es6 features in pm2 process.
pm2 start my_app.js --watch --node-args="--harmony"
If you are on windows 10
pm2 not working with esm on windows 10, there are no workarounds!

"Failed to load gRPC binary module" error when running a Sails.js application inside a Docker container

I have a local Docker developer environment to build a Sails.js application. This is what my Dockerfile looks like:
FROM node:8.12
LABEL Name=us.gcr.io/my-project/my-app Version=1.0.0
# Container configuration
RUN npm install -g sails#1.0.2 grunt#1.0.3 nodemon#1.18.4
WORKDIR /usr/src/app
COPY ./server/package.json ./package.json
RUN npm install
VOLUME /usr/src/app
EXPOSE 1337
This is what my docker-compose.yml file looks like:
version: '3.4'
services:
server:
image: us.gcr.io/my-project/my-app:latest
build: .
environment:
NODE_ENV: development
IS_DEV_MACHINE: "yes"
ports:
- 1338:1337 # HOST_PORT is 1339 to avoid conflicts with other Sails.js apps running on host
volumes:
- ./server:/usr/src/app
entrypoint: nodemon
mongodb:
image: mongo:4
ports:
- 27018:27017 # HOST_PORT is 27018 to avoid conflicts with other MongoDB databases running on host
volumes:
- ../database:/data/db
Normally, everything works fine however, I recently imported and initialised the #google-cloud/logging NPM package in my application and now, when I run docker-compose up, I get the following error:
server_1 | error: Bootstrap encountered an error: (see below)
server_1 | error: Failed to lift app: { Error: Failed to load gRPC binary module because it was not installed for the current system
server_1 | Expected directory: node-v57-linux-x64-musl
server_1 | Found: [node-v57-darwin-x64-unknown]
server_1 | This problem can often be fixed by running "npm rebuild" on the current system
server_1 | Original error: Cannot find module '/usr/src/app/node_modules/grpc/src/node/extension_binary/node-v57-linux-x64-musl/grpc_node.node'
server_1 | at Object.<anonymous> (/usr/src/app/node_modules/grpc/src/grpc_extension.js:53:17)
server_1 | at Module._compile (module.js:653:30)
server_1 | at Object.Module._extensions..js (module.js:664:10)
server_1 | at Module.load (module.js:566:32)
server_1 | at tryModuleLoad (module.js:506:12)
server_1 | at Function.Module._load (module.js:498:3)
server_1 | at Module.require (module.js:597:17)
server_1 | at require (internal/module.js:11:18)
server_1 | at Object.<anonymous> (/usr/src/app/node_modules/grpc/src/client_interceptors.js:145:12)
server_1 | at Module._compile (module.js:653:30)
server_1 | at Object.Module._extensions..js (module.js:664:10)
server_1 | at Module.load (module.js:566:32)
server_1 | at tryModuleLoad (module.js:506:12)
server_1 | at Function.Module._load (module.js:498:3)
server_1 | at Module.require (module.js:597:17)
server_1 | at require (internal/module.js:11:18) code: 'MODULE_NOT_FOUND' }
mongodb_1 | 2018-10-09T09:27:52.521+0000 I NETWORK [conn4] end connection 172.19.0.2:48730 (0 connections now open)
In the error above, "Bootstrap" is the bootstrap.js file in my Sails.js project that initialises #google-cloud/logging. This is how I am initialising the logger in bootstrap.js:
// Globally required packages
const { Logging } = require('#google-cloud/logging');
const logging = new Logging({ projectId: 'my-project' });
const logger = logging.log('test');
I just can't seem to figure out why this error is occurring. I even tried changing my base Docker image to the official Google App Engine Docker image (gcr.io/google-appengine/nodejs) and that did not help either. i can't find any solutions to this problem anywhere. Appreciate any help.
By any chance did you do a npm install on your local Mac (darwin) environment when it should have been done in the container (linux)? The grpc binary is for the wrong OS thus the error. This often happens with a local Mac running a linux Docker container.
Expected directory: node-v57-linux-x64-musl
Found: [node-v57-darwin-x64-unknown]
The solution would be to rm -fr node_modules and do npm install in the container.
Rebuild the app by the following command.
npm rebuild --target=8.1.0 --target_platform=linux --target_arch=x64 --target_libc=musl
It looks like the project is having difficulty finding dependencies such as the gRPC binary module (repaired with npm install grpc) or perhaps where they are currently located - more info here

Port in use when launching Node.js app with Heroku Foreman

I am trying to deploy my node.js app to heroku but when I try to launch it locally using foreman I am getting Error: listen EADDRINUSE. I have run a netstat and grepped for the port nothing else is using it and the server starts without issue when running directly as a node http server.
The app I am trying to deploy is using mongo and redis I am not sure if these components will effect the server starting with Foreman. Does anyone have any suggestions on areas I could look at for potential bugs?
foreman start
01:37:18 web.1 | started with pid 1835
01:37:18 web.1 | /usr/local/foreman/lib/foreman/process.rb:66: warning: Insecure world writable dir /usr/local in PATH, mode 040777
01:37:19 web.1 | events.js:72
01:37:19 web.1 | throw er; // Unhandled 'error' event
01:37:19 web.1 | ^
01:37:19 web.1 | Error: listen EADDRINUSE
01:37:19 web.1 | at errnoException (net.js:863:11)
01:37:19 web.1 | at Server._listen2 (net.js:1008:14)
01:37:19 web.1 | at listen (net.js:1030:10)
01:37:19 web.1 | at Server.listen (net.js:1096:5)
01:37:19 web.1 | at Function.app.listen (/Users/craig/Documents/Sandboxes /xxx/node_modules/express/lib/application.js:535:24)
01:37:19 web.1 | at Object.<anonymous> (/Users/craig/Documents/Sandboxes/xxx/web.js:25:5)
01:37:19 web.1 | at Module._compile (module.js:456:26)
01:37:19 web.1 | at Object.Module._extensions..js (module.js:474:10)
01:37:19 web.1 | at Module.load (module.js:356:32)
01:37:19 web.1 | at Function.Module._load (module.js:312:12)
01:37:19 web.1 | exited with code 8
01:37:19 system | sending SIGTERM to all processes
SIGTERM received
Thanks.
--Additional information--
The procfile just has one entry:
web: node web.js
and I have set the listener up as follows:
var port = process.env.PORT || 5000;
app.listen(port, function() {
console.log("Listening on " + port);
});
I just ran into this on OS X. It looks like foreman picks port 5000 by default, which seems to conflict with Bonjour/mDNS/UPNP services. (From what I've read. I haven't taken the time to pick out which it is.)
However, you can change the port that foreman uses in two ways: specify the port on the command line or create a .foreman file with the port number specified there.
Good luck and happy coding!
I had the same issue, Error: listen EADDRINUSE means that a Node server is already running.
Check that you are not running a Node server for the same project locally. If you are working on a GitHub synced project locally (on port 5000 for instance) which is tied to Heroku you cannot run a local Node server for that project as the port will be in use twice.
I was actually running a Node server on a project in a different Terminal window and didn't notice immediately.

Can't start foreman cos node.js complains about some obscure module it can't find

trying to get a project working on my debian vm but foreman refuses to start. the node.js error message is not very helpful cos it doesn't even tell me what module can't be found.
sissi#debian:/media/fancystuff$ foreman start
22:05:33 web.1 | started with pid 2949
22:05:33 web.1 |
22:05:33 web.1 | module.js:337
22:05:33 web.1 | throw new Error("Cannot find module '" + request + "'");
22:05:33 web.1 | ^
'2:05:33 web.1 | Error: Cannot find module '/media/fancystuff/web.js
22:05:33 web.1 | at Function._resolveFilename (module.js:337:11)
22:05:33 web.1 | at Function._load (module.js:279:25)
22:05:33 web.1 | at Array.0 (module.js:484:10)
22:05:33 web.1 | at EventEmitter._tickCallback (node.js:190:38)
22:05:33 web.1 | process terminated
22:05:33 system | sending SIGTERM to all processes
btw 1: the error message is the same no matter if web.js is there of if it's deleted....which just adds to my confusion.
btw 2: "foreman check" gives me "valid procfile detected (web)"
sigh.
From this line:
'2:05:33 web.1 | Error: Cannot find module '/media/fancystuff/web.js
it looks like there is a non-printing character at the end of the line in your Procfile where you call node web.js since the ' character that was put after module name string ended up at the beginning of the line.
Editing Procfile and making sure that that special character is gone, your problem will probably be solved. I could replicate this on my Debian dev. server by adding <32 characters at the end of the line after web.js before EOL.
Most probably the Procfile was coppied from different OS that append carriage return e.g \r\n that not compatible with foreman. Just remove the trailing spaces or character in the Procfile and rerun. Or the simplest is to remove the Procfile and create using same OS
Example Procfile:
web: node web.js
And start the apps:
ubuntu#yadayada:~/heroku/web$ foreman start

Resources