Setup Your Personal Site From Scratch Using Linux, Apache And Jekyll
Like I promised in my
last post
, this is going to be a comprehensive tutorial to get your site up and running on a VPS. It is assumed
that you already have root access to a VPS running Linux ready and also have registered www.example.com
.
If you haven’t and want to, check out DigitalOcean for cheap a VPS and
NameCheap for a domain.
And to go lashing out our linux-fu, please make sure you know the basics of some command line plaintext
editor such as vi
, emacs
, nano
, etc
Introduction to Some Basic Terminologies
Before we jump into the terminal and get our hands dirty, I’d like to familiarize you with the basics of
how a website works. Let’s assume that your domain is www.example.com
. Now, when someone types this in their
favourite web browser and hits go, what happens? What happens can be broken down as follows:
- Your browser requests the landing page of
www.example.com
to the host ofwww.example.com
by translating the domain name using a DNS (domain name system). - The remote server receives the request, does some processing, and sends the requested page back to you.
- The requested page arrives at your device and the browser displays the page as per the HTML code of the page.
Our interest is in step two of this process, i.e., listening for incoming requests by clients for webpages, processing their requests and then serving them the requested page(s). The program that does this is called a webserver. A webserver uses the HTTP/HTTPS protocol in the application layer to do this. There exist a variety of webservers around - Apache, Nginx, IIS, GWS., etc.
The webpages that the webserver serves may be either generated statically or dynamically. The difference between the two is that in case of dynamic webpages, they have to be rebuilt everytime they’re requested whereas in case of static webpages the pages are generated just once and are served without rebuilding. We are going to build a static website because it’s elegant, faster and efficient. Thus, we’ll be also needing a static site generator too.
Which Tools Will We Use?
We are going to use a VPS running Linux, Apache for the webserver and Jekyll as the static site generator. The popular choices of Linux distros for servers are Fedora, Ubuntu, Debian, CentOS, OpenSUSE, RHEL, etc. The choice doesn’t really matter much since Apache and Jekyll are available for all popular distros. I’d advise you pick either Ubuntu or Fedora.
I’ll be demonstrating all commands for Fedora. Exact usage may vary for other distros.
How will our site work, you ask? You see, we’ll setup Apache and configure it properly to receive incoming HTTP requests on port 80 of the server. We’ll also add a repository to which we can push our site’s code using git version control. By using a post receive hook that automatically builds the code using Jekyll and copies it to the document root of Apache, we take your site live within seconds of pushing to the repository! Back on our local machine, we’ll create a simple Jekyll site that will be pushed into the VPS’s repo which was setup previously.
But before doing any of this, it’s important that you make www.example.com
point correctly to your
VPS’s IP address and configure it properly. If you already know how this is done, skip the next section.
If not, then fret not and read on!
Making www.example.com Point to your VPS
To do this first go to your domain name registrar’s site and access the control panel for managing your domain. Make it point to the nameservers of your VPS provider and then create the A records.
The nameservers for your VPS can be found on your VPS access control panel. They typically look like
nsx.myvpsprovider.com
. Make your domain name point to the nameservers from the domain control panel
and create A records for www
and www.examle.com
.
Now that this is done, it should take some time (from a few minutes to upto 24 hours) until all cached copies of DNS records are updated to reflect this change.
Configuring Your VPS to Run Apache
Apache is the most widely used webserver that’s out there. Hence it’s available in most Linux distros’ package repositories. Install Apache:
# dnf install httpd
Before running and testing the webserver, we need to make sure that HTTP requests on port 80
are allowed to pass through the firewall. There’s a wonderful tool called iptables
that is made for
managing the firewall and traffic through it.
Go ahead and install the iptables-services
package.
# dnf install iptables-services
To enable the iptables
service to start automatically on boot and also to start it, do:
# systemctl enable iptables
# systemctl start iptables
Next, save the current runtime rules of iptables
(to etc/sysconfig
) by doing:
# /usr/libexec/iptables/iptables.init save
One last thing remains is to allow HTTP traffic so that requests can reach our webserver:
# vi /etc/sysconfig/iptables
In the rules file, just add this line:
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
After all this is done, the VPS’s firewall has been configured to allow HTTP traffic through port 80.
We can now tell Fedora to start Apache on boot and also start the Apache daemon.
# systemctl enable httpd.service
# systemctl start httpd.service
Now if you visit www.example.com
using your browser, you’ll be greeted by a sample Apache Foundation
webpage. This means Apache has been installed and is ready to be configured.
Configuring Apache
The configuration file of Apache resides in /etc/httpd/conf/httpd.conf
. We will now tailor it to suit our
needs.
Open the httpd.conf
file:
# vi /etc/httpd/conf/httpd.conf
First, we’ll tell Apache which IP it will listen for HTTP requests. Replace xxx.xxx.xxx.xxx
with
the IP of your server.
Listen xxx.xxx.xxx.xxx
Then find the ServerAdmin
and ServerName
sections and update them with your email and domain name.
ServerAdmin [email protected]
...
ServerName www.example.com
Next, locate the <Directory />
block and make it like so:
<Directory />
AllowOverride FileInfo
Require all denied
</Directory>
What we just did is tell apache that the contents of the root of the webserver should not be openly
accessible to the outside world. We also set AllowOverride
to FileInfo
from the default Non
as
we want to be able to use the ErrorDocument
directive for configuring custom error pages.
All the other configuration options can be safely left to their default values for now.
Installing Jekyll
Jekyll has to be installed on both your VPS and also on your local machine; the Jekyll installation on the VPS will build the entire site everytime you push ay changes to it and the local Jekyll copy will help you build and design your site.
Jekyll is written using Ruby. Hence, we’ll be using the Ruby package manager called RubyGems to install all dependencies of Jekyll and Jekyll itself.
Install Ruby and RubyGems:
# dnf install ruby rubygems
Now, install & update Jekyll:
$ gem install jekyll
$ gem update jekyll
Making a Simple Jekyll Site
After you’ve installed Jekyll on both the VPS and your local machine, it’s finally time to run Jekyll and build our site!
Jekyll works by converting markdown into HTML files based on the configuration you set. Since this post is not going to be a comprehensive Jekyll gide by itself, you are encouraged to take a look at the official Jekyll docs which is as beginner friendly as it can be.
On your local machine, go into the directory of your choice and create a new Jekyll site.
$ jekyll new mysite
This will create a new folder called mysite
in the present working directory with bare minimum Jekyll
configuration.
Go into foo
to build and test the default Jekyll site.
$ cd foo
$ jekyll build
$ jekyll serve --watch
Now, head over to http://localhost:4000
and you should see your first ever Jekyll generated site!
This bare minimum default theme is called Minima, BTW.
Let’s take a look at the contents of mysite
directory. You will find that a lot of subfolders and files
have been generated. The file called Gemfile
is responsible fot bundling required Jekyll dependencies
when a new site is being created. Aadvanced users usually use the Ruby gem called bundle
with Jekyll
to create a Jekyll site based upon their configuration choice.
Next in line is _config.yml
, which contains Jekyll configuration options. Typically,
it look likes this:
title: Title of MySite
email: [email protected]
description: > # this means to ignore newlines until "baseurl:"
Welcome to MySite! I'm MyCoder! Nice to Meet ya.
baseurl: "" # the subpath of your site, e.g. /blog
url: "http://example.com"
twitter_username: mytwitterhandle
github_username: mygithubhandle
# Build settings
markdown: kramdown
theme: minima
gems:
- jekyll-feed
exclude:
- Gemfile
- Gemfile.lock
Update the relevant parts of the config file with your personalized info. Know that
you have to use exactly two spaces for indentation at the beginning of each line
in the _config.yml
file. Else your changes won’t be recongnized by Jekyll!
The individul pages of our site are in markdown format (end with .md
) extension
prior to Jekyll working its magic. Open about.md
and notice the header of the file.
It should be something like this:
---
layout: page
title: About
permalink: /about/
---
This is called the front matter which is necessary in any page that you want Jekyll to churn. Jekyll will only process and generate files with the front-matter.
All that remains to touch about Jekyll is the blog section. Blogging is what Jekyll
was built in the first place. To create a new post, just add a file with the naming
convention yyyy-mm-dd-your-title-goes-here.markdown
. Don’t forget to add the relevant
front-matter that Jekyll uses for blog posts:
---
layout: post
title: "Your Title Goes Here"
date: YYYY-DD-MM HH:MM:SS
categories: tag1 tag1 tag3 tag4
---
Notice how the about page uses the layout called page
and the blog post uses a layout
called post
. Layouts are one of the many powerful features of Jekyll. You can define
multiple custom layouts that can be shared by similar pages, e.g., the page
layout
might be shared by the home, about and projects page whereas the post
layout is used
by blog posts.
Lastly, the _site
directory is where Jekyll puts the static HTML files after processing
the markdown files we supplied it. The contents of _site
has to be copied to the document
root of Apache everytime we update our site and build it.
NOTE:
The baseurl
and url
fields should be properly set to the url you want your site
to be accessible from. Typically, url
will be set to www.example.com
and baseurl
will be set when you want your site to be accessible as a subpath of url
. Make these
changes everytime before pushing to the repo on your VPS or else your site won’t work
properly.
We will now create a remote git
repo to track and push our changes to the main repo
on the VPS (which we will create in the next section).
$ git init
$ git add .
$ git commit -m "Initial commit"
Taking Your Site Live
Just one last step remains to go live! We now have to create a bare git
repo on the VPS
and configure the repo to build the site everytime you push into it and copy the generated
site to the document root.
Switch to a comfortable place in your VPS where you’d like to place the repo and then create the repo.
$ cd /path/to/repo/dir/
$ mkdir mysite.git
$ cd mysite.git
$ git --bare init
So far so good. Now if you push your changes to this repo from your local machine, the changes
will be updated to this repo, but your site won’t be updated; it needs to be built by Jekyll and
the contents of the _site
folder have to be copied to the document root (/var/www/html
).
To do that, we’ll now create a git post-receive hook.
$ cd hooks
$ cp post-receive.sample post-receive
$ vi post-receive
We just copied the sample post-receive
script supplied by git
, which we’ll now configure.
GIT_REPO=/path/to/repo/dir/mysite.git
TMP_GIT_CLONE=$HOME/tmp/mysite
PUBLIC_WWW=/var/www/html/
git clone $GIT_REPO $TMP_GIT_CLONE
jekyll build -s $TMP_GIT_CLONE -d $PUBLIC_WWW
rm -Rf $TMP_GIT_CLONE
exit
We also need to give this post-receive
script executable rights.
# chmod +x post-receive
To enable the non-root user, using whose rights this script will be run,
to have write access to the document root (/var/www/html
), add them to
the apache
group.
$ sudo usermod -a -G apache <username>
Let’s go back to your local machine now. Since we’ve already commit our changes, all that needs to be done is push our changes, sit back and watch!
$ git remote add <vps-deploy-alias> ssh://<username>@<vps-address>:/path/to/repo/dir/mysite.git
$ git push <vps-deploy> master
That’s it! You’ve done it! Head over to www.example.com
and if you’ve followed this post correctly,
you’ll be greeted by your very own pseronal webpage!
Troubleshooting
TO DO
References
- DigitalOcean article on configuring a VPS:
-
Apache HTTP Server Documentation:
http://httpd.apache.org/docs/2.4/ - Jekyll Documentation:
https://jekyllrb.com/docs/quickstart/