How to serve an angular app with Node js API on a Nginx server

Anas Oualim
5 min readSep 6, 2018

--

The first time I wanted to deploy my Node back end and Angular front on server I found my self facing a big problem :

How can I deploy my Angular app with my Nodejs Backend ?

The first solution was very simple : “Serving my angular app directly with express”. In fact node and express are quit good at serving static files. The schema of this configuration is :

Serving Angular with Nodejs

This can seems as a good idea at a first look, But there is 3 Reasons why you should not do this :

  • Node and express are not optimized for serving statics files, While Node will do fine, nginx will most definitely be faster when configured correctly.
  • Because Nginx ismuch much faster. Node/express are good for executing logic, but for serving raw content… nothing can beat nginx. You also get additional capabilities such as gzip, load balancing
  • Nginx has become the de facto standard as the frontend server

For this reasons and more the best solution is to use Nginx as a middle ware for serving static files and as a proxy for your node app.

The structure of this architecte is quit simple :

As you can see this architecture is more structured and more scalable.

Nginx has a lot of other functionalities that will make you life easier :

  • Rate Limit
  • Load Balance
  • Easy SSL integration with let’s encrypt

Now that you are convinced that this is the best solution for your app this is how you can do it :

1- First lets install Nginx :

$ sudo apt-get update;
$ sudo apt-get install nginx;

At the end of the installation process, Ubuntu 16.04 starts Nginx. The web server should already be up and running. We can check with the systemdinit system to make sure the service is running by typing:

$ systemctl status nginx

The output should be similar to the following:

● nginx.service - LSB: Stop/start nginx
Loaded: loaded (/etc/init.d/nginx; bad; vendor preset: enabled)
Active: active (running) since Mon 2017-05-15 09:21:58 CEST; 20min ago
Docs: man:systemd-sysv-generator(8)
Process: 3133 ExecStart=/etc/init.d/nginx start (code=exited, status=0/SUCCESS)
Main PID: 24279 (code=exited, status=0/SUCCESS)
CGroup: /system.slice/nginx.service
├─3141 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.con
└─3142 nginx: worker process

Now that your Nginx Server is running let’s set it up to serve the Angular app First :

2- Redirect all request to get Static files :

Let’s open our nginx config file with vim :

$ vi /etc/nginx/sites-enabled/default

this file should look like this :

server {
listen 80 default_server;
listen [::]:80 default_server;
# 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 /var/www/html;# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;location / {
# 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://localhost:8080;
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection 'upgrade';
# proxy_set_header Host $host;
# proxy_cache_bypass $http_upgrade;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php7.0-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# # With php7.0-fpm:
# fastcgi_pass unix:/run/php/php7.0-fpm.sock;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

Ok first set your root to your static files location : (in my case all my angular files are inside /var/www )

...root /var/www;..

Then Redirect all request starting with / to try to get files :

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying The
index.html
try_files $uri $uri/ /index.html;
}

Since Angular is a single page application and all routes are managed by angular all server request should in worst case send back the angular App if no file is found, then it’s up to the front end developer to manage 404 error and other …

Now close and save your file by typing escape then :wq!

Then reload Nginx :

$ service nginx reload

Coool ! Now you should be able to open your app on a browser.

3- Redirect all API request to Node JS :

For this I will suppose that your app is running on the port 4646 !(To deploy and run your app you can use PM2)

I will also suppose that all your API requests starts with /api if it’s not the case you should add a Prefix to all your Routes :

app.use('/api', router);

Ok ! Now let’s open again our Nginx config file :

$ vi /etc/nginx/sites-enabled/default

And add a new location :

location /api/ {
proxy_pass http://localhost:4646;
proxy_http_version 1.1;
}

This is telling Nginx that all request starting with /api should be redirected to the port 4646.

Don’t forget to reload Nginx

$ service nginx reload

And Voilà ! Your app is now working !

Hope this small blog was helpful :)

--

--