Deploying a Node.js Web Application on Amazon EC2 with Apache

Deploy your Node.js web application on AWS EC2 instance with Apache web server

AWS Node.js Apache PM2
AWS Node.js Apache PM2

When you are done with your Node.js web application the next big thing you may worry about is “how and where to deploy it?”. There are many ways to deploy a Node.js application. Most people go for managed hosting like Heroku, DigitalOcean, AWS Elastic Beanstalk, etc. But some are adventures and want to manage everything on their own.

In my case, I had an EC2 server with existing Laravel applications running. My goal was to deploy the Node.js application on it without messing the existing Laravel sites and with minimal installs possible. So I decided to use the existing Apache server and didn’t want to install another web server like Nginx. Fortunately, everything went well and I had my application deployed without messing anything.

With that experience in hand, here I am trying to explain the step by step process to deploy a Node.js web application on Amazon EC2 as simple as I can.

To get a clear picture of what we are doing, we can split the steps into 3 major sections.

  • Step A: Install Node.js and setup your application on EC2 instance.

Step A: Install Node.js and setup your application

In this step, we will install the Node.js and setup your project on your EC2 instance. Assume you have root SSH access to your EC2 instance and access to your project source code. All the steps are doing inside the EC2 terminal, so go ahead and log in to the EC2.

ssh <username>@<server ip>

Step A-1: Install Node.js

The best and easy way is to install Node.js is using NVM (Node Version Manager).

Download and install NVM.

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash

Reload the profile.

source ~/.profile

Now install Node.js. You must be aware of the node version that supported by your project or install the latest LTS version.

nvm install v10.19.0

Step A-2: Clone the project

This is a simple step to copy your project to the server. You can either download or clone from a repository. Usually, the web projects are saved under the folder “/var/www/html”, so you can follow that.

cd /var/www/html
git clone <repository url>

Change the directory to your project directory

cd <your new project directory>

Step A-3: Install dependencies and build

Now you can install your project dependencies and build your project.

npm install

You can also use the “ — production” flag if you don’t want to install the dev dependency. If your project needs to build, you can run you build script, like “npm start” or “npm run build” or “grunt” or “gulp” depends upon your project configuration.

Step A-4: Set the environment variable

You may need to set the flag `NODE_ENV` to tell your project that it is running on the production environment. We can configure that as a server-level environment variable by editing or creating the file “/etc/environment”

sudo vim /etc/environment

This will open the file on the vim editor. Add the following line, save and exit (on vim editor, ESC + : + wq + Enter).

NODE_ENV=production

Logout and login the terminal again to take effect on the environment variable.

Step A-5: Verify the application is working

Now, make sure that your application is running properly on the server. You can run your project’s start command to check that. If it works, we are halfway succeeded. But if not, you have to check what is missing on the EC2 than your local running environment.

node app.js

Step B: Install process manager and keep your application run always

Now we are entering into the deployment section. To give you an idea of what we are going to do. The Node.js web applications are started by running a command like “node app.js”. So the web application can listen to the specified port for HTTP requests, for example, “http://127.0.0.1:3000”. But, if you exit the remote terminal the command will eventually stop and the project will not be accessible.

To avoid this problem, we are using a process manager which will keep running the node application even when we exist the remote terminal or the server is restarted.

Step B-1: Install the Process Manager

We can install the process manager PM2.

npm install -g pm2

Step B-2: Configure process

pm2 start app.js
pm2 save
pm2 startup

Now you are running your application. Please note the above start command. The last parameter is the name of your start script. For example, if you start your application like “node app.js” then it will be ”pm2 start app.js”.

You can see the running process and mange it anytime you want. The below command will list the running processes.

pm2 list

Step B-3: Test the application is accessible

Now we believe the application is running and we must make sure it is happening. We are running the application inside the EC2 and it is only accessible locally until we configure the web server. We can use telnet command to check if the application is accessible. (Considering the port configuration for you project is 3000).

telnet 127.0.0.1 3000

If you get the success response, we are pretty close to the final step.

Step C: Configure Apache to work with the Node.js application

Now the final step is to route your original domain to the locally running Node.js application (Ex. http://127.0.0.1:3000). For this, we can use Apache as a reverse proxy server which will take care of the communication in between.

Considering you already have made the DNS settings for your domain to point to this EC2 server.

Step C-1: Enable Apache proxy modules

Enable the Apache proxy modules.

sudo a2enmod proxy
sudo a2enmod proxy_http

Step C-2: Add virtual host settings

Open the Apache virtual host configuration file.

sudo vim /etc/apache2/sites-enabled/000-default.conf

Add the following virtual host settings and save the file. Please replace “yourproject.com” with your domain name.

<VirtualHost *:80>
ServerName yourproject.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:3000/
</VirtualHost>

If you have to setup the SSL configuration, you have to add the virtual host settings on the file “/etc/apache2/sites-enabled/default-ssl.conf” also.

Step C-3: Restart Apache web server

Now restart the server to take effect on the virtual host settings.

sudo service apache2 restart

And we are done!

Conclusion

Hope everything went well for you too and you have your domain working perfectly. The configuration is not that hard if we do it properly. The best bet is to understand each step and why we are doing it. I hope I could explain the steps properly and easily.

Thank you so much for reading. Happy Coding!

Full stack engineer. Believes the code should be as beautiful as the design. http://dipu.me

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store