Tag Archives: node.js

Deploying Node.js to production

Node.js community has not yet defined any standard or a good practice for deploying applications. And dealing with production caos can be a total pain in the butt. Fortunately after searching a lot over the web, I found some consensus and tips for deploying a Node.js app to production.

  • Express
  • If you typically use Express like me, you can set up the configs for your deployment modes (development, production, etc) in the main file. The below config is simple but easily extensible for supporting your needs. Here I just set the exception verbosity and an initializer for the MongoDB connection which can differ between the deployment modes:

    app.configure('development', function () {
      app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
      mongo.connect('development',logger); // mongodb initialization
    });
    
    app.configure('production', function () {
      app.use(express.errorHandler());
      mongo.connect('production',logger); // mongodb initialization
    });
    
  • Uncaughts Exceptions
  • A Node.js app (without forking or cluster facilities) runs on a single process. An uncaught exception can totally tear your instance down, stopping your service from responding to client’s requests. One way for surpassing this issue is to listen to ‘uncaughtException’, log the error and gracefully shutdown the process.

    process.on('uncaughtException', function (err) {
      console.error('uncaughtException:', err.message)
      console.error(err.stack)
      process.exit(1)})
    
  • Process Manager
  • However, even with this safety measure, your service is offline and doesn’t respond to any requests. First of all, you can daemonize your app by using Linux Upstart so the node process could run in background (forget about screen multiplexing or leaving the terminal open all day!).

    On Debian systems (Ubuntu, etc) run this for installing Upstart:

    $ sudo apt-get install upstart
    

    Ok good, now create a new file (/etc/init/nodeapp.conf) for configuring your new daemon. I borrowed this config and made some little changes:

    #/etc/init/myapp.conf
    description "Node App"
    author "me"
     
    start on startup # it's possible to use "net-device-up IFACE=eth0" for starting the process when the ethernet adapter is up
    stop on shutdown
    
    script
            cd /home/me/nodeapp
            exec sudo -u ubuntu NODE_ENV=production /usr/bin/node /home/me/nodeapp/app.js >> /home/me/nodeapp/log/app.log 2>&1
    end script
    

    In this simple config I teel Upstart to auto-start the process on boot and log output to a specific log file. Upstart also gives you some basics commands for managing the daemon:

    $ start nodeapp
    $ stop nodeapp
    
  • Monit
  • Having your app daemonized doesn’t save yourself from waking up at 3am because of some crashing activity (uncaught exceptions, network timeouts, etc). The rescue tool is Monit. Monit is a awesome utility which monitor and manage processes, files, directories, networking connections on Unix systems. Under the hood it just runs tests in certain intervals and proactively takes some action based on configured rules.

    On Debian systems (Ubuntu, etc) run this for installing Monit:

    $ sudo apt-get install monit
    

    Open “/etc/monit/monitrc” and uncomment the “set httpd” to be able to monitor on localhost:

    set httpd port 2812
        use address localhost  # only accept connection from localhost
    

    This test rule will check if the node and mongodb processes responds to HTTP requests:

     check host nodeapp with address 127.0.0.1
               start "/sbin/start nodeapp"
               stop "/sbin/stop nodeapp"
               if failed port 3004 protocol HTTP
                        request /
                        with timeout 5 seconds
                        then restart
                        if 5 restarts within 5 cycles then timeout
               if failed port 28017 protocol HTTP
                        request /
                        with timeout 5 seconds
                        then exec "/sbin/start mongodb"
    

    The DSL is pretty self-explanatory. For the node process running on 3004, the test will check if HTTP requests are failing, wait 5 seconds, restart the process, and if after 5 restarts the instance still doesn’t respond, it will call timeout. On the other side, for the mongo instance running on 28107, the test will checks if HTTP requests are failing, wait 5 seconds, and start a fresh mongodb process.

    Wait! don’t forget to restart monit:

    $ sudo service monit restart
    

    Monit has lots of configurations for dealing with every possible situation. I recommend searching over the web or just checking their website.

    For managing a Apache web server:

    check process apache with pidfile /var/run/apache2.pid
        start program = "/etc/init.d/apache2 start" with timeout 20 seconds
        stop program  = "/etc/init.d/apache2 stop"
        if totalcpu > 20% for 2 cycles then alert
        if totalcpu > 20% for 5 cycles then restart
    

    Alert the sysadmin by mail is something goes wrong:

    set mailserver localhost
    set alert sysadmin@domain.com
    
       set mail-format {
           from:xxxx@gmail.com
         subject: monit alert --  $EVENT $SERVICE
         message: $EVENT Service $SERVICE
                       Date:        $DATE
                       Action:      $ACTION
                       Host:        $HOST
                       Description: $DESCRIPTION
      }
    

    Finally use this command (or the web GUI) for checking the actual monitoring status:

    $ sudo monit status
    The Monit daemon 5.3.2 uptime: 2h 7m 
    
    Remote Host 'nodeapp'
      status                            Online with all services
      monitoring status                 Monitored
      port response time                0.000s to 127.0.0.1:28017/ [HTTP via TCP]
      port response time                0.001s to 127.0.0.1:3004/ [HTTP via TCP]
      data collected                    Fri, 26 Sep 2013 19:31:00
    
    System 'system_Server'
      status                            Running
      monitoring status                 Monitored
      load average                      [0.01] [0.02] [0.05]
      cpu                               0.1%us 0.2%sy 0.1%wa
      memory usage                      791252 kB [19.5%]
      swap usage                        0 kB [0.0%]
      data collected                    Fri, 26 Sep 2013 19:31:00
    
  • Git
  • Finally the deployment process per-se.

    Set your development environment by editing “~/.ssh/config”:

    Host nodeapp
    Hostname nodeapp-server.com
    
    IdentityFile ~/.ssh/mykey.pem
    User me
    

    Next create a bare (empty) git repo on the server:

    $ mkdir nodeapp.git
    $ cd nodeapp.git
    $ git init --bare
    

    And a git hook in “~/nodeapp.git/hooks/post-receive” for automatically restarting your node process with the deployed modifications:

    #!/bin/sh
     
    GIT_WORK_TREE=/home/me/nodeapp git checkout -f
     
    echo "Restarting node process..."
    sudo restart nodeapp
    
    

    Back in your development machine, add the remote repo to your local setup:

    $ git remote add origin ssh://nodeapp/home/me/nodeapp.git
    

    And finally push the code!

    $ git push origin nodeapp
    

    In this post I only presented some tools and tricks for deploying to production without fear. Eventually you will need to setup a reverse proxy as Nginx in front of your processes for load balancing between them or just for serving static assets and error pages. I will talk about Nginx in a future post. Good hacking!

    Advertisements
    Tagged , , , ,

    How debug Node.js applications using Eclipse

    eclipse-node

    In this post I’ll help understand how can debugging a Node.js application from scrach.

    Requirements

    You need installed in you computer the following tolls:

    • Java
    • Eclipse
    • Node.js (make sure that you have access a node command in your command line tool)

    Create a Simple Node.JS application

    First, we’ll install express.

    npm install -g express

    Note: The -g flag means that you are installing express globally on your system.

    So, now we are available for create a node.js application using express.

    express -c stylus express-app-sample

    Note: The -c states that we want to use stylus for css.

    The next step, is install the app dependencies. So, we need enter express-app-sample folder and install. We can do that with the following commands:

    cd express-app-sample
    npm install
    

    And now we’re available for running our app. What we need to do is the following command.

    node app.js

    You should see Express server listening on port 3000 and if you open http://localhost:3000 you’ll see the default Express page.

    Debugging Node.js application using Eclipse

    Install Eclipse debugger plugin for V8

    With Eclipse debugger plugin for V8 we can easy used for debugging node applications. This is the steps to install the plugin on Eclipse:

    1. Select the menu item Help > Install New Software…
    2. Click on Add… button.
    3. In the textbox labeled Name: enter Google Chrome Developer Tools. In the textbox labeled Location: enter http://chromedevtools.googlecode.com/svn/update/dev/. Click OK.
    4. Select Google Chrome Developer Toolshttp://chromedevtools.googlecode.com/svn/update/dev/ from the combo box Work with.
    5. Click the checkbox next to Google Chrome Developer Tools in the table. And Click the button labeled Next >.
    6. Accept the terms of the license agreement and click the button labeled Finish.
    7. Eclipse will restart with the V8 Eclipse Debugging Plugin installed.

    Debug node.js application

    1. Using node.js command line, we’ll launch our app on debug mode, using the following command:
      node --debug=5858 app.js
      
    2. In the Menu, choose Window > Open Perspective > Other, then select Debug from the list and click OK, to ensure we are viewing the debug perspective.
    3. Click the drop box button next to the green bug one and select “Debug Configurations …” option.
      debug-configurations
    4. Start the debugging by clicking “Debug” button. If everything goes well, we’ll get something like this:
      node.js-debug
    5. So, we just need to put breakpoints on the project that appears when we start debugging, in the Project Explorer, to debug.

    NOTE: You can find out more about debugging node.js applications using Eclipse in this link.

    Tagged , , ,

    NPM and the Node ecosystem

    After one month of hacking around with Node.js, I created and distributed my first package. NPM is the repository of all kind packages that you can think of. At this moment, there are 28 698 packages in NPM which is a lot for a 4 years old project. The philosophy of Node and its community is to keep the core tiny and encourage composition with small modules that do one thing well.
    In that sense, I wrote a small facebook API client that I called tiny-facebook-wrapper, as you can see in the figure. The package.json and .npmignore are two important files to have in any Node.js package. In a nutshell, the first one is the descriptor of your package with the author, version, dependencies, etc. The second one is used for keeping off things that you don’t want to share in your package, such as, docs, tests(?) or other superfluous files. Don’t forget to document your package in a README file with some hands-on examples of how developers can use your software, they will thank you from the bottom of their hearts.

    Now that I have my module ready to share, I can create a dev account in the NPM registry directly from the command line:


    $ npm adduser
    $ Username: davidcunha
    $ Password: ********
    $ Email: davidgoncalvescunha@gmail.com

    Publish the module:

    $ npm publish

    And that’s all folks, my small facebook API client is online for the community to use it:

    Simple, right?

    Tagged , , , ,

    Node.js logger: winston

    Winston is a fancy and flexible logging library developed by the guys from Nodejistu. It is totally decoupled allowing an easy extension and customization for any Node.js project.
    In a configuration file I created a simple data structure log with the different levels of logging and respective colorization. Afterwards it is trivial to instantiate my own logger adding the so call “multi transport” supported by Winston which enables different storage devices (console, file, mail, etc). Finally I set the logging levels/colors previously defined, and I’m ready to go!
    As aforementioned, Winston is highly flexible and supports many tweaks which are all thoroughly detailed in github.

    var log = {
        'logger' : {
          'levels': {
            'detail': 0,
            'trace': 1,
            'debug': 2,
            'enter': 3,
            'info': 4,
            'warn': 5,
            'error': 6
          },
          'colors': {
            'detail': 'grey',
            'trace': 'white',
            'debug': 'blue',
            'enter': 'inverse',
            'info': 'green',
            'warn': 'yellow',
            'error': 'red'
          },
        }
      };
    
      function getLogger() {
        var logger = new (winston.Logger)({
          'transports': [
          new (winston.transports.Console)(
          {
            'level': 'enter',
            'colorize': true
          }),
          new (winston.transports.File)(
          {
            'filename': 'logging-file.log'
          })]
        });
    
        logger.setLevels(log.logger.levels);
        winston.addColors(log.logger.colors);
    
        return logger;
      }
    
    Tagged , , , ,