Installing Node.js on Ubuntu 18.04 and deploying Express SSR website


If you came here and see this text, your situation is as follows: you have a website or webapp or just a pet project made using Node.js and Express; it runs perfectly at your localhost and you came here at VPSServer[1] to make your project available on the web. Yeah you've made the right choice, congratulations! Flexible pricing plans[2] allow you to start from 5€/mo (if your project is not very "resource hungry", but believe me, even the cheapest basic plan fits perfectly for the most of pet projects).

So you are buying the server and configuring it up. First of all, as this tutorial is about Node.js under Ubuntu, it's assumed that you picked "Ubuntu" as operating system of your server (I should say that I'm not a Linux profi, but there are the very basics everyone should know, right?). And the first thing you meet at your server - the absence of Node.js and npm on board. The server is shipped with the basic (I would say, "naked") distro of Ubuntu, and you are to install them by yourself. So open your terminal (assuming that you have installed PuTTy or Git Bash if you are under Windows and yes, forget about GUIs), and login using "ssh": ssh username@XXX.XXX.XXX.XXX, where XXX.XXX.XXX.XXX is the IP address of your server. The IP address, your username and your SSH password are provided at your server's dashboard.

VPSServer Dashboard

I should note for Windows users that in PuTTy or Git Bash you need to use [Shift + Ins] instead of [Ctrl + V] to paste your password from clipboard while login. Just in case :-)

Once you've logged in, you need to install Node.js and npm. The one extra tool you may need to install is "unzip" to (obviously) unzip archives you upload to the server. The terminal commands for this are as follows:

apt install nodejs
apt install npm
apt install unzip

Yeah, now you're shipped with all the necessary tools. Now you need to deliver your project to the server somehow (keeping in mind that we forgot about GUIs and you cannot just drag and drop your files to the server). Pack your project into ZIP archive (don't include "node_modules" folder and "package-lock.json" lockfile to the archive), open one more terminal from your project's local directory and use "scp" command:

Using 'scp' command for copying file to server

Note the ":/root" after the destination (your server's) IP address. "root" is the root path of the server. And if you forget to include this part (semicolon, slash and path), you will fail to copy the file. And to succeed the copying you will need to enter your server's password (the same that you used for logging in).

After copying the archive should appear at your server's root. You may check it with "ls" command at the terminal. Almost done! You just need to unpack your project, install its dependencies and run it. So your next actions at the server's terminal are:

unzip <your-project-archive-name>.zip
npm install

And you see that we have unpacked the project, installed the deps, but... nave not run. Why? Yes, we can use linux-default method to run the processes in background. It looks like this:

nohup npm start &

But this method is far away from perfection. Node.js app servers can sometimes go down for unobvious reasons. And ran with "nohup", the app will not restart if it goes down. For this case I recommend to use "pm2" npm package[3] - it will restart your app after unhandled exception, plus it provides a good piece of docs for managing your processes. So your next actions at the server's terminal are:

npm install -g pm2
pm2 <your-server-executable-name>.js

And that's it, your app is running! Be sure that your app listens to the default port (80), so you can get to your app from the browser by entering your server's IP address (without adding :port). If you want to connect your app to the domain name, there is a good tutorial[4] on this point.

I hope this tutorial saved you hours of stackoverflow'ing. Be free to comment if you have anything to add or if I'm wrong at some points and you want to correct me.