Wednesday, December 5, 2018

How to deploy NodeJS ReactJS to AWS EC2

I am working on a web application, which BackEnd is in NodeJS, FrontEnd is ReactJS Single Page Web Application.

I want to deploy the application on AWS EC2, Here is how I did it.

2018-12-05-00-19-12
Client - Server overview

 NodeJS

node version : v10.13.0

npm version : 6.4.1

BackEnd application runs on port 3000

I use PM2 for  process manager for Node.Js http://pm2.keymetrics.io/

ReactJS

React-scripts : 2.1.1 is ReactJS development tool, also help us to bundle javascript, css, images... into a build folder.

NGINX

Version : nginx version: nginx/1.14.0 (Ubuntu) , to find ngnix version
Change  nginx default file: /etc/nginx/sites-enabled/default

1. Add proxy pass for API
location ~ ^/api/ {
   proxy_pass      http://127.0.0.1:3000;
}

to pass all API requests to NodeJS server.

2. Add root static folder
root /home/ubuntu/public_html/lime-fe/build;

To point default static folder to the build folder of react-script.

3. Also it is important to have

location / {
    try_files $uri /index.html;
}
4. Reload nginx sever:
 
# systemctl restart nginx
OR
# sudo systemctl restart nginx
5. Additional setups: - Remove nginx version
server_tokens off;
- Enable Gzip
        ##
        # Gzip Settings
        ##

        gzip on;
        gzip_disable "msie6";

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        

to let reactJS application handles the routing (URLs) instead of nginx.

Full configuration file.
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
# gzip on;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /home/ubuntu/public_html/lime-fe/build;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location ~ ^/api/ {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-PORT $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
try_files $uri /index.html;
}
server_tokens off;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /var/www/example.com;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}
view raw default.conf hosted with ❤ by GitHub


Setup environment variables

~/.bash_profile

Some variables :

export NODE_ENV=production

To reload bash environment, using the command

source ~/.bash_profile

OR
. ~/.bash_profile

Some notes:

1. npm install without devDependencies:

If server setup with production mode on

NODE_ENV=production

, NPM install will ignore devDependencies

We can use npm install --only=dev or set NPM production.

to check if npm is in production mode , we can use the command:

npm config get production

To turn off production mode:

npm config set -g production false

2. pm2 doesn’t reload environment variables:

we need to use --update-env ,
e.g:
 pm2 reload sever --update-env

References

  1. How to install NodeJS and NPM : https://github.com/nodesource/distributions/blob/master/README.md

  2. How to install
    https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-16-04

  3. How to check Ubuntu version: https://askubuntu.com/questions/686239/how-do-i-check-the-version-of-ubuntu-i-am-running

  4. How to install MongoDB on Ubuntu: https://docs.mongodb.com/v3.2/administration/install-on-linux/