Hosting Angular Universal on a server

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
Search for a command to run...

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
No comments yet. Be the first to comment.
Most of you know me for my consistency, a golden arrow in my blog series. I've written 1000 articles in 1008 days! Almost an article a day, and my honeymoon was the only holiday I ever took. I'm super proud of this achievement; it has been a fantasti...

It's not the first time I'll be talking about community. I think it's an essential aspect of any successful tool. This shows in my previous explorations of Astro, Medusa, and now Vendure as well. All these products thrive in a super open, welcoming, ...

The cool part about Vendure is how easy it is to set up and how abstract each layer is. Basically, we get the following elements: External database Server Worker Admin UI Frontend While this is amazing, it also brings a bit of complexity when it co...

The previous article looked at customizing Vendure on a data and process level. In this article, we'll look at customizing emails, as they are often a big part of a webshop system. We'll be looking at two different layers of customization for customi...

Even though Vendure is a pretty significant project out of the box, in some cases, we might want to go in and modify some elements to work to our specific use case. In this article, I'll take a high-level look at some elements we can customize within...

By now, you've seen how we converted our Angular application to Angular Universal. And we optimized this Angular Universal app for SEO.
That means it's time to put our hard word to rest and put the website online.
When trying to do this a while ago, I couldn't find many articles describing how that would work.
A plain overview of why this is slightly different:
Jim wants to view your website and asks the internet for yourawesomewebsite.com. The DNS will point that domain to your server's IP address.
By default, your server would serve these websites on port 80 or 443 for SSL. With our Angular Universal application, we have to start a node server that runs in the background.
node /home/user/domain/dist/server/main.js
Now our server is running on localhost:4000 on the server.
By this time, I had some question marks and regrets for moving to Angular Universal.
However, we can use proxies on a server to redirect our domain to that port internally.
I'll be showing you a preferred way and an alternative way. The alternative way was my only solution since our server wouldn't allow modifications on the vhost level.
There are multiple ways to get the Angular Script on the server.
You will pull the latest git branch on the server and let the server install all the dependencies.
This is a great way to deploy, but small servers with not much power can crash on the install and build.
npm install
npm run build:ssr
This would be ideal. We can have GitHub build all the files and artifact the dist folder as a zip, which we can transfer to the server.
I might come back on this in a future article. For now, you could read more on this concept on Philo's article
This is one way I've used as a middle-layer between the two methods.
This is powerful when your server can't handle the deployment for whatever reason, and GitHub can't transfer the artifact to your server.
What it means is we build everything locally on a deploy branch.
npm install
npm run build:ssr
That will give us the correct dist. Now we will specifically add this dist to the deploy branch.
# Force add the dist folder
git add -f dist/
git commit -m "Add build files"
git push -f origin production
Then on the server, you can checkout and pull the deploy branch, and you will have your build files ready.
Note: This is not a preferred method and should only be used if the above two options don't work for you.
You might remember above that we started the Angular Universal server with a node script, that will however, stop running if we terminate the script.
We can use systems like PM2 to run this script forever, and it allows us to monitor it, restart it, etc.
On your server, install the pm2 script globally.
npm install pm2 -g
Now we can start the same script with pm2 and even give it a name:
pm2 start /home/user/domain/dist/server/main.js --name yourappname
After this, you'll be able to stop it and restart it using the name.
pm2 stop yourappname
pm2 restart yourappname
Once we have Angular deployed and running on our server, we need to find a way to proxy the default domain to show the localhost:4000.
This depends on which server you are using, but let's say you use apache.
Find the Virtual Host file for this domain, and add the following lines:
ProxyPass / http://localhost:4000/
You would be able to find or create a new virtual host in this folder:
/etc/apache2/conf-availableRead more
What this line will do is say every request should redirect internally to localhost:4000.
Do make sure you have the proxy and proxy_http modules enable.
sudo a2enmod proxy_http
After adding this, you should also restart apache.
sudo service apache2 restart
This is the alternative way, and from what I've seen online, it's not recommended. However, I'm not sure for what exact reason.
For me, this works fine, especially if you don't have access to the vhost files or any server setup.
So with no access to the vhost files, I ended up using the htaccess method, which in essence does the same thing.
Open up your .htaccess file and add the following lines.
<IfModule mod_rewrite.c>
RewriteEngine on
# Redirect Public ports to NodeJS port
RewriteRule ^$ http://localhost:4000 [P,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ http://localhost:4000/$1 [P,L]
</IfModule>
These lines will make sure all requests are served to the localhost:4000 internal server.
You can now verify if your website is running. Let me know if you have any ideas, questions, or remarks on this article on Twitter.
Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter