I am Hack Sparrow
Captain of the Internets.

Running Express.js in Production Mode

How to run Express.js in production mode

So you have become a Node.js developer and have ever since started churning out kickass Express.js apps by the dozens. But you have a little secret - you still can't figure how to run your Express.js app in production mode. All your apps run in development mode:

Express server listening on port 3000 in development mode

How do you run Express in production mode? Do I need to edit a config file or something? Do I need to set some variables in app.js? What is the difference between development and production mode? Can someone tell me what to do?! This post will answer all these question and more.

I am gonna show you how to run your app in production mode. But be warned that should you run your app in production mode in any environment other than production, you are inviting 20 days and 21 nights of unfathomable pain.

Considering the current state of Node.js and Windows, I will assume your production server is a Linux. You 'mark' the server as production environment by creating an environment variable named NODE_ENV, and setting it to 'production'.

$ export NODE_ENV=production

That's it. Now when you run your app, it will be running in production mode.

Express server listening on port 3000 in production mode

And don't you dare think I have bad programming grammar looking at missing spaces before and after =. Deviate from what I showed, and you have something which spells F-A-I-L. That just how Bash rolls.

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.

Don't panic. All it is saying is that the default session store MemoryStore is not a top notch one, you need to use something better - like RedisStore or MongoStore. These two popular sessions stores are very well documented and easy to use. I personally prefer RedisStore.

So that brings us to the end of this post. I am sure you learnt not only how to run Express.js in production mode, but a lot more than that. Any comments, opinions, questions? I'll be available in the comments as usual. Node and Express FTW!

12 Responses to “Running Express.js in Production Mode”

  1. Captain says:

    I would recommend against setting the value of `process.env.NODE_ENV in the code`.

  2. Carlos Rene says:

    Thanks for the post!

Make a Comment