How to package & deploy Node.js + express web application?
Asked Answered
S

6

87

I am new to Node.js programming and I have recently created a sample working web application using (express, backbone & other complimentary view technologies, with mongoDB). Now i am at a point where I want to deploy the same on a staging environment and I am not sure how to package this application and distribute the same. [I can take care of mongoDb and setting it up seperately]

I am from Java world and in there we create jars for reusable libs and war/ear packages for web applications which is deployed in a servlet container. Now in this case since node.js itself acts as a web container as well, how do i package my webapp?

  1. Is there any standard format/guidelines of packaging node webapps built using express? (Is there a similar jar/war packaging systems for node apps?)
  2. How do I deploy it once packaged? Would it become an exe, since it is also its own container?

PS: As of now I am thinking of just manually copying all the required source files into the staging environment and run npm commands to download all dependencies on that machine and then use 'forever' or some other mechanism to run my server.js. (Also, add some sort of monitoring, just in case app crashes and forever fails) I am not sure if that is the right way? I am sure there must be some standardized way of addressing this problem.

Schafer answered 21/1, 2014 at 13:12 Comment(1)
For my java projects we use Maven as a build/deploy tool. In the past, i have experience with even ant. I did look at Grunt for Node.js, but all i could understand from its tasks was that, it does preprocessing tasks (like minification, concat, JSHint etc..), it did not mention anything about packaging the app and then say installing into a repository (like how maven does).Schafer
R
45

There is no standardized way, but you're on the right track. If your package.json is up to date and well kept, you can just copy/zip/clone your app directory to the production system, excluding the node_modules.

On your production system, run npm install to install your dependencies, npm test if you have tests and finally NODE_ENV=production node server.js

Some recent slides I considered to be quite helpful that also include the topic of wrappers like forever, can be found here.

Rotunda answered 21/1, 2014 at 13:24 Comment(3)
Sorry for such a delayed response. I ended up with the above suggestion itself, after trying out all possible combinations. Thanks!Schafer
What if I don't want npm to download the modules from the internet. Instead I want to ship everything within the package. Is it possible to ship the node_modules Folder too? Does it work? The reason I ask is: My application may run in an intranet environment, without internet connection.Waaf
@Waaf Depends on the modules you ship with it. Since some modules which are not pure JS need to be built first, it could be that moving them to a different environment could break them. I haven't had to deal with this yet, but maybe using npm cache provides a viable solution by populating the cache with the full list of packages, then installing (and building) from that.Rotunda
M
92

Deploying Node.js applications is very easy stuff. In maven, there is pom.xml. Related concept in Node.js is package.json. You can state your dependencies on package.json. You can also do environmental setup on package.json. For example, in dev environment you can say that

I want to run unit tests.

but in production;

I want to skip unit tests.

You have local repositories for maven under .m2 folder. In Node.js, there is node_modules folder under your Node.js project. You can see module folders with its name.

Let's come to the grunt part of this answer. Grunt is a task manager for your frontend assets, html, javascript, css. For example, before deployment you can minify html, css, javascript even images. You can also put grunt task run functions in package.json.

If you want to look at a sample application, you can find an example blog application here. Check folder structure and package.json for reference.

For deployment, I suggest you heroku deployment for startup applciations. You can find howto here. This is simple git based deployment.

On project running part, simply set your environment NODE_ENV=development and node app.js. Here app.js is in your project.

Here is relative concept for java and nodejs;

  1. maven clean install => npm install
  2. .m2 folder => node_modules(Under project folder)
  3. mvn test => npm test(test section on package.json)
  4. junit, powermock, ... => mocha, node-unit, ...
  5. Spring MVC => Express.JS
  6. pom.xml => package.json
  7. import package => require('module_name')
