Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Provide Node.JS webapp "key in hand"

I am building a simple Node.JS application for a client. The webapp should be easy to deploy on each server instance (which are RedHat EL 6.3), "key in hand".

What is the best way to package a Node.JS app? Basically, I need an "installer" or "package" to:

  • Install Node.JS
  • Install the dependencies (npm install)
  • Populate the application files (CSS, JS, HTML, etc.)
like image 273
Randomblue Avatar asked Dec 29 '12 17:12

Randomblue


1 Answers

You should deliver a self-contained package. Please check out the great site The Twelve-Factor App, specifically the build, release, run section. There is a lot of hard-won wisdom from experienced operations engineers embodied in that site.

  • In your app's repo, write a script (shell, node, whatever) that can generate a distributable archive
  • RPM or tar archive are the 2 most sensible choices for you. tar is more portable and simpler. RPM would integrate nicely with an RPM-based distribution. I would recommend starting with tar if you have not done a lot of software packaging/management work. RPM is significantly more complex than tar.
  • The tar archive should embed the node.js files within it. This will make your app easy to install and avoid sharing a system-wide node install thus creating artificial coupling. If you go the RPM route, you can specify node as a dependency in your RPM spec file (but you probably shouldn't - see below).
  • The archive should embed all of the npm dependencies as well. Don't run npm install at package install time. Consider using the npm shrinkwrap tool to manage your dependencies during development, but at deployment time they should be pre-bundled and ready to run.

Specifically, these are bad ideas you should avoid:

  • Do not download anything from the Internet during installation. This is brittle, slow, and potentially can throw you bad surprises including security problems
  • Do not build artifacts at install time that can be built at build time. So ship pre-build CSS files, requirejs optimized files, pre-compiled binaries, etc.

As to whether your application RPM should list node.js as a dependency or embed node into the RPM, here are some points to consider.

  • Embed node.js into your RPM
    • Single .rpm file to distribute
    • Allows your application to tightly control the node version it uses. (see below)
    • Higher reliability. The fact is your app is probably coupled fairly tightly to at least the minor version of node.js you develop on (0.8.x for example) or even a patch release (>= 0.8.12 < 0.9 for example). It's best to allow node.js to decouple your app from the OS, but don't be fooled into thinking your app will work reliably on a different version of node.js without testing & adjustment. Most commonly these days there's just 1 app running on the OS, and the notion of sharing node between apps incorrectly values conservation of disk space over proper decoupling and operational independence of applications.
    • It's unclear whether there are any official/reliable pre-built RPMs out there in yumland that will "just work".
  • Specify node.js as a dependency of your PRM
    • Follows the general philosophy of OS package management (avoid duplication, conserve disk space, etc)
    • RPM provides capabilities beyond TAR around inventory management, uninstallation, upgrade, etc. Since you are asking this question, you are probably not ready to address these properly yet, so you might want to start with tar and once you have a solid understanding of that, consider RPM upgrade scripts, etc.
    • The "single file to distribute" nice point can quickly become untenable once your app starts using a database or 3, supporting daemons for email, log aggregators, etc.
like image 124
Peter Lyons Avatar answered Nov 19 '22 15:11

Peter Lyons