#Node - Running in Production
This gist is based on the excellent post by @hacksparrow which is found at http://www.hacksparrow.com/running-express-js-in-production-mode.html. The main principle is that you want the application to detect that it is running on a production server and to use the production configuration. The way to do this is to set the NODE_ENV=production
. To do this you need to do the following:
$ export NODE_ENV=production
But we have a little problem here. The NODE_ENV environment variable will be lost if the server restarts, so it is safer to put it in the .bash_profile file. That way the variable will set again every time the system reboots. You will find the file in your home directory. It's a hidden file, so you can't see it unless you do a ls -la. We will append the export command to the .bash_profile file.
$ echo export NODE_ENV=production >> ~/.bash_profile
$ source ~/.bash_profile
The source command is required to make the NODE_ENV variable available in your current shell. Your Express app is finally running in production mode. And that bring us to the question: what is the difference between development mode and production mode? In development mode, view templates are read from file for each request. In production mode, the views are cached, meaning your app will be much faster. But there is more to these modes than just caching.
In your app.js file, you might have noticed this:
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
You can configure your app to behave differently according to the mode it is running in. In the above example, errors will be made verbose if the app is running in development mode, but not so if it is running in production mode. Likewise, you can set variables, configure middlewares etc for different modes.
And mind you, the modes are not just limited to development and production. You can have any mode names - testing, staging, win7, lolwtfhaha ... and what not. Set the proper NODE_ENV value and configure your app accordingly and you have a very flexible environment specific app.
In case you want to set the same configuration for many modes, you can do it this way:
app.configure('production', 'staging', function(){
...
});
We have hard-coded NODE_ENV to the shell for the production environment, but that doesn't have to be for the development environment. While you are developing, it is essential that you can quickly switch to different modes for testing, benchmarking, using different settings, etc. - all without having to edit files and calling source. That's easy:
This will run your app in the mode named testing:
NODE_ENV=testing node app.js
This will run your app in the mode named staging:
NODE_ENV=staging node app.js
This will run your app in the mode named mongodb:
NODE_ENV=mongodb node app.js
This will run your app in the mode named redis:
NODE_ENV=redis node app.js
You get the idea. And the best part about this method of running the app is that the mode is temporary only. Once you stop the app, and run it again using node app.js or whatever conventional way is, the default mode will be used - most probably development.
You can access the current mode from your script using the process.env.NODE_ENV variable. You could potentially use it for setting different variables etc. for different modes. But use it only when it can't be done with app.configure().
Instead of:
if (process.env.NODE_ENV == 'production') db = require('mongoskin').db('localhost:37751/bands');
else db = require('mongoskin').db('localhost:27017/bands');
do this:
app.configure('development', function(){
db = require('mongoskin').db('localhost:27017/bands');
...
});
app.configure('production', function(){
db = require('mongoskin').db('localhost:37751/bands');
...
});
Wondering if you could set the value of process.env.NODE_ENV? Yes, you can, but DO NOT TOUCH IT! Your code should not tell itself what environment it is running in, doing so is playing with untraceable bugs and tons of headache. It should read the environment var and find out what the environment is.
Lastly, if you had been developing a website with sessions enabled, you will see this warning as you run your app in production mode for the first time:
Warning: connection.session() MemoryStore is not
designed for a production environment, as it will leak
memory, and obviously only work within a single process.
This is warning that the default session store MemoryStore is not a top notch one, you need to use something better - like RedisStore or MongoStore.