I struggled a lot to understand nginx during my first assignments in nginx configurations for one of the angular deployments and little interesting things in it. I captured as much as possible in this post to help someone who is like me!!
Below entries are added to nginx.conf file which usually exist in /etc/nginx/nginx.conf
Table of Contents
Basic commands:
- sudo service nginx start – to start nginx server
- sudo service nginx stop – to stop nginx server
- sudo service nginx status – returns the current status
- sudo service nginx restart – restarts the nginx server
Converting uppercase url to lowercase:
This is actually highly recommended if you are going to deploy an application which is like shopping/any end user needed site and expecting better SEO.
# As your first location entry, tell nginx to rewrite your uri, # if the path contains uppercase characters location ~ [A-Z] { rewrite ^(.*)$ $scheme://$host$uri_lowercase; }
How to remove trailing slash for better SEO ?
By default nginx has the below snippet/something similar to this,
location / { try_files $uri $uri/ /index.html; error_page 500 502 503 504 /50x.html; location = /50x.html { } return 301 https://$host$request_uri; }
This one actually keeps the trailing slash as well if you enter it, so same url like ngdeveloper.com/nginx-server-notes and ngdeveloper.com/nginx-server-notes/ (observe the trailing slash) looks like duplicate url for your Search engine which may affects your site ranking, so always change the above snippet to like this,
location / { try_files $uri $uri/ /$is_args$args; error_page 500 502 503 504 /50x.html; location = /50x.html { } return 301 https://$host$request_uri; }
How to achieve IP canonicalization ?
IP canonicalization is also important to rank better in google/search engines.
This is nothing but, if suppose you hosted your site at 1.2.3.4 ip address named example.com, then if you just enter only 1.2.3.4 itself it should open example.com only. But if you hosted your website in any shared hostings you can not achieve this, as in the same IP(same server) many domains could have been hosted, so it can’t be done.
If you have deployed only one domain in your own server like EC2, then by doing below config in your nginx.conf file, you will be able to achieve IP canonicalization and greater SEO.
# ip canonicalization working part starts (works for http and https) server { listen *:80; listen *:443 ssl http2; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_certificate "/etc/letsencrypt/live/example.com-0001/fullchain.pem"; ssl_certificate_key "/etc/letsencrypt/live/example.com-0001/privkey.pem"; server_name 18.218.3.10; return 301 https://example.com; }
Here I have completed IP canonicalization for both http and https, that is why you are able to see ssl entries as well as two ports (80 -http, 443- https).
I have actually configured ssl (https) using free ssl certificate provider letsencrytp, read this link to understand more about it.
How to add subdomain (like demo.ngdeveloper.com) configuration in nginx.conf ?
Adding subdomain is very easy than you think in nginx.conf.
Here files to open/subdomain(admin.ngdeveloper.com) related files should be kept in this path, /usr/share/nginx/admin. (if it does not reflect make sure that you have restarted your nginx).
server { listen 80; listen [::]:80; server_name demo.ngdeveloper.com; root /usr/share/nginx/admin; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { try_files $uri $uri/ /index.html; } # redirect server error pages to the static page /40x.html error_page 404 /404.html; location = /40x.html { } # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { } return 301 https://$host$request_uri; }
How to configure Angular SSR (server side rendering) in nginx ?
Are you hosting angular application in nginx, then this may be the must know step to change your angular application to seo application.
As angular is a SPA (single page application), and loads only index.html file technically, google crawlers/search engines struggles to understand the basic details to show like title, description etc…
so convert your angular application to SEO application through angular universal and enable this below step in nginx for nginx server side rendering, having more money, then you can also try prerender.io for the same.
Here your angular application must be running in port 5000 in your server and nginx renders all the files from that port and helps to achieve server side rendering.
upstream ssr_saveji { server 127.0.0.1:5000; } // this block exists actually inside the server {} location /{ try_files $uri $uri @backend; } // here @backend refers to another location, which is, location @backend { // this line for caching in nginx server side proxy_cache ngdeveloper_cache; proxy_cache_key "$request_uri"; proxy_cache_valid 200 60m; # NOTE THERE IS NO TRAILING SLASH AT THE END. NO TRAILING SLASH. NO SLASH. NO! proxy_pass http://ssr_ngdeveloper; # <--- THIS DOES NOT HAVE A TRAILING '/' proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_http_version 1.1; # disable x-powered-by starts #proxy_set_header X-Powered-By ""; # disable x-powered-by ends proxy_set_header X-NginX-Proxy true; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; #below line commented when nginx above caching block enabled # proxy_cache_bypass $http_upgrade; proxy_redirect off; proxy_set_header X-Forwarded-Proto $scheme; } }
How to enable caching in nginx ?
proxy_cache_path /tmp/cache levels=1:2 keys_zone=ngdeveloper_cache:10m max_size=1g inactive=60m use_temp_path=off;
location / { # this increases minium 8 points in your google page speed score if ($request_uri ~* ".(ico|css|js|gif|jpe?g|webp|svg|png|woff2|jpg)$") { // keep this 90d - for 90 days, 30d - for 30 days expires 90d; access_log off; add_header Pragma public; add_header Cache-Control "public"; break; } }
How to redirect non-trailing slash to trailing slash in nginx ?
You have to include in the below line in your location / {} block, this single takes care of rewriting all the non-trailing slashes to slashed ending urls.
rewrite ^([^.]*[^/])$ $1/ permanent;
How to do reverse proxy (or) different port docker instances to point same subdomain ?
When we are working with microservices, all our microservices will be running with different ports in docker containers, so we can not create subdomains for all the running microservices.
So we need to enable reverse proxy in nginx with different locations (with same subdomain) to make this job easier.
This below configuration points https://api.ngdeveloper.com/microservices1 to https://ngdeveloper.com:8443/
and https://api.ngdeveloper.com/microservices2 to https://ngdeveloper.com:8440/,
Same way n number of microservices can be configured with different running ports for the same subdomain. And each endpoint will have different locations.
server { ssl on; ssl_certificate "/etc/letsencrypt/live/ngdeveloper.com/fullchain.pem"; ssl_certificate_key "/etc/letsencrypt/live/ngdeveloper.com/privkey.pem"; server_name api.ngdeveloper.com; listen 443 ssl http2; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP; location /microservice1/ { proxy_pass https://ngdeveloper.com:8443/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; } location /microservice2/ { proxy_pass https://ngdeveloper.com:8440/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; } }
How to increase nginx default timeout ?
By default nginx is configured with 30 seconds timeout. If you are processing any complex logics which takes more than 30 seconds then your user will face 504 timeout error only, instead of actual output.
In order to fix this, you need to create timeout.conf file in cd /etc/nginx/conf.d/timeout.conf
then paste the below values:
timeout.conf:
proxy_connect_timeout 600; proxy_send_timeout 600; proxy_read_timeout 600; send_timeout 600;
Then restart your nginx server.
sudo service nginx restart
How to test the nginx configurations ?
sudo nginx -t -c /etc/nginx/nginx.conf