Node.js how to set server environment PORT and NODE_ENV? - node.js

How do I set the server environment to a certain port?
For instance,
const app = require('express')()
const isProd = (process.env.NODE_ENV === 'production')
const port = process.env.PORT || 3000
I will always get false for isProd and 3000 for port
I don't see the usefulness of these two lines and I can just set them below manually:
app.get('/', function (req, res) {
const data = {message: 'Hello World!'}
return res.status(200).json(data);
})
app.listen(3000, function () {
console.log('listening on port 3030!')
})
Do I need some config file in my root?
Any ideas?
I am using Linux/ Ubuntu/ Kubuntu.

Try running your server using below command
set NODE_ENV=production && set PORT=7000 && node server.js
Or for Linux
NODE_ENV=production PORT=7000 node server.js
This will set environment and port for your Node server.

Depends a bit on where you're hosting (e.g. windows or *nix) and how you're running your app (as a Windows or Linux service, using pm2, using systemd, etc).
The simplest way is to just change the command line call you start your app with, eg (linux):
NODE_ENV=prod PORT=34567 node myapp.js
or Windows
set NODE_ENV=prod && set PORT=34567 && node myapp.js
If you're using systemd or pm2 (and you should be), then they each have config files that allow you to set those variables for the environment the server is running in.
Pm2 docs: http://pm2.keymetrics.io/docs/usage/application-declaration/
Locally, you can just set defaults in your environment through normal means (in *nix that means exporting them in your shell config)

Related

Say 'Hello World!' in Openshift with Node.js

