Deborah Emeni I'm a software developer and technical writer who specializes in Node.js and JavaScript.

Configuring Apache for Node.js

7 min read 1983

Configuring Apache For NodeJ.js

There is a correlation between website performance and user engagement across all industry verticals. Having a server solution that can handle high traffic volume, respond to requests quickly, and mitigate cyber risk can be beneficial for both customer satisfaction and retention.

Apache is a popular, open source server that offers several benefits for improving application performance and security. Apache is used with over 30 percent of all websites, including those of many well-established companies, such as Slack, The New York Times, and LinkedIn.

In this article, we’ll examine some of the benefits that Apache brings to Node.js applications. We’ll also walk through a tutorial with a working code sample to demonstrate how to configure Apache for a Node application.


  • Latest versions of Node.js and npm
  • Terminal for installing packages and testing code
  • VS Code, or your favorite code editor

N.B., the tutorial portion of this article was developed using an Ubuntu 18.04 operating system and Node.js v14.17.6.

Let’s get started!

Benefits of configuring Apache for Node.js

Apache provides three core benefits for Node applications:

Let’s explore the use case for each benefit.


An app is more likely to retain users when its content loads quickly. Caching improves the performance of an application by saving bandwidth and improving the application’s speed. Any time a Node application gets simultaneous, multiple requests for the same static content, caching is essential.

By configuring Apache for a Node application, we allow the Apache server to install the static content. When there are future requests for the same content, the response will come directly from Apache, rather than from the application’s server.

Load balancing

A high-performing app must be readily available to users, even as it scales. Load balancing improves an app’s responsiveness by distributing incoming requests across multiple servers. A popular app may get thousands of requests per second. By configuring Apache for a Node application, we permit Apache to distribute the multiple events across all servers in the application.

Reverse proxy

It’s important to ensure your application is protected from viruses, malware, and other cyber risks. With reverse proxy, Apache can be configured to act as a firewall or filter for all incoming requests. Reverse proxy helps to mitigate some security threats, such as DDoS attacks. Additional benefits of reverse proxy are improved user request management and the encryption of the application’s IP address and data.

Now that we’ve reviewed the benefits of using an Apache server, let’s install and start the Apache server.

Installing and starting the Apache server

Let’s start by checking if Apache is already installed on our system by running this command:

apache2 -v

This will display the version of Apache that is currently installed:

Display Apache Version

If Apache is not currently installed and you are using an Ubuntu OS, follow these four steps to install the apache2 package on your system:

  1. Update your package repository with the following command:
sudo apt-get update
  1. Once your repository has been successfully updated, install Apache by running this command:
sudo apt-get install apache2
  1. Check that Apache has been installed correctly by pasting into your browser. If the installation was successful, you should see the following default page:

Apache2 Ubuntu default page

Next, check your IP address using the following command:


If you paste your IP address in the browser, you should see the same default page displayed on the screen.

  1. Ubuntu automatically starts the Apache server following installation. Now, confirm the status of apache2:
sudo systemctl status apache2

The status screen should confirm that the Apache server is up and running:

Apache Status Screen

Reviewing basic commands for the Apache server

Now that we’ve installed the Apache server (or confirmed that it was already installed), let’s review some important commands:

Restart the Apache server:

sudo systemctl restart apache2

Reload the Apache server after adding a configuration:

sudo systemctl reload apache2

Disable the Apache server from starting automatically upon reboot:

sudo systemctl disable apache2

Enable the Apache server after it has been disabled:

sudo systemctl enable apache2

Reviewing basic content and file structure of the Apache server

Let’s review some of the basic content and files of the Apache server. We can see a list of available files using this command:

ls /etc/apache2/

Here’s the output:

Apache Files

The apache2.conf file contains the Apache server’s configuration.

The sites-available directory is where we can create configuration files that Apache will run.

The sites-enabled directory contains symlinks to the configuration file defined in the sites-available directory.