Mordant answered 21/1, 2014 at 13:25 Comment(5)
Very useful. In package.json, is there a way to specify version to minimize possibility of breaking due to changes in dependencies?Expansionism
@MikiJ sure, you can specify version for the modules (dependencies). Semantic versioning is used in the package.json, you can see here for more detailsMythopoeic
Nice Java - Node comparison. Great!! Thanks!!Lammastide
Great.!! Is there anything equivalent to War file in Java? Because we would deploy only class files instead of source file, is there anything like that in node instead of deploying whole JS files.Irisirisa
@HüseyinBABAL your analogy isn't completely correct. because mvn clean install creates a bundled .war file that can be easily deployed to any server in the world and java -jar *.war executes it in the server. But how can I create a bundled file for my node project!! and how can I execute it in the server!!Orcinol
R
45

There is no standardized way, but you're on the right track. If your package.json is up to date and well kept, you can just copy/zip/clone your app directory to the production system, excluding the node_modules.

On your production system, run npm install to install your dependencies, npm test if you have tests and finally NODE_ENV=production node server.js

Some recent slides I considered to be quite helpful that also include the topic of wrappers like forever, can be found here.

Rotunda answered 21/1, 2014 at 13:24 Comment(3)
Sorry for such a delayed response. I ended up with the above suggestion itself, after trying out all possible combinations. Thanks!Schafer
What if I don't want npm to download the modules from the internet. Instead I want to ship everything within the package. Is it possible to ship the node_modules Folder too? Does it work? The reason I ask is: My application may run in an intranet environment, without internet connection.Waaf
@Waaf Depends on the modules you ship with it. Since some modules which are not pure JS need to be built first, it could be that moving them to a different environment could break them. I haven't had to deal with this yet, but maybe using npm cache provides a viable solution by populating the cache with the full list of packages, then installing (and building) from that.Rotunda
D
7

Hope this might be helpful for somebody looking for the solution,Packaging of Node js apps can be done using "npm pack" command.It creates a zip file of your application which can be run in production/staging environment.

Davita answered 15/9, 2018 at 17:15 Comment(0)
L
6
  1. Is there any standard format/guidelines of packaging node webapps built using express? (Is there a similar jar/war packaging systems for node apps?)

Yes, the CommonJS Packages specification:

This specification describes the CommonJS package format for distributing CommonJS programs and libraries. A CommonJS package is a cohesive wrapping of a collection of modules, code and other assets into a single form. It provides the basis for convenient delivery, installation and management of CommonJS components.

For your next question:

2. How do I deploy it once packaged? Would it become an exe, since it is also its own container?

I second Hüseyin's suggestion to deploy on Heroku for production. For development and staging I use Node-Appliance with VirtualBox and Amazon EC2, respectively:

This program takes a Debian machine built by build-debian-cloud or Debian-VirtualBox-Appliance and turns it into a Node.js "appliance", capable of running a Node application deployed via git.

Your webapp will not become an exe.

Loincloth answered 22/1, 2014 at 13:29 Comment(1)
Thanks for doing nothing more than simply answering the daggone question.Arissa
F
5

few ways to approach this:

  • Push your code into Git repository, excluding everything that isn't your code (node_modules/**), then pull it in your staging environment, run npm install to restore all dependencies

  • create an NPM package out of it , install it via npm in your staging environment (this should also take care of all of the dependencies)

  • manual copy/ssh files to your staging environment (this can be automated with Grunt), than restore your dependencies via npm

Farseeing answered 21/1, 2014 at 13:24 Comment(0)
W
2

I used zeit's pkg module. It can create cross platform deliverables for linux/win/macos. Actually used it in production and works fine without any issues.

It takes in all the js scripts and packages it into a single file.

The reason I used it is because it helps in securing your source code. That way in production at customers environment they will have access to application but not the source code.

Also one of the advantages is that at production environment, you do not actually need to have the customer install node.js as the node binaries also get packaged inside the build.

https://www.npmjs.com/package/pkg

Wein answered 11/4, 2019 at 11:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.