DevOps Roadmap

DevOps Roadmap
DevOps flow

After working in the Software industry for more than 2 years(including internships), I have learned many things, one is to have knowledge about how the applications are hosted, whether it is on-prem or on the cloud, but knowing how they will be hosted really helps you get a deeper dive on how to write the code and maintain it. Going serverless or monolithic and why and all those questions that arise during desiging the architecture of the application. Anyways going on that will itself is a completely separate topic to itself.

So coming back to the point, let's start to see the DevOps roadmap.

So DevOps is not just about hosting the application on a server and forgetting about it, it is just so much more than that, and some more things are
- Hosting the application and exposing it with an SSL Cert
- CI/CD pipelines
- Server monitoring
- Scaling the infra according to the requirements
- Securing the servers from bad actors (e.g. preventing/handling DDOS attacks)

These are the few topics that we will cover in this blog and in the same sequence, so let's dive in.

Before going in-depth into the topics, I am assuming you have a basic Linux understanding and its file system and how to start an ec2 machine and SSH into it.

Hosting the application and exposing it with an SSL Cert

For further simplicity let's break it down into 3 parts,
1. Running the application in the background
2. Exposing the application
3. Having an SSL cert to the domain

Running the application in the background
So, let's say you have an application that internally exposes and runs on a specified port, let's say 3000.
So now our 1st step will be to make it run independently, we can use PM2 (NodeJs/NextJS/Flask, etc), forever, serve (ReactJS), or even make our own systemd config file that will have the start command and will make sure the application runs as expected.
But prefer to run the application over PM2 as it has better capabilities and monitoring than compared to others.

Here we will be seeing how to start a NodeJS application via pm2.
First things first, install the pm2 module globally via npm and we are good to go.

npm install pm2@latest -g  # to install pm2
# once installed start the application
# assuming server.js is the main file,
# pass the name accordingly in the name flag
pm2 start --name 'hello_world' server.js 

And that's it, you have started a background application that will run at port 3000 even if you close the terminal.

Now that the application is up, let's expose it to the public.
One way to do this is to directly open the firewall port and it will run on the IP:3000 but that's not up to the standard, is it?
So let's expose port 443 with an SSL certification, to the end users.

Exposing the application
For mapping the internal port 3000 to 443 we are going to use Nginx, and this process that we are going to use is called reverse-proxy.

So as always install Nginx, and will update the config file to our use.

sudo apt update  # update the system package cache
sudo apt install nginx  # install the nginx package
sudo vi /etc/nginx/site-available/default  # edit the config file using vim or any editor of your choice

Once you are in the file, you can simply remove the content and paste the updated nginx sample config file as below, where we have to replace the example.com with your actual domain name and this makes sure your application will only accessed via your domain. Or just pass the IP if you don't have a domain.

server{
    server_name example.com 123.123.123.123;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
	    add_header Access-Control-Allow-Credentials: true;
      	add_header Access-Control-Allow-Origin: *;
        # location /overview {
        #     proxy_pass http://127.0.0.1:3000$request_uri;
        #     proxy_redirect off;
        # }

	if ($request_method = 'OPTIONS') {
           add_header 'Access-Control-Allow-Origin' '*';
           add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
           #
           # Custom headers and headers various browsers *should* be OK with but aren't
           #
           add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
           #
           # Tell client that this pre-flight info is valid for 20 days
           #
           add_header 'Access-Control-Max-Age' 1728000;
           add_header 'Content-Type' 'text/plain; charset=utf-8';
           add_header 'Content-Length' 0;
           return 204;
        }
        if ($request_method = 'POST') {
           add_header 'Access-Control-Allow-Origin' '*' always;
           add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
           add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
           add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
        }
        if ($request_method = 'GET') {
           add_header 'Access-Control-Allow-Origin' '*' always;
           add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
           add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
           add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
        }
    }
}

nginx sample config file

nginx reverse proxy conf file
nginx reverse proxy conf file. GitHub Gist: instantly share code, notes, and snippets.
sudo systemctl restart nginx

And now 2 of 3 parts are completed.

Having an SSL cert to the domain
For attaching the SSL cert, we need to have a fully qualified domain, i.e. you should have full domain access, not just the subdomain, like xyz.github.io.
If you don't have a domain, you can't deploy an SSL cert.

Assuming you have a domain, lets go forward and grab that server's IP and map it to the domain in your domain provider, eg GoDaddy or Name.

What we want to do is, add an A Type record (it internally maps to an ipv4 address, AAAA to ipv6, CNAME is an alias to another domain).

Below is a screenshot from the name.com where you have to pass the * for absolute domain or a subdomain and enter the IP in the answer field.

Now after adding, it internally might take time to reflect to all the DNS providers, so let's take a small break, and grab a cup of coffee, tea, or beer whatever sails your boat.

Coming back, assuming the application is up on your domain, but just not with the SSL cert, lets fix that, using Cerbot.

Let's install and set it up.

sudo apt install python3-certbot python3-certbot-nginx # install 
sudo certbot

On running the certbot, it will automatically read the nginx config and get the domain details, and just follow the on-screen steps, i.e. enter your email for SSL-based notifications for your domain. Once done, and voila you are done.

You have now a fully functional application running on your domain.

Going forward, we will see the next topics in the next blog post about setting up a CI/CD pipeline for our application so that we don't have to manually SSH and update the application's code.

So sign up for the next post-release notification.

If you have any doubts feel free to reach out to me, via email at [email protected] or over Telegram at https://t.me/harshitruwali, Or drop a comment below.

Until then cheers!