Serve Angular Universal Server Side Dynamic Rendering with Nginx as Proxy

Updated, Nov 2023: Deploy Angular 17+ Server Side Rendering with Nginx as Proxy

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.

Here’s a story on how to switch to Angular Universal for Server Side Rendering (SSR), Dynamic or Pre-render.

That is the story I followed to get 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…


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/

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

pm2 start ~/ --name ssr.angular

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 {
    listen 443 ssl http2;

    server_name; # <--- Change this part

    include /etc/nginx/ssl/ssl-params.conf;# <--- Ignore this part if not using SSL
    include /etc/nginx/ssl/;# <--- Ignore this part if not using SSL

    root /home/khophi/; # <-- 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 {
        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;
    return 301 https://$server_name$request_uri?;

Finally, let’s enable our recently created virtual server block via

sudo ln -s /etc/nginx/sites-available/ssr.khophi /etc/nginx/sites-enabled/

sudo nginx -t to see if we did everything right

sudo service nginx restart should, duh!

This is what I get in response. Success!


Lemme know of any questions in the comments.

Hope to see you in the next one.

Related Articles

Back to top button