Hosting with Linode & SSL

Rahul Ravindran
6 min readApr 27, 2020

--

This story is about me migrating my personal blog from Github to self-hosting on Linode. I thought it made sense to not host this on GitHub anymore because the value of it being done for free made me write less. If maintaining my personal website cost me money, I figured it would make me write more. This rant is about how to go about setting your own blog/website on Linode.

Why Linode

There are multiple hosting providers out there and I choose Linode mainly because of the cost and the hardware resources it provided me along with it. Currently, t2 micro instance on AWS would set me around `$9.50` with 1GiB of RAM. With a 10$ fixed rate per month, I can get 2GB of RAM and 50GB in storage for Linode. I could go with a nano instance on AWS and save quite a bit, but I occasionally like to code with my iPad. So, having a decently sized box would be beneficial.

Linode has pretty decent documentation for hosting your website. They do have issues with some steps along the way, So this guide will probably help you avoid the pitfalls. Once you have registered on Linode, spin up your instance (preferably close to where you live). *Pro Tip:* setup ssh keys so you can easily jump into your box without needing to input your password.

$ssh-keygen -t rsa

This command should generate an ssh key (use a passphrase for extra security) which you can add in Linode manager when you spin up your instance.

Purchasing your domain & Setting up DNS A records

You now have your instance spin up, but before moving ahead — you need to purchase your domain. Once, you have purchased this — you need to let your domain provider know which Nameservers to use. This is used later for DNS resolution. Follow this guide here to get the list of Nameservers you need to use for Linode.

You are not done yet since there is more to DNS than meets the eye. For now, your browser knows which nameservers to connect to when someone goes to <your_domain>.com but you have to setup an A record to let the nameservers know which machines your files are on. This is where your public IP for the instance you spun up is useful. This guide explains how to do this on Linode. Pro Tip: Leave hostname as blank for one record if you wish to proxy <your_domain>.com correctly without www. The guide has an example for www. If you’re lazy about it — just put * along with the blank option — to route all subdomains and <your_domain>.com.

This step is the most time-consuming. It takes about 24 hours for the DNS resolution to take place for your nameservers or worse case — 48 hours. On the other hand, A record resolution takes around 2 hours. Once you’re done with this — you can head to the next section to bootstrap your server and serve your website.

Apache Web Server and SSL

While you’re waiting on your DNS resolution to complete, you can go ahead and bootstrap other bits on your Linode box. I choose Apache server here but you can also use the popular option — Nginx. Frankly, I would prefer Nginx here since it should be more light-weight for static websites. Here’s the guide for doing this on an Ubuntu box. I skipped the part about setting up databases since I don’t require it. There’s also a guide for Nginx there, so you can follow that if you choose that.

Setup a sample index.html page containing Hello World at /var/www/html/example.com/public_html, so you can test out apache settings by doing curl -X GET localhost:80. The next bits of steps involve waiting for the DNS resolution to take place. You can use dns-checker and verify for both A record check and nameservers check. Once nameservers resolve, A record should also resolve pretty soon.

Once you have all the bits above working — you can use lets-encrypt to get yourself ssl certificate. Follow this guide here to get yourself an SSL certificate. Pro Tip: stop apache2 service because lets-encrypt cannot have anything bouund to port 80 while it’s issuing the certificate. The command should spit out both the certificate and the private key you need to setup rest of apache configs.

You will likely run into a problem before all of this. Once, DNS resolution finished it should be possible for you to check your website using your browser. If you followed this guide — you should have the hello world page display up. You will need to use http for now since we haven’t added the settings in apache to enable ssl yet.

If not, you need to setup your ip tables to accept traffic on two ports 80 and 443. 80 will be used for HTTP traffic and 443 for HTTPS.

$ sudo iptables -A INPUT -p tcp -m multiport — dports 80,443 -m conntrack — ctstate NEW,ESTABLISHED -j ACCEPT$ sudo iptables -A OUTPUT -p tcp -m multiport — dports 80,443 -m conntrack — ctstate ESTABLISHED -j ACCEPT

The commands above should open up the connections to these ports. So far, what we have is:

  • when someone opens up your website on the browser, it contacts your nameservers (Linode).
  • Based on the A/AAAA records setup, the nameservers resolves which machine to route the request to.
  • IPTABLE command you setup should allow all HTTP and HTTPS connections to your machine.
  • lets-encrypt should have granted you certificates to verify your secure HTTPS connection

The final bits you need to do is follow this guide to enable HTTPS connection on your apache server. If you followed this guide until now — you should have your website setup on the Linode machine you spun up. The output command from lets-encrypt will have the private key and certificate information you need to use for SSLCertificateFile and SSLCertificateKeyFile in the config.

Building your static website

Let’s now look at the final piece of the puzzle. Static website generator are available on the web and the easiest IMO to use is what Github uses for static websites. Jekyll is pretty easy to setup and some templates use markdown to create blog posts. My personal blog outside of Medium is done using it. You can take a look here. Here is a good example to follow. bundle exec jekyll build generates all the necessary resources in _site folder within your working directory. This directory contains all the files you need to put in your apache webserver to host your website.

So, the next part of the blog talks about how I ended up automating this workflow for now. I haven’t used the actions flow yet in Github but have a fairly vague idea of how I would go about doing this. For now, this is done through a script and I will give this recipe out before using Github actions in another post. I love Makefiles and for I am going to use that here.

The most common actions I end up doing is build, clean and serve so I set this up as Makefile recipes

The important recipe here is deploy. Here, I’m saying in order to execute this recipe — we need to execute build first and depend on the folder _site to exist. The rest of the workload is now managed by a shell script. The script looks something like this:

Comments in the code should help you tell what I am doing. This is a fairly simple script that does some barebones folder manipulation to get the job done. This is all I have for now, I might come up with a new blog post to see how Github actions fare and if I can manage to do this entirely in Github itself. The main challenge here is to ensure I have a less privileged user when ssh(ing) from Github workflow. From past experiences, I have found it easier to build workflows in Makefile and move this to automated workflow like jenkins or any other build system like Travis, CircleCI.

This story is a copy of my blog article @ soupynoodles.dev. Check out my personal website for more frequent updates.

--

--

Rahul Ravindran
Rahul Ravindran

Written by Rahul Ravindran

Software Engineer | Gamer | Soccer | Tennis | Drone Enthusiast | Follow me @ https://soupynoodles.dev

No responses yet