Serve Angular Universal Server Side Dynamic Rendering with Nginx as Proxy
December 16, 2017
0 3 minutes read
You’ve managed to go through getting your current Angular 5+ project Angular Universal-friendly, which might have involved finding dependencies that are Angular Universal friendly too.
That is the story I followed to get khophi.com to be SSR. After re-reading for some 5 times, the process made sense and all the moving parts fell inline.
Hopefully, some day, the process might be simplified.
All looks good, you built SSR and ready to deploy. But wait…
How?
This article will go through how to server your Angular SSR in production behind a Nginx proxy.
Folder Structure and Upload
If you followed the SSR story link I shared above, you should end up with a folder structure similar to this on your local machine after successfully running npm run build:ssr
NOTE: Although npm run build:ssr might build your project without errors, the true litmust test of whether your application will run or not is to do npm run serve:ssr
That would be the moment of truth. If any errors come up, do well to fix them. Many of the errors at this point might likely be a piece of your code or third party code making reference to window.something or document.something
Folder Structure after SSR Build
So via SFTP or any other means, you find suitable, upload the entire contents of the dist/ folder.
In my case, I’m gonna upload into a folder /home/khophi/khophi.com/ssr/dist
Upload via SFTP
Use whatever folder names that match your setup.
Now let’s run the server and proxy
pm2 our SSR
PM2 is a production process manager for Node.js applications with a built-in load balancer. You can read more about it. That’s what we gonna use.
To get our dist/server.js running as a node process, we run
We then can monitor our running process at pm2 show ssr.angular or simply see all running processes at pm2 status
NOTE: After running the pm2 start ... command, run pm2 status. If you notice the restarts column for your process is more than 1, then there’s a restart loop.
pm2 status
pm2 show ssr.angular
You know where to find the logs if any issue. All the best.
If all is well, our process will be running on port localhost:4000
You can check if your port is running by entering the command sudo netstat -plunt
I assume all is well at this point. The last step is proxying the Nginx part. Let’s do it
All Hail Nginx
sudo nano /etc/nginx/sites-available/ssr.khophi – This creates a file where we put the content below into, in our sites-available folder of nginx
put the content below into it.
upstream ssr_khophi_nodejs {
server 127.0.0.1:4000;
}
server {
listen 443 ssl http2;
server_name staging.khophi.com; # <--- Change this part
include /etc/nginx/ssl/ssl-params.conf;# <--- Ignore this part if not using SSL
include /etc/nginx/ssl/khophi.com.ssl;# <--- Ignore this part if not using SSL
root /home/khophi/khophi.com/ssr/dist/browser; # <-- Notice where we're point to
location / {
try_files $uri $uri @backend; # <--- This looks for requests (statics i.e js/css/fonts)
# in /ssr/dist/browser folder. If nothing found, calls @backend
}
location @backend {
# NOTE THERE IS NO TRAILING SLASH AT THE END. NO TRAILING SLASH. NO SLASH. NO!
proxy_pass http://ssr_khophi_nodejs; # <--- 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;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name staging.khophi.com;
return 301 https://$server_name$request_uri?;
}
Finally, let’s enable our recently created virtual server block via
This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish.AcceptDetails
Privacy & Cookies Policy
Privacy Overview
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.