Node.js Web Server Quick Start Guide

Requirements:

  • VPS with Linux installed. This guide covers Ubuntu/Debian.
  • Domain name with configured DNS.

Do Stuff

Login to the server from the terminal with ssh root@yourdomain.xyz. If you don't have the domain name set up you can replace yourdomain.xyz with the server's IP address.

Use apt update and then apt full-upgrade -y to update server.

Create user for you to login with by entering adduser youruser. Then add the user to the sudo group with usermod -aG sudo youruser.

Check to make sure that this worked. su - youruser to login as the new user then sudo ls -a /root. If you don't get an error, it worked.

Logout of the server. On YOUR computer, not the server, run ssh-keygen. Store the files in the default directory (c:/User/You/.ssh/id_rsa or /home/you/.ssh/id_rsa). You should use a password when it prompts you for one, even a weak one. Then use ssh-copy-id youruser@yourdomain.xyz to copy the key to the server. Test the new security with a login. You should be prompted for the password to your ssh key.

Once you are able to log in with your ssh key and you have a sudo user run sudo nano /etc/ssh/sshd_config and change the line that says PermitRootLogin yes to PermitRootLogin no. Press Ctrl + O then Enter to save the file and then Ctrl + X to exit nano. Logout of the server again and try to run ssh root@yourdomain.xyz. You should be told Permission denied, please try again. Probably don't try again though, it worked.

Log back in as your sudo user and run sudo apt install nginx certbot nodejs double check if npm came with nodejs. If not install that too with sudo apt install npm. Once that's done run sudo nano /etc/nginx/sites-available/yourdomain.xyz and enter

server {
        listen 80;
        listen [::]:80;

        server_name yourdomain.xyz www.yourdomain.xyz;

        location / {
                proxy_pass http://localhost:9000; # This number has to match the port on your node app
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_cache_bypass $http_upgrade;
        }
}

Output the file and close nano. Enable the site with sudo ln -s /etc/nginx/sites-available/yourdomain.xyz /etc/nginx/sites-enabled then run sudo nginx -t to make sure nothing is wrong. Finally restart nginx with sudo systemctl restart nginx.

Decide where to locate your web root and create a new .js file there. (i.e. mkdir /home/youruser/web_root && nano ~/web_root/myServer.js). While in the directory as your .js file run npm init then npm -i express. When that's done edit your .js file and add

const express = require("express");
const app = express();

app.get("/", (req, res)=>{
  res.json({response: "Hello World"})
});

app.listen(9000, ()=>{ // 9000 is the same port we set in the nginx configuration
  console.log("server started");
});

Save and close the .js file. Run sudo nano /etc/systemd/system/yourservicenamehere@.service and enter

[Unit]
Description=My Node HTTP Server
After=network-online.target
[Service]
User=youruser
WorkingDirectory=/home/youruser/web_root
ExecStart=/usr/bin/node myServer.js
Restart=always
RestartSec=500ms
StartLimitInterval=0
[Install]
WantedBy=multi-user.target

Then run sudo systemctl daemon-reload, sudo systemctl yourservicenamehere@1, and sudo systemctl start yourservicenamehere@1.

Lastly run sudo certbot follow the prompts and then you're done.