I created an app in Openshift and created a local git repo on my computer. I want to change the default welcome page here: http://nodejs-j4nos.rhcloud.com:3000 and just tell Hello world as this tutorial say.
So I removed from local repo the index.html, and modified server.js, pasted in this code below. And commit, and push. I get a long approval, that they accepted my commit.
If I good understand I do not have to stop node and start it again, but Openshift do it for me. But as you can see no Hello World is able to see, when open link in browser (http://nodejs-j4nos.rhcloud.com:3000) why?
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
remote: Git Post-Receive Result: success
remote: Activation status: success
remote: Deployment completed with status: success
To ssh://5556b4c4fcf9336abf0000de#nodejs-j4nos.rhcloud.com/~/git/nodejs.git/
and here is the tree structure, express is listed
Based on this SO answer I tried to modify script, but does not helped:
var express = require('express');
var app = express();
app.set('port', process.env.OPENSHIFT_NODEJS_PORT || 8080);
app.set('ip', process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1');
http.createServer(app).listen(app.get('port'), app.get('ip'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
app.get('/', function (req, res) {
res.send('Hello World!');
});
Link is working now: http://nodejs-j4nos.rhcloud.com The right script to show "Hello world!" is
var http = require('http');
var express = require('express');
var app = express();
app.set('port', process.env.OPENSHIFT_NODEJS_PORT || 8080);
app.set('ip', process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1');
http.createServer(app).listen(app.get('port'), app.get('ip'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
app.get('/', function (req, res) {
res.send('Hello World!');
});
And here is the proof:
Thanks for this: Deployed Node app to OpenShift successfully, OpenShift still shows default page
and this question: Node.js Deployment in openshift
And you should now that you can write in /app-root/repo the $ node server.js command, and if something wrong with script, it will indicate right there
I´ve readed this, maybe you must use a port over 15000:
https://help.openshift.com/hc/en-us/articles/202185874-I-can-t-bind-to-a-port
Found my notes on using OpenShift with Node:
The openshift system has some integrated control tools to support its ‘gear’ system, useful to control the openshift
application and environment.
gear control your application (start, stop, restart, etc)
or deps with --cart (gear start --cart mysql-5.1)
tail_all tail all log files. This command displays the last entries
in your log files as they are written. You can hit
<ctrl>-c to exit this command.
export list available environment variables
rm remove files / directories
ls list files / directories
ps list running applications
kill kill running applications
mysql interactive MySQL shell
mongo interactive MongoDB shell
psql interactive PostgreSQL shell
quota list disk usage
The gear system has additional commands. OpenShift Gear Control, An assortment of gear utilities:
COMMANDS:
build Run the build steps
deploy Run the deploy steps
help Display global or [command] help documentation.
postreceive Run the git postreceive steps
prereceive Run the git prereceive steps
reload Reload a cart
remotedeploy Run the remotedeploy steps
restart Restart a cart
restore Restore an application
snapshot Snapshot an application
start Start the gear/cart
status Get the status for a cart
stop Stop the gear/cart
Will any of this stuff help you stop and restart the gear? I'd start with the simple 'gear' command. I don't remember, is Express loaded up via NPM or now native with node? At one time it was a NPM install. Those don't get pushed to Openshift.
What is the directory tree structure on the openshift nodejs server?
root
\ app-root
\ data
\ repo <- - the working files for web content end up here.
\ runtime
\ git
\ nodejs
In openshift dependencies don't get pushed. For that you can login thru ssh and go to:
cd app-root/repo or cd $OPENSHIFT_REPO_DIR and then npm install tool_of_choice

Best way to set a Node/Express app to live or production mode

I'm currently in the process of making my node/express app into a production deployment, and as part of this, I need to make it run in a production friendly mode (e.g. fewer debugs to stdOut, write logs to different places, tell users less when errors occur etc.).
I'm struggling a bit with this, as whenever I set a variable of virtually any kind to invoke a 'production' mode, it doesn't take affect for the program as it runs.
When launched in dev mode, my code runs through Gulp, and runs this script:
#!/usr/bin/env node
var debug = require('debug')('ascema');
var app = require('../app');
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
Which, as you know, is just the generated launch script from the express generator.
In order to run it in live mode, I created an alternative startup for the server to use (I could hardly use gulp anyway) and live.js runs this:
#!/usr/bin/env node
var app = require('./app.js');
app.set('env', 'production');
console.log('running on Port 3000');
var server = app.listen(3000);
But, when I use app.get('env') anywhere in the app (e.g. in app.js or in it's various dependencies) it still returns 'development' and so none of my production tasks happen.
What am I doing wrong here?
Many thanks.
You have to set the NODE_ENV variable on the command line when you execute your NodeJS application.
For example:
NODE_ENV=production node app.js
Also, NODE_ENV is an environment variable so if set it in the environment on your server, you will not need to provide it every time you execute your application so node app.js will do.
You can set your environment variables in the /etc/environment file. Here are more details on that.
By using NPM you might to be used the follow scripts in the package.json:
"scripts": {
"start": "nodemon ./bin/www",
"dev_win": "set NODE_ENV=development && node ./bin/www >> /romba/log/api.log 2>> /romba/log/error.log",
"prod_win": "set NODE_ENV=production && node ./bin/www >> /romba/log/api.log 2>> /romba/log/error.log"
"prod_nix": "NODE_ENV=production node ./bin/www >> /romba/log/api.log 2>> /romba/log/_error.log"
},...
To start one of the script use the command:
npm run-script prod_win
In the JavaScript code I check the condition:
process.env.NODE_ENV.indexOf('production') > -1
or with Express.js
app.use((err, req, res, next) => {
req.app.get('env') === 'development' ? ...

How do I make Openshift to use Express 4, instead of its installed Express 3?

I developed my Nodejs Express app locally using Express 4 and it works as expected on my computer. I then git the whole app up to Openshift. When I try to run it Openshift returns"503 Service Unavailable". If I ssh into my base Node cartridge and do "express -V" it returns version 3.2.5. I get the same version 3.2.5 if I go into my app folder at app-root/repo and run "express -V".
So clearly my Express 4 which was included in the git upload in my app's node_modules is not being used. What is the solution to use Express 4 as required by my app?
Ideas are- remove Openshift's version of Express 3, force Openshift to use my Express 4 in my app area, upgrade Openshift's Express 3 to Express 4. I cannot figure out how to do any of those and I have researched this.
Here's how to troubleshoot:
ssh into your cartridge
cd into the app-root/repo directory
run grep version ./node_modules/express/package.json
you should see a version based on your package.json dependency
verify your package.json has a scripts section containing a start command that just runs your app with something like node ./server.js (server.js being whatever file you coded your main app start script in). You don't need the express command line program to launch an express server. It's for setting up new project boilerplate and other ancillary tasks.
To see the version of express running within your app, you can add this code to your server.js (or equivalent) file: console.log(require("express/package").version);
Look at this project to know how to integrate openshift with express4
Its a simple example .
https://github.com/master-atul/openshift-express4
try this
rhc ssh
cd app-root/repo
npm start
also edit the ./bin/www
var port = normalizePort(process.env.OPENSHIFT_NODEJS_PORT || '8080');
var ip = process.env.OPENSHIFT_NODEJS_IP;
if (typeof ip === "undefined") {
// Log errors on OpenShift but continue w/ 127.0.0.1 - this
// allows us to run/test the app locally.
console.warn('No OPENSHIFT_NODEJS_IP var, using 127.0.0.1');
ip = "127.0.0.1";
};
//app.set('ip', port);
app.set('port', port);
var server = http.createServer(app);
server.listen(port, ip);
server.on('error', onError);
server.on('listening', onListening);
you can follow step:
copy all content bin/www and replace all content in file server.js:
Change some content at server.js:
from
`var port = normalizePort(process.env.PORT || '3000');`
to
var port = normalizePort(process.env.OPENSHIFT_NODEJS_PORT || '3000');
Add line:
var ip = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1';
from
server.listen(port);
to
server.listen(port, ip);
Add more to package.json
from
"scripts": {
"start": "node bin/www"
},
to
"scripts": {
"start": "node server.js"
},
Add line:
"main": "server.js",
Use npm install --save module-name for npm install
create file .gitignore with content:
node_modules
on local run node server.js to start server with address localhost:3000
upload to openshift:
git add .
git commit -m "First update new server version"
git push
Browser: domain-appname.rhcloud.com

Can't get NODE_ENV to stick on my MEAN stack on open shift

I have:
added export NODE_ENV=production to app-root/data/.bashprofile (and echo $NODE_ENV shows production)
Tried rhc set-env NODE_ENV=production -a myapp which generates Setting environment variable(s) ... Server returned an unexpected error code: 501
Created an .openshift/action_hooks directory in my local repo and added the line export NODE_ENV=production to both a start and a pre_start file, committed and pushed to openshift
Tried the .openshift/action_hooks/pre_start_* aswell
Declared a root variable (as tipsed by #JuJoDi below) in the beginning of my server.js file, now it looks lite this:
var express = require('express'),
routes = require('./routes'),
api = require('./routes/api'),
http = require('http'),
path = require('path'),
everyauth = require('everyauth'),
connect = require('connect'),
env = process.env.NODE_ENV ? process.env.NODE_ENV : "process.env.NODE_ENV is null";
I'm then printing out using this route:
app.get('/version', function(req,res){
res.json({
"app.get('env')" : app.get('env'),
"process.env.NODE_ENV" : process.env.NODE_ENV,
"Global env" : env
});
});
What happens is that app.get('env') always returns 'development' and process.env.NODE_ENV is not printed at all (null value)
Has anyone got any ideas why this isn't working?
UPDATE
I created a minimalistic node server, still can't get any env-variables to work on open shift:
var http = require('http');
var port = process.env.OPENSHIFT_NODEJS_PORT || 3000;
var ipaddress = process.env.OPENSHIFT_NODEJS_IP || process.env.OPENSHIFT_INTERNAL_IP || 'localhost';
var env = process.env.NODE_ENV
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('' + process.env.NODE_ENV + "|" + env);
}).listen(port, ipaddress);
I couldn't reproduce this issue. I think the 501 error response that you initially received is the cause of your problems.
You should be able to troubleshoot by running the following from within in your project source folder (add -a YOUR_APP_NAME to the end of each command to run elsewhere):
Check your current list of application tokens:
rhc env list
If you have something listed for NODE_ENV, then clear it:
rhc unset NODE_ENV
Set your NODE_ENV to "production":
rhc env set NODE_ENV="production"
Verify that the value has been set by reloading your server, by running rhc env list, or by connecting to your application over SSH to check the system environment directly:
rhc ssh
env | grep NODE_ENV
Running rhc help env provides a lot of good usage info as well. Depending on how they're written, some servers need to be reloaded in order to fetch the new content.
I think the easiest way to get up and running with MEANStack on OpenShift is to use Yeoman's Angular-fullstack generator. It should automatically configure your environment for you.
That closure does not have access to the process object. Above that try
var env = process.env.NODE_ENV;
then print it with
app.get('/version', function(req,res){
res.json({
"app.get('env')" : app.get('env'),
"process.env.NODE_ENV" : env
});
});
When you run the app, try this:
NODE_ENV=production npm start
Substitute npm start with whatever way you start your app (node server or whatever).
That's the way I change the environment, when I am working locally. Since I usually want it to be development.
Express.js will default app.get('env') to development if process.env.NODE_ENV isn't set.
Update:
Sorry, missed the OpenShift part :/
https://www.openshift.com/developers/openshift-environment-variables
Looks like the environment variables in OpenShift need to go in:
.openshift/action_hooks/build
Using export. Have you tried that?

How to set proccess.env in Node express app on heroku

I have a simple node with mongo (via mongojs) app that is developed locally and deployed on heroku. In my development environment, i want to use a local instance of mongo, while in production, I would like to use the instance heroku provides to me via "process.env.MONGOLAB_URI".
My current approach is that I would set the datavase url depending on the environment variable, but how do i actually go into production mode? Moreover, how can i configure this so that when i develop on my local machine its development mode, when i upload to heroku its production mode?
app.configure('production', function(){
// ...
databaseUrl = "mydb"; // the default
});
app.configure('development', function(){
// ...
databaseUrl = process.env.MONGOLAB_URI;
});
db = require("mongojs").connect(databaseUrl);
Set the NODE_ENV environment variable to "development" on your local environment, and set it to "production" on Heroku. https://devcenter.heroku.com/articles/nodejs#setting-node-env
You can also access your online database locally by starting your app by adding the following:
var mongoose = require( 'mongoose' );
var dbURI = 'mongodb://localhost/Loc8r';
if (process.env.NODE_ENV === 'production') {
dbURI= process.env.MONGOLAB_URI;
}
mongoose.connect(dbURI);
And starting your app with "NODE_ENV=production nodemon bin/www"

Resources