How to Host a Node.js Website With Apache on Ubuntu

Node.js is a JavaScript runtime environment that can be used to create websites or web-based applications. The process for hosting a website that has been built with Node.js differs quite a bit from a “normal” HTML website, or even those that use PHP or other languages. In this guide, we’ll go over the instructions to host a Node.js website with Apache on Ubuntu Linux.

Towards the end of the guide, we’ll show how to get a free SSL certificate for your website from Let’s Encrypt. We’ll also go over installation of PM2, which is used to monitor your Node.js application and automatically restart it when it goes offline or detects changes to the code.

Configure Apache for Node.js

1. We’ll need a few packages to get started. Execute the following commands to install Apache, Node.js, and npm.

$ sudo apt update
$ sudo apt install nodejs npm apache2

2. In order to host a Node.js website, Apache will need to be configured as a reverse proxy server. Therefore, we’ll need to run this command to enable the necessary modules.

$ sudo a2enmod proxy proxy_http rewrite headers expires

Apache will warn that it needs to be restarted, but we will do that later.

3. Next, it’s time to create an Apache virtual host file. We’ll use the following command to create a new configuration file with the nano text editor.

$ sudo nano /etc/apache2/sites-available/example.com.conf

Inside this file, you can paste the template below. You will need to replace the ServerName and ServerAlias values with your own domain name. Also, this configuration assumes you will be running your Node.js application on port 3000 (the default). If that’s not the case, change the http://127.0.0.1:3000/ path accordingly.

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com

    ProxyRequests Off
    ProxyPreserveHost On
    ProxyVia Full

    <Proxy *>
        Require all granted
    </Proxy>

    ProxyPass / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:30000/
</VirtualHost>

Save your changes to this file and close it.

4. Enable the new site and disable the default Apache site. Then, restart Apache.

$ sudo a2dissite 000-default
$ sudo a2ensite example.com.conf
$ sudo systemctl restart apache2

5. At this point, we are ready to start our Node.js application. If you haven’t already created your Node.js app, you could generate a simple Hello World script for the sake of testing. You only need to do this step if you don’t already have a Node.js app ready to go.

Create the file in your user’s home directory.

$ nano ~/app.js

And paste the following code.

const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

6. There are multiple ways to run a Node.js app on Ubuntu. In our experience, one of the best ways is definitely with PM2. You can install the software by executing the command below.

$ npm install pm2 -g

7. Next, use the following PM2 command to start your Node.js app. The --name option makes our application easier to identify, and the --watch option will restart your application if changes are made to it, so they’re instantly reflected in the live version.

$ pm2 start ~/app.js --name example.com --watch

To make sure your Node.js application will come online automatically even after a full system reboot, save your PM2 process list and generate a startup script with these commands.

$ pm2 save
$ pm2 startup

To see your application in PM2 at any time, use the list option.

$ pm2 list

Logs for your Node.js app are stored in $HOME/.pm2/logs by default. You can also see a live feed of the logs with this command.

$ pm2 logs example.com

Press Ctrl + C to exit the log feed.

At this point, you should be able to access your Node.js website in a web browser, even if it’s just the Hello World script we created above. Continue to the next section if you want to configure SSL (HTTPS) on the website.

Obtain SSL Certificate

Let’s Encrypt is a free service that allows us to obtain an SSL certificate for our website. It’s rather easy to use on Ubuntu, including with Node.js, and most of the configuration is done automatically for us. Follow these steps to set it up.

1. Start by installing the necessary certbot packages with the following command.

$ sudo apt install certbot python3-certbot-apache

2. Then, execute the following command to obtain your SSL certificate, while replacing the example domains and email address with those of your own. Note that this command will automatically redirect www.example.com to example.com, which is good for SEO.

$ sudo certbot -d example.com -d www.example.com --apache --agree-tos -m admin@example.com --no-eff-email --redirect

If you’d prefer to use the certbot wizard to configure SSL instead, you can use the following command. This will prompt you about various options, including whether or not you want to redirect the www. prefix of your domain or not.

$ sudo certbot --apache

3. The certbot program will continue to run in the background, always keeping your certificate up to date by renewing it when necessary. You can check its status with this command, to make sure it’s actively running on your system.

$ sudo systemctl status certbot.timer

To ensure that certbot will auto renew certificates successfully, use the following command to perform a dry run.

$ sudo certbot renew --dry-run

Conclusion

Finally, you can navigate to your Node.js website in browser, and see that your connection is secure via SSL. If you’ve followed along this far, your website is up and running and will largely maintain itself. PM2 will ensure that your site is always running, and certbot will keep your SSL certificate in good standing.

You can continue to make changes to your JavaScript code as needed, and see the updates on your website instantly. Your configuration will also withstand system reboots and future upgrades. If you have any questions or remarks, let us know in the comments below.

If our content helped you, please consider buying us a coffee. We appreciate your support!

Buy me a coffee donation button

Leave a Comment

Your email address will not be published. Required fields are marked *