The Apache server will load files from the sites-enabled directory while applying the configurations defined in the sites-available directory.

The sites-enabled and sites-available directories are both critical for configuring Apache for Node. Upon installation, Apache automatically creates default files in each of these directories.

To view the default files, cd into the sites-available directory:

Now, run the ls command:

Apache Sites Available Directory
Terminal showing the default files available in the sites-available directory.

We can see there are two default configuration files, 000-default-conf and default-ssl.conf, in the sites-available directory.

Now, let’s cd into the sites-enabled directory:

cd ../sites-enabled

Again, run the ls command:

Apache Sites Enabled Directory
Terminal showing the content of the sites-enabled directory.

Next, let’s set up the Node application!

Setting up the Node.js application

For this tutorial, we’ll use a Node.js demo application that was built on the Express.js framework with a MongoDB database.

Here are the steps to follow along:

  1. Clone the repository from GitHub to your local system. If you are not sure how to clone a repo, check the GitHub documentation
  2. Open the Node application with your code editor
  3. Run the npm install command

Let’s start by reviewing the demo’s app.js file:

const express = require('express');
const app = express();
const mongoose = require('mongoose');
const cors = require('cors');
const bcrypt = require('bcrypt');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const jwt = require('jsonwebtoken');
const authRoute = require('./routes/auth.route');
const suggestionRoute = require('./routes/suggestion.route');
const documentationRoute = require('./routes/documentation.route');
const port = process.env.PORT || 3000;
const corsOptions = {
    "origin": "*",
    optionsSuccessStatus: 200
app.use('/', documentationRoute);
app.use('/api', authRoute);
app.use('/api', suggestionRoute);
//Connection to mongoose
try {
    mongoose.connect(process.env.DB_CONNECTION, {
        useNewUrlParser: true,
        useUnifiedTopology: true,
        useFindAndModify: false,
        useCreateIndex: true
    }, () => console.log('Connected to DB'));
} catch (error) {
    console.log(`connection failed!! ${error}`)

app.listen(port, (() =>; console.log(`server started on port ${port}`)));

In the controllers folder, we define the documentationRoute.

Then we send the documentationRoute on the root request.

Here’s the Node application’s file structure:

Node File Structure

Now, let’s navigate to the documentation.controllers.js file in the controllers folder and review the content:

exports.documentation = (request, response) => {

The exports.documentation function accepts a request and responds with a link to the Node API documentation for the postman.

This Node application was built on MongoDB. We will need to create our own MongoDB cluster in order to generate our URI.

In the code editor, we create a .env text configuration file to set a DB_CONNECTION string for our session:


Next, let’s test the application to ensure it’s successfully connected to the database and is running.

Launch the Node application:

npm start

Here’s the result:

Node Application Launch

The Node application is connected to the database and is running on port 3000.

Next, let’s configure the Apache server for the Node application!

Configuring Apache for Node.js

We’ll reconfigure the Apache server to listen on port 80 and redirect all requests to the Node application running on port 3000.

To configure the Apache server for the Node application, we’ll follow these steps:

Confirming the Apache server is running

To begin, we need to start the Apache server. If you have been following along with this tutorial, the Apache server should still be running. If this is the case, simply run the following command:

sudo systemctl status apache2

You should see the following output:

Apache Server Running
Terminal showing the Apache server is running.

Paste localhost into the browser. If Apache is running successfully, the following will be displayed:

Apache2 Ubuntu default page in browser

Creating the Apache configuration file

Next, we need to create the configuration file. First, open a new tab and cd into the sites-available directory:

cd /etc/apache2/sites-available

Now, run the ls command:

Apache Sites Available File Contents
Terminal showing the default files available in the sites-available directory.

Next, we’ll open the 000-default.conf default configuration file in order to make edits:

sudo nano 000-default.conf

Here’s the open default configuration file:

Apache Default Configuration File
Terminal showing the 000-default.conf default configuration file.

The VirtualHost enables the Apache server to share its resources with multiple domains or hostnames. Any edits to the configuration must be made between the VirtualHost‘s opening and closing tags. Refer to the Apache documentation for additional information about the VirtualHost.

The Apache VirtualHost is defined in the 000-default.conf file and is set up to listen for requests on port 80.

We’ll configure the 000-default.conf file so that all requests coming in via port 80 will be proxied, or forwarded, to the Node application running on port 3000.

We use ProxyPass to map the root URL at the specified address: http://localhost:3000.

ProxyPass / http://localhost:3000/

Copy the following into the 000-default.conf file:

Apache Default Configuration File
Terminal showing the 000-default.conf default configuration file.

Next, use the Control+X command to save and exit.

Enabling the proxy and proxy_http modules

For ProxyPass to work, we must enable the proxy and proxy_http modules that act as gateways to allow for the passing of the request.

In the sites-enabled directory, run the following:

sudo a2enmod

a2enmod is an acronym for “Apache2 enable module.” Running this command will list all modules that are available to be enabled.

Next, we are prompted to enter the name of a module that we’d like to enable:

Apache2 Enable Module
a2enmod script running in the terminal.

We enter proxy at the prompt to enable the proxy module:

Enabling Proxy Module
proxy module enabled.

Next, we enter proxy_http at the prompt to enable the proxy_http module:

Enabling Proxy-http Module
proxy_http module enabled.

It’s important to note that we used the sudo command to run the a2enmod script. Running the a2enmod script without the sudo command will result in a Permission denied error:

Apache Permission Denied Error
Permission denied error.

Applying the configuration

Since we changed the configuration file, we must reload the Apache server in order to apply the configuration.

In the sites-enabled directory, use the following command to reload the apache2 server:

sudo systemctl reload apache2

Now, use this command to stop the apache2 server:

sudo systemctl stop apache2

Next, use this command to start the apache2 server:

sudo systemctl start apache2

Testing the configuration

To check if the Apache configuration is configured correctly, paste http://localhost:80 into the browser window.

If the configuration was applied successfully, we’ll see the Node application displayed:
Node Application Display


In this article, we reviewed some of the Apache server’s benefits, basic commands, and file structure. We also demonstrated how to configure the Apache server for a Node application for improved performance and security. See the Apache server documentation and Wiki for additional information, tips, and tricks.

200’s only Monitor failed and slow network requests in production

Deploying a Node-based web app or website is the easy part. Making sure your Node instance continues to serve resources to your app is where things get tougher. If you’re interested in ensuring requests to the backend or third party services are successful, try LogRocket.

LogRocket is like a DVR for web and mobile apps, recording literally everything that happens while a user interacts with your app. Instead of guessing why problems happen, you can aggregate and report on problematic network requests to quickly understand the root cause.

LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. .
Deborah Emeni I'm a software developer and technical writer who specializes in Node.js and JavaScript.

10 Replies to “Configuring Apache for Node.js”

  1. In your last step you say to visit localhost:3000 but apache listens to port 80, so you’re not using apache at all in the end? You should visit “localhost:80”

    1. If I got your question correct, running ‘npm start’ will autostart npm after reboot due to the nodemon package installed.

  2. Nice article as usual. However, I would like to bring in an edit at the Testing configuration section. To check if the configuration works, then pointing to localhost (not localhost:3000) again on the browser should no longer show the default apache page but should now redirect to the postman documentation as directed in the controller. I think that’s s better way to distinguish between the configuration before Apache is configured and after configuration. Localhost is now redirecting because requests through port 80 are being redirected to the root of the node application running on port 3000. Usually you also want to ensure that direct access to port 3000 is no longer possible as a firewall rule.

    1. Hi Brett, please what information is that? Do you mind pointing it out? Thanks!

Leave a Reply