// twoslashes

Self-Hosting Your Node Application

Last updated Sun Jul 28 2024

I’ve been seeing a lot of talk about the concept of self-hosting in the context of it being a lost art; even questionable not to. The recent horror stories around a change in fee structure as well as developers waking up to emails of the hosting company requiring a tidy sum overnight when their website received some unexpected traffic has prompted many to explore the idea of self-hosting; with some even claiming that if you don’t self-host, it’s a big skill issue.

Great news, it’s really easy. In this blog, I intend to show you how to:

  1. Create a droplet on DigitalOcean
  2. Setting up the droplet and configuring it for a web application in Nodejs
  3. Deployment
  4. Adding an optional domain and SSL through LetsEncrypt (Optional)

Note: Not all web frameworks will support what we’re about to do without some additional configuration. This article is meant to give you the general starting point. This article is meant for the basic React or Vue application; or any framework that generates a static HTML file in either a build or dist folder.

If you don’t already have a DigitalOcean account, sign up for one at DigitalOcean.

Create a droplet

  1. Click the “Create” button and select “Droplets.”
  2. Choose an OS (Ubuntu is a common choice, but do your research and choose what’s right for your needs)
  3. Select a plan (a basic plan is sufficient for small to medium applications).
  4. Choose a datacenter region close to your target audience (If you’re marketing to the US, choose a US server).
  5. Add SSH keys (optional, but recommended for security).
  6. Click “Create Droplet”

You should receive an email about your droplet’s creation as well as information about how to access it via ssh. It could take some time for your droplet to be fully created/provisioned, but the process is generally quick.

Setting Up The Droplet

  1. Connect to your Droplet using SSH
ssh root@your_droplet_ip

Note: This article does not go into detail about Linux user accounts and their privileges. Using the root account beyond setting up your droplet is not recommended, but it will be up to you to research and learn the best approach for your needs.

  1. Update and install necessary packages
sudo apt update
sudo apt upgrade -y
sudo apt install nginx -y

We’ll be using nginx as our web server.

  1. Install Node and npm. This is optional, but I find it’s good to have installed in case you need to do any troubleshooting or want to build the package server side.
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs

This step adds the correct repository to download and install the LTS version of Nodejs. Once this step is completed, verify your installation with the following commands:

node -v
npm -v

If the prompt returns a version number, you’re all set.

Deployment

  1. Build your application. On the local machine where your web application is located, executing the build script should get you a working build or dist directory located in your project root folder.
npm run build

This may differ depending on your web framework. See your framework’s documentation about how to build out the application.

  1. Transfer the build files to your droplet using SCP. If your /var/www/html path already has an HTML file in it, it’s likely the static file generated when Nginx is installed. Delete it.

Note: There are other ways to transfer files, such as Rsync. Feel free to use whichever method you prefer.

# Navigate to your local project root in terminal
scp -r build/* root@your_droplet_ip:/var/www/html
  1. Create an Nginx configuration file for the web app on your server
sudo nano /etc/nginx/sites-available/default

Replace it’s contents with:

server {
    listen 80;

    # If using IP only, use this:
    server_name your_ip;

    # If using domain name, use this:
    server_name your_domain www.your_domain

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

Save and exit (CTRL+X, then y, then Enter)

  1. Restart nginx

Note: This step is critical as it will read the configuration file and set up the path to your application. In many cases of “It doesn’t work.”, it’s because this step was skippped.

sudo systemctl restart nginx

And you should now have a functional web application by navigating your browser to https://your_server_ip_address!

Optional, but kinda not; Domain and SSL

  1. Acquire domain and point it to DigitalOcean

This article assumes the reader is familiar with purchasing a domain through the many domain registrars out there. Once a domain is acquired, you’ll need to make sure your DNS has the appropriate records set so your domain queries the correct server.

Ultimately, you want your @ alias to point to the IP of your server. Additionally, you’ll want to point the www record to the IP as well. If you don’t see a www record, create one.

After that, give DNS some time to update. It’s generally pretty quick, but can take up to 48 hours in some instances. You’ll need DNS to be updated at your server location before generating SSL certificates. You’ll know it’s updated if you visit your URL in the browser and you see your website. You could, alternatively, execute the dig command from your VPS.

dig your_domain

If you see the IP of your server associated with the URL, you’re golden.

Note: DigitalOcean has a handy article on adding your domain using their control panel. You can find it (here).

Next, you’re going to want to secure your web traffic and the only way to do that is with an SSL certificate. These steps will fail if DNS hasn’t properly updated, so make sure step 1 is complete before moving on.

  1. Install Certbot for SSL
sudo apt install certbot python3-certbot-nginx -y
  1. Obtain and install the SSL certificate
sudo certbot --nginx -d your_domain -d www.your_domain

Just follow the prompts and certbot will automatically generate and set the SSL certificate.

Once finished, visit your domain or IP in the browser to see your deployed application; now complete with SSL!

Conclusion

I hope this article helps you with self-hosting your web applications. Some future considerations would be setting up Github Actions to automatically update your website when you push changes to your repo. This site has a workflow that automatically builds the application and uses rsync to deploy it.