[{"content":"","date":"1 January 2024","permalink":"/tags/api/","section":"Tags","summary":"","title":"API"},{"content":"","date":"1 January 2024","permalink":"/tags/aws/","section":"Tags","summary":"","title":"AWS"},{"content":"","date":"1 January 2024","permalink":"/tags/express/","section":"Tags","summary":"","title":"Express"},{"content":"","date":"1 January 2024","permalink":"/tags/hands-on/","section":"Tags","summary":"","title":"Hands-On"},{"content":"","date":"1 January 2024","permalink":"/tags/intermediate/","section":"Tags","summary":"","title":"Intermediate"},{"content":"","date":"1 January 2024","permalink":"/posts/","section":"Posts","summary":"","title":"Posts"},{"content":"","date":"1 January 2024","permalink":"/tags/","section":"Tags","summary":"","title":"Tags"},{"content":"","date":"1 January 2024","permalink":"/","section":"The blogs of GhostVaibhav","summary":"","title":"The blogs of GhostVaibhav"},{"content":"A little backstory # It was a while back when I was working on one of my projects. I had my frontend ready as a React app hosted on GitHub pages to my custom domain. Everything was perfect and I deployed my backend server on an EC2 instance with an Elastic IP. Tried to use the combination in production, when I got hit with this error:\nThe Error Yes, it was Mixed Content error and I had an idea to resolve it. The idea was simple. It was to basically upgrade my Express server from HTTP to HTTPs. Now, I know this sounds simple but when I started to do so, it turned out to be rather complex. Even though it was complex, I got to know so many things that I wouldn\u0026rsquo;t have known if I wouldn\u0026rsquo;t be hit by this error.\nHow to go about it? # So, then, how to upgrade it? Well, I will first give you the whole technical summary of how my though process went and later put on the coding part.\nMy Thought process # The Certificates # As soon as I started the process, the first thought that crossed my mind were certificates. HTTPs was nothing but just short for HTTP with security which is implemented through SSL. For making sure that the server is not a bad entity, certificates are issued. Certificates are like a card of authentication which gives an idea about the server authenticity. In the above case, I was not having any certificates on my server, therefore the browser was not letting the request happen.\nCertificates can be issued by a global trusted entity like Amazon, etc. or they could be self-signed. Obviously, the self-signed ones are rather insecure since they don\u0026rsquo;t have any liabilities. Now, this is where the twists started, I tried to issue a certificate for my server.\nQuestion (#8fa387): Can you issue a certificate for a bare IP address?\nDon\u0026rsquo;t reveal the answer right away, search the internet first. What's the answer? IP\u0026rsquo;s vs Domain Names # After this, there was a huge question about how to issue a certificate and more importantly, to which entity? An IP address or a domain name.\nElastic IP Configuration As it turns out, the certificate can be issued to domain names only. But, but, but, when I was going through some resources, I came across a website which issues certificate for IP addresses as well linked here. I don\u0026rsquo;t know how they do it but it works. (I haven\u0026rsquo;t personally tested it but saw a YouTube video regarding the same) When I tried to do the same, it didn\u0026rsquo;t work. It crashed on some error about the site being down. So, I resort to issuing a SSL certificate to my Elastic domain name which is present in the Public DNS field of the configuration above. (something ending with *amazonaws.com)\nOnly a certain set of domains # It turns out you can\u0026rsquo;t issue a certificate for AWS IP servers, if you are not Amazon itself. And for doing that, you require both time and money, since it then meant to issue certificates from Amazon themselves. But I was adamant and didn\u0026rsquo;t want to use it, so I used my own domain for the process. The process afterwards went surprisingly well and easy.\nThe Redirection # When I first set up my new subdomain for this task, I blindly configured it to be used with GitHub Pages which I later realized. After an hour of investigation as to why it isn\u0026rsquo;t working, I came across about just adding an A record for redirecting it to the Elastic IP address on which my EC2 instance was configured.\nBut, where did Nginx come from? # I promise this is the last section before coding. I know you might be having a lot of questions about the introduction of Nginx in the mix, but, bear with me here. Configuring Express to serve with HTTPs requires prior certificates and private keys that I didn\u0026rsquo;t had access to. Therefore, I took the path with Nginx and passed all the traffic to Nginx which will then route the traffic back to my Express API server. For this, we need to shutdown some ports and open only some ports for the proper usage, this is where ufw will come into play. At the end of the day, this is how my architecture looked like -\n%%{init: {'theme': 'neutral' } }%% flowchart RL subgraph Port 80 direction RL A(Frontend) --\u003e|\"Takes request Over the internet\"| B(Nginx) end subgraph Port 3000 direction RL C(Nginx) --\u003e |Forwards to| D(Express) end B --\u003e |Internal Communication| C Ok, now enough talking, let\u0026rsquo;s get hands-on with this.\nNote: I won\u0026rsquo;t be setting up an Express API, I will just signify the changes. The changes won\u0026rsquo;t be done in your API but just the Nginx configuration.\nLet\u0026rsquo;s jump to coding # Configuring PM2 to keep your app running # Install PM2 with the following command -\nnpm should be installed for the following command to work.\nsudo npm i pm2 -g Then, run the following command to run your file with name index.js -\npm2 start index.js Some other commands that might be helpful (for PM2) -\npm2 show index.js pm2 status pm2 restart index.js pm2 stop index.js pm2 logs # Show log stream pm2 flush # Clear logs Also, a very important command, if you want PM2 to start on system startup automatically -\npm2 startup ubuntu # Your distribution name here If you have any problems you can run pm2 startup to get the exact instructions regarding the same.\nSetup the ufw firewall # To enable ufw, use the following command -\nsudo ufw enable Allow the rules for specific ports using the following commands -\nsudo ufw allow ssh # Port 22 sudo ufw allow http # Port 80 sudo ufw allow https # Port 443 Check the status of the service before moving on to the next step -\nsudo ufw status Installing nginx and configuring it # We will first install Nginx in your EC2 instance, it can be done through different commands for your distro. For this tutorial, I\u0026rsquo;m using Ubuntu, therefore the command will look something like -\nsudo apt install nginx After this, we have to edit the file /etc/nginx/sites-available/default using -\nsudo nano /etc/nginx/sites-available/default We have to add the following to the location part of the server block -\nserver_name yourdomain.com www.yourdomain.com; location / { proxy_pass http://localhost:3000; #whatever port your app runs on proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection \u0026#39;upgrade\u0026#39;; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } Just check the Nginx config using -\nsudo nginx -t And restart the Nginx service for the changes to take place -\nsudo service nginx restart Now, you should be able to visit your IP address with the default port (80), and it should work just fine.\nTime for setting up SSL # For this, we would be using LetsEncrypt\u0026rsquo;s certbot.\nIf you\u0026rsquo;re using any distro other than Ubuntu, take a look at this link for instructions for different OSes. If you\u0026rsquo;re using Ubuntu, you can follow along.\nFirst, we will add the repo containing the certbot scripts using -\nsudo add-apt-repository ppa:certbot/certbot Then we will update the system repo -\nsudo apt-get update Then, we will install the certbot -\nsudo apt-get install python-certbot-nginx Finally, we will call the certbot for issuing the certificate -\nNote: Before issuing the certificate, make sure that you have added an A record to your domain\u0026rsquo;s DNS records for your preferred subdomain. The A record would look something like this -\nKey Value subdomain.domain.com Your EC2 public IP address If you want to add a certificate for your apex domain, you can use www as your subdomain.\nsudo certbot --nginx -d yourdomain.com -d www.yourdomain.com Conclusion # In this tutorial, we learnt about how to make an Express webserver serve while on HTTPs with the full setup on an EC2 instance. A quick note could be, that this is recreatable on any cloud provider\u0026rsquo;s solution regardless of AWS. In the end, I would like to thank the reader for going through the article and I hope that you understood the thought process and the practical code that was written in the tutorial.\nUntil then, see ya!\nReferences # https://gist.github.com/bradtraversy/cd90 Don\u0026rsquo;t bother to check this # Answer (#8fa387) # No you can\u0026rsquo;t. You need to have a domain name for doing that.\nLet me take you back! ","date":"1 January 2024","permalink":"/posts/upgrading-an-express-server-to-https-on-ec2/","section":"Posts","summary":"A little backstory # It was a while back when I was working on one of my projects.","title":"Upgrading an Express server to HTTPs on an EC2 instance"},{"content":"","date":"30 December 2023","permalink":"/tags/age/","section":"Tags","summary":"","title":"AGE"},{"content":"","date":"30 December 2023","permalink":"/tags/beginner/","section":"Tags","summary":"","title":"Beginner"},{"content":"","date":"30 December 2023","permalink":"/tags/graph-database/","section":"Tags","summary":"","title":"Graph Database"},{"content":"Welcome to my new post, continuing from the last post, I will briefly discuss some basic operations and an introduction to graph databases.\nIntroduction # First, let’s talk about the language these databases understand. Most databases can understand more than one language, just as more than 60% of humans do. In our case, these are SQL and Cypher. Don’t worry if you don’t understand these languages, the syntax used in this tutorial is beginner-friendly and can be understood without prior experience.\nGetting Started # In the previous post, I set up our instance of Postgres and installed the AGE extension. Let’s now connect to the Postgres process through —\nusername=# CREATE EXTENSION age; username=# LOAD \u0026#39;age\u0026#39;; username=# SET search_path = ag_catalog, \u0026#34;$user\u0026#34;, public; The above three commands are used to connect with the Postgres server running in the background. The meaning of these three lines is mentioned below —\nThe first line loads an extension named age. It also creates new SQL objects. The second line loads a shared library file (a.k.a the extension) in memory. The third line sets an environment variable search_path to ag_catalog. This serves the same purpose as appending the schema name to all the functions you use from the AGE extension. Now that you have installed and loaded all the stuff, it’s time to learn some basic syntax about graph databases.\nBasic Coding # Creating a graph # To create a graph, the following command can be inputted on the server —\nusername=# SELECT create_graph(\u0026#39;scan\u0026#39;); The above command creates a graph named “scan” containing no vertices and edges.\nCreating a vertex # The next thing to implement is the creation of vertices. Vertices can have labels. Labels are text associated with a vertex for conveying extra information about it. They are helpful in different conditions, like, representing vertices with the types of people based on income levels as labels. Let’s see a sample query and understand it thoroughly —\nusername=# SELECT * username=# FROM cypher(\u0026#39;scan\u0026#39;, $$ username=# CREATE (field) username=# $$) as (v agtype); Notice the multiple lines of the query. In the Postgres server, a query is not accepted until you end it with the delimiter “;”.\nLet’s dissect the query in four lines and understand it one-by-one —\nSELECT * is used to select the data in the database. “*” here represents everything. FROM cypher('scan', $$ is used to point to the graph that we are using. We use the cypher() function for the same. It takes two parameters — the graph name and the cypher query. Also, note that the cypher query starts and ends with $$. CREATE (field) is used to create a vertex, where the name of the vertex is field . A quick tip here — Multiple vertices can be created through the modified query: CREATE (n), (m) . $$) AS (v agtype); is used to return the result as agtype . Here the rows will be returned under the heading v . Note that, AGE only returns agtype as the return value.\nThe next task would be to create a vertex with a label on it. The query would change a little bit and is as follows —\nusername=# SELECT * username=# FROM cypher(\u0026#39;scan\u0026#39;, $$ username=# CREATE (field:offside) username=# $$) as (v agtype); Notice the “:offside” attached to the end of vertex name. That specifies the label.\nCurrently, the AGE project doesn’t support the definition of multiple labels for a single vertex. For that particular use case, we could use something called property.\nCreating properties # Properties are key-value pairs through which the vertices store information about them. Below is the example code for the same —\nusername=# SELECT * username=# FROM cypher(\u0026#39;scan\u0026#39;, $$ username=# CREATE (field:offside { elevation: 1.5 }) username=# $$) as (v agtype); Notice the additional “{ elevation: 1.5 }” part. That part specifies the properties associated with the vertex. We can add additional properties by just appending and comma-separating them within the brackets.\nThe last thing to cover in this introductory guide is how to display the graph / visualize it.\nDisplaying the graph # Below is the query to display the graph. Don’t worry if you don’t understand it, I will further dissect it and make you understand.\nusername=# SELECT * FROM cypher(\u0026#39;scan\u0026#39;, $$ username=# MATCH (v) RETURN v username=# $$) as (v agtype); The first and last statements are already explained above. I will explain the second statement below —\nMATCH(v) RETURN v returns all the nodes in the database.\nThe MATCH() function actually matches a pattern. In this pattern, we defined only node names and not any labels, which in turn will return all the nodes.\nConclusion # That’s it for this tutorial! I know I have skipped some parts of the basic coding, but I will cover it in the next post, so stay tuned.\nUntil then, see ya!\n","date":"30 December 2023","permalink":"/posts/graph-databases-101/","section":"Posts","summary":"Welcome to my new post, continuing from the last post, I will briefly discuss some basic operations and an introduction to graph databases.","title":"Graph Databases 101: A Beginner’s Guide"},{"content":"","date":"1 January 0001","permalink":"/authors/","section":"Authors","summary":"","title":"Authors"},{"content":"","date":"1 January 0001","permalink":"/categories/","section":"Categories","summary":"","title":"Categories"},{"content":"","date":"1 January 0001","permalink":"/series/","section":"Series","summary":"","title":"Series"}]