Instructions for deploying the a nodejs server to production.
- Deployment
- Resources
Once a linux server has been created in your preferred cloud platform (I am using Hetzner here), we need to prepare the server for production usage.
Generally speaking, you should get access to the root user when you create a server, which should allow you to ssh into the server using the command below:
$ ssh root@your_server_ip_addrOnce you have logged in, immediately the first thing to do is to set a password to the root account.
Use the command below to change password:
root $ passwdSince working with root directly is generally discouraged for various security and safety reasons, we'll create a seperate user account with limited permissions who's job is to run the server.
Use the command below to create a new user account:
root $ adduser server_usernameWe can now provide our new user with admin privileges so we don't have to switch to root user every time we need to do an administrative task. This will allow the new user to do administrative tasks by prepending sudo to their commands.
root $ usermod -aG sudo server_usernameWe can make use of ufw firewall to limit the extent of ports etc that general public can access. To do this, first make sure to install ufw on the server:
root $ apt install ufwNow that we have ufw installed, it's time to configure it. You can try to run the following command to see if we can already start configuring various applications' access through firewall:
root $ ufw app listWe need to make sure that the firewall allows SSH connections so that we can log back in next time, we can allow these connections by typing:
root $ ufw allow OpenSSHand then we enable the firewall itself:
root $ ufw enableYou can check the status of the firewall by typing in:
root $ ufw statusFor our application user that we created a few steps back, if you try to ssh using the command below:
$ ssh server_username@your_server_addrYou will be prompted to enter the user password to login, but since we already have our public SSH key on the server configured for the root user, we can just copy over the root user's .ssh/authorized_keys folder into our server user's home folder.
We can do this using rsync:
root $ rsync --archive --chown=server_username:server_username ~/.ssh /home/books-server/.sshNow you should be able to simply SSH into your server without typing in your password.
Starting now, let's use our newly created application user to setup NodeJS
So if you want to run the books-server, since it is written in NodeJS, we'll need to setup nodejs on the server. To install NodeJS, I'm going to simply follow the instructions from NodeSource as they provide binary distributions for most major versions of NodeJS.
Simply follow the installation instructions from their github page, as I am using a debian server, I'll be using the instructions for Debian:
books-server $ sudo apt install -y curlbooks-server $ curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.shbooks-server $ sudo -E bash nodesource_setup.shbooks-server $ sudo apt-get install -y nodejsbooks-server $ node -vGenerally speaking, NPM should come part of the Node.js package, so if you have nodejs installed, you should be able to also use Npm, you can verify that npm is installed by typing:
books-server $ npm -vFor some NPM packages, we often need to locally compile the native binaries from source, for example in the case of node-gyp. To make it possible, we can install the build-essential package as it will install various tools like make, gcc etc on our system.
books-server $ sudo apt install build-essentialBooks server primarily uses yarn for it's package management, so let's install yarn:
books-server $ npm i -g yarn@latest # installation
books-server $ yarn -v # verificationYou can just copy over the books-app server from your local machine to the server by using scp. But before you do that, make sure that you make a production copy of your server folder and then remove any unwanted folders like .git, node_modules, .yarn etc.
Run this on your local machine to copy over the books-server:
$ scp -rp .\books-app-prod books-server@your_server_addr:/home/books-server/appYou might have to rename or move the server folder to an appropriate directory on the server once you have uploaded everything. I stored my server at /home/books-server/app.
At this point, you should just be able to use node path/to/server.js or equivalent to run the server. Please note that the server will not be available to public yet as we currently only allow SSH connections through the ufw firewall.
Before we configure the firewall, we should first setup the server itself.
Make sure to update the env variables file in the server folder, specifically configure the server to run on port 80 (since we're only doing http for now) as well as any other env variables like the database URL etc.
At the end of this step you should be able to already start a production server, albiet without any daemon in place to handle automatic restarts etc.
PM2 is going to be our daemon controller, it will setup a daemon for our server so that any time our server has to restart, the daemon will make sure that books-app server is also restarted and up and running again.
To install PM2, just run:
books-server $ sudo npm install pm2@latest -gNow you can instruct PM2 to start the books-server
books-server $ sudo pm2 start path/to/server.jsThis will add books-app server to PM2's process list. Applications running on this process list will be automatically restarted if the app crashes or is killed. We can also take one additional step to make sure that the app is run on system startup:
books-server $ sudo pm2 startup systemdThis will ask you to run a specific command with sudo permissions in your terminal, once that is done, a systemd unit is created, that runs a pm2 process on boot for books-server user. This pm2 instance in turn will run the server itself.
Now that the server is up and running you should do one last thing before accessing the server and that is to allow http connections on port 80.
books-server $ sudo ufw allow 80 # alternative: sudo ufw allow httpYou can verify that access to port 80 is allowed by typing in:
books-server $ sudo ufw statusCongratulations! You have accessfully setup a nodejs server for production!
You can now visit http://your_server_addr to checkout your newly setup server!
- https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/deployment
- https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu
- https://www.digitalocean.com/community/tutorials/understanding-nginx-http-proxying-load-balancing-buffering-and-caching
- https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-20-04
- https://www.digitalocean.com/community/tutorials/how-to-configure-remote-access-for-mongodb-on-ubuntu-20-04
- https://advancedweb.hu/how-to-use-lets-encrypt-with-node-js-and-express/