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
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 favorite option is managed hosting like Heroku, DigitalOcean, AWS Elastic Beanstalk, etc. But you can also host Node.js applications on your own server and manage yourself.
In my case, I had an AWS EC2 server with existing Laravel applications running. And 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. And it will be same for all Linux servers you have.
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 B: Install a process manager and keep your application run always.
- Step C: Configure Apache to work with the Node.js application.
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 Linux terminal, so go ahead and log in to your server.
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.
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.
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.
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).
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 server than your local running environment.
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
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.
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 server and it is only accessible locally until we configure the web server. We can use telnet command to check if the application is accessible inside the server. (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.
ServerName yourproject.com ProxyRequests Off
ProxyVia Full <Proxy *>
Require all granted
</Proxy> ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
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! Take the project URL on a browser and see it working.
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. Hope I have explained the steps properly and easily.
Thank you so much for reading. Happy Coding!