21

What is the best practice for deploying a nodejs application?

1) Directly moving the node_modules folders from the development server to production server, so that our same local environment can be created in the production also. Whatever changes made to any of the node modules remotely will not affect our code.

2) Run npm install command in the production server with the help of package.json. Here the problem is, any changes in the node modules will affect our code. I have faced some issues with the loopback module (issue link).

Can anyone help me?

Sanjay Kumar N S
  • 4,165
  • 3
  • 18
  • 34

5 Answers5

22

Running npm install in production server cannot be done in certain scenario (lack of compiling tools, restricted internet access, etc...) and also if you have to deploy the same project on multiple machines, can be a waste of cpu, memory and bandwidth.

You should run npm install --production on a machine with the same libraries and node version of the production server, compress node_modules and deploy on production server. You should also keep the package-lock.json file to pinpoint versions.

This approach allows you also to build/test your code using development packages and then pruning the node_modules before the actual deploy.

DBellavista
  • 692
  • 5
  • 11
  • This should be the accepted answer. Building on production is not the way to go, since it doesn't allow you to run tests before you deploy. Also if you use typescript, you don't actually want the source but only the compiled .js files on production server. For completeness: make sure to build on the same architecture if node modules with native code (node-gyp) are used. – N4ppeL Sep 02 '19 at 15:56
4
  • Moving node_modules folder is overkilled.
  • Running npm install might break the version dependencies.
  • The best approach is npm ci. It uses the package_lock file and installs the required dependencies without modify the versions. npm ci meant for continuous integration projects. LINK
Raj Sahoo
  • 388
  • 3
  • 10
1

My guess is that by asking this question you don't really understand the point of the package.json file.

The package.json file is explicitly intended for this purpose (that, and uploading to the npm registry), the transfer of a node package without having to transfer the sizeable number of dependencies along with it.

I would go as far as to say that one should never manually move the node_modules directory at all.

Definitely use the npm install command on your production server, this is the proper way of doing it. To avoid any changes to the node_modules directory as compared to your local environment, use the package lock file. That should help with minimising changes to the source code in node_modules.

I mean no bad intent by saying this

harryparkdotio
  • 818
  • 12
  • 28
  • 4
    I'd say one case where copying of `node_modules` is unavoidable, is if the server cannot access internet (security reasons etc). – Vasan Jun 05 '18 at 06:56
  • This is a fair point. We have a set up like this for our build servers at work, but instead of copying over `node_modules`, we use our internal mirror, a far more elegant solution – harryparkdotio Jun 05 '18 at 06:58
  • So if we are moving the package.lock.json also, this won't occur rt? – Sanjay Kumar N S Jun 05 '18 at 07:18
  • what do you mean? – harryparkdotio Jun 05 '18 at 07:19
  • means, in the package.json file, the version is specified as "^3.0.0", and if we are moving the packag.lock.json file also to the production server and running npm install, the version which will be installed in the production will be same as the local rt? – Sanjay Kumar N S Jun 05 '18 at 08:51
  • the same as what is listed in package lock – harryparkdotio Jun 05 '18 at 08:55
  • @Vasan what security reasons? how is internet access considered unsafe? and it's easy to restrict internet access to access only npm registry etc. – Konrad Nov 02 '18 at 09:12
  • @Konrad the issue on production servers is not always access to the Internet, but also the lack of compilers to do the install to begin with. Having compiling tools on a production server is bad practice and should be avoided. Granting access to a public node.js module repository on a production server is also bad practice (just like for rubygem repositories...). The easy solution is to use containers built from pre-built images (i.e. Docker), but that's not always possible either. – Yanick Girouard Jun 19 '19 at 20:46
1

Definitely npm install. But you shouldn't do this by your own hand when it comes to deploying your app.

Use the tool for this like PM2.

As for your concern about changes in packages, the short answer is package-lock.json.

1

I am an ASP.NET Core developer but I recently started working with Node.js apps. For me this was one of the challenges you mentioned to move the node_modules folder to production. Instead of moving the whole folder to production or only running the npm install command on production server, I figured out and tried a way of bundling my Node.js app using Webpack into a single/multiple bundles, and I just got rid of the mess of managing node_modules folder. It only picks up the required node_modules packages that are being used/referred in my app and bundles up in a single file along with my app code and I deploy that single file to production without moving the entire node_modules folder.

I found this approach useful in my case but please suggest me if this is not the correct way regarding the performance of the app or if any cons of this approach.

Ali Shahzad
  • 4,381
  • 7
  • 26
  • 56