Deploying Angular Using http-server, Nginx, and PM2
Since it took about an hour to put all the pieces together correctly I thought it best to document how I deployed an Angular (version 2) app using http-server, pm2, and nginx. In my case I deployed to an Ubuntu server hosted on DigitalOcean, but these instructions should work the same as long as you have the other components installed correctly.
I am not an expert on this topic. Like most people, I am learning as I go. If you think I am doing something stupid please let me know.
Pre-reqs
Let’s get the easy stuff out of the way…
http-server
First, I installed http-server to serve my Angular app. I already had node/npm installed on my remote server, so I simply ran the follow command and was done.
npm install http-server -g
Angular
I used the angular-cli to create an app. When the app was done1, I created a build using:
ng build -prod
After the build was complete, I copied the contents of the dist/
directory to my remote server. Easy part, done.
Nginx
I am going to assume that the only reason you have made it this far is because you already have nginx installed on your server.
Nginx requires a server block for the Angular app so for me, this meant adding a file to the /etc/nginx/sites-available/
directory on my remote server. I am running multiple web sites so I created a new file called: ng2.cooldomain.com
. Before I forgot, I also created a symbolic link to the sites-enabled
directory:
ln -s /etc/nginx/sites-available/ng2.cooldomain.com /etc/nginx/sites-enabled/ng2.cooldomain.com
This is the configuration I ended up with2:
server {
listen 80;
server_name ng2.cooldomain.com;
location / {
proxy_pass http://127.0.0.1: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;
}
}
Two points of interest:
- You may use an IP address or some other convention for the
server_name
depending on your setup. - Depending on how you serve (e.g., different port) the Angular app you may have a different
proxy_pass
as well.
Pro Tip two commands to remember when messing with nginx: sudo nginx -t
will test your configuration and run sudo service nginx restart
after saving changes.
{: .notice–info}
PM2
Finally, I wanted to use pm2 to keep the new Angular site up and running. Over time I have created a collection of apps. Executing a pm2 command each time I finished an app has not been a big deal. Knowing if something goes wrong I would have to start them all again however is a different story. I went looking for a way to configure all the apps in a single config file. Of course pm2 has such a feature and I found the Application declaration documentation. Below are the important bits, including a snippet for another app just to demonstrate how you can configure multiple apps. I added the JSON below in a file called process.json
.
{
"apps": [
{
"name": "angular",
"cwd": "/var/www/ng2.cooldomain.com",
"args": "-p 8080 -d false",
"script": "/root/.nvm/v4.2.6/bin/http-server"
},
{
"name": "api",
"cwd": "/var/www/api.cooldomain.com",
"script": "app.js",
"watch": true
}
]
}
With all that out of the way I was finally able to test it all out:
pm2 start /path/to/process.json
Wrap-up
I am happy everything is up and running, but please ping me with suggestions on improving my setup. It’s not like I’m running anything important, so a true production setup isn’t required. However, I will say that I went through all this just to deploy a simple flash card game for my nine-year-old son. The app took me less than 30-minutes to write. The server setup and this post took me considerably longer.