This post is translated from its original version in Spanish. As I'm not a native English speaker, I apologize in advance for any mistake I can make.
Maybe some of you are using the Github students pack offer and have rented a VPS at DigitalOcean (by using the cheapest configuration you can enjoy a simple VPS for free for almost two years), but after renting it, the next question is... And now WTF am I supposed to do with it?
I've been using Markdown when taking my class notes for so long, because I'm able to:
- Have my notes in an easily Internet-exportable format
- With an editor like atom I can see them rendered in real time (although I use Vim/Emacs)
- As they usually contain code snippets, I'm able to have syntax highlighting in lots of platforms
Until now, I had a copy of the .md files at my Dropbox (lately at my Owncloud), and time to time I had to export from .md to .html, and then upload them via FTP to the correct folder at the VPS... As you can see, it's a tedious work.
Be engineer. Be lazy
As good engineers, we need to use those technology wonders, called computers, that were created in order to avoid us doing those repetitive tasks.
I had even created a bash script that automated the .md -> .html generation, but the uploading part was still missing. Also, it would have been great uploading only the files that had changed... Oh wait.
That sounds like a great task for git.
Git + Jekyll to the rescue
Once I had decided that the best choice for uploading files would be using git, the only thing missing was automating the .html generation from the .md files (that is, if we are going to be lazy, let's be veeery lazy).
I searched and tried some static code generation tools, but I finally decided using Jekyll, which is generally oriented to blogs, but one of the goods of its layout system is that, literally, you can tweak it in any way you want (ie: using categories for subjects).
After messing around a little with Jekyll, finding a decent theme, adapting it to my needs (and learn that you don't need to run
jekyll serve permanently, only
jekyll build) the only thing remaining was to create and configure the git repo.
Let's get started
I am not an expert in git nor in Unix systems, so I'm just going to explain how I solved my problem, being conscious that of course there will be thousands of better solutions
I will suppose you have the git tools installed and configured.
After this little comment, here it comes the first suprise in this post: You won't be creating one but two repositories. How does that feel?
That's why: if we initialize a git repository with
git init, if we are on
MASTER branch and we make a push via
git push origin master it will complain, because if we initialize it with
git init, git will save an active working copy with the repository.
In other words, you will also have a physical copy of the files contained in the repository.
In order not to happen, you have two choices:
- Change branch before and after making a push (which of course is silly)
- Create the repository by
git init --bare
If we create the repository marking it as bare, we won't have that physical copy of the files (that in our case would be necessary in order to work with them (aka convert them to html)), so it seems that this also does not solve our problem, right?. Let's see how this actually will save our lifes.
The part where commands appear
Now I'm going to explain step by step how I ended up configuring my git server
Creating the git user
By SSH-ing into the server, we will create a new user called
git, assign it a password and create its directory at
sudo useradd git sudo passwd git sudo mkdir /home/git sudo chown -R git /home/git
Adding SSH keys
We will need to add our SSH key to the file located at
If you don't know how to do it, I recommend you reading this tutorial at DigitalOcean that explains it perfectly.
Creating the main repository
Once we are able to SSH as the git user we will create a bare repository that, as we said earlier, will not have a physical copy of the files.
It's recommended not to place it in the same folder we will be showing our public content, so I've decided to place it at
All the following commands will be run as the git user
cd ~/ mkdir apuntes.git cd apuntes.git/ git init --bare
After running these commands, we can see that the
apuntes.git folder has all the files that in any other git repo we could have found inside the
Accessing the repository from our computer
In order to check if we are doing okay, from our current computer let's try to clone the repository:
git clone git@[myserver.com]:/home/git/apuntes.git
In order to avoid complications, I've decided to write the full path.
As you can see, after the
[myserver.com] (which you will have to replace), you append a
: and add the full path to the repository.
If all works as it should, you should get a message saying that you have cloned an empty repository.
It you get it, congratulations!
Now, also in your current computer, try to add a local file (whatever you want. ie:
hello.txt) and run:
git add . git commit -m 'First commit' git push origin master
And if you don't get any error, it means that all is working perfectly.
After installing Jekyll's gem (I won't explain how to install a gem nor how to use Jekyll, as that's not the main point of this post) we will place our Jekyll site wherever we wont.
In my case, I decided to track only the
_posts folder, as I'm pretty satisfied with the theme I've modified and I'm not changing anything of it, nor editing any of the configuration files.
So by now, we will access our posts folder (as an example I will use the path
Once we are placed in our
_posts folder, we will run
git init and add the main repository as a remote:
git remote add origin /home/git/apuntes.git git pull origin master
If all is working well, we should see how in our
_posts folder now we can find the file we had previously uploaded from our local computer.
Now we only need to create the content from our current computer, make a commit, push it to the git server, and any time we push something, ssh into our server, go to our
_posts folder and run
git pull origin master . And of course, generate the content with
This is something that, obviously, we are not going to allow. We want to be lazy!
The power of the hooks
Git provides a very powerful tool called
hooks. Those hooks are scripts that will be executed whenever some conditions happen at the repository.
As in our case we will need to execute some actions every time the repository gets updated, we will use the
In order to do it, we will go to the
hooks directory placed at
/home/git/apuntes.git/ and create a file called
post-receive with the following content:
#!/bin/sh unset GIT_DIR cd /var/apuntes/_posts git pull origin master && cd /var/apuntes && jekyll build
Once we've created it, we will need to give it execution permissions:
sudo chmod 755 /home/git/apuntes.git/hooks/post-receive
If we are lucky and everything is working correctly, whenever we make a change in our current computer and push it to the main repository, we will see how in the
git push output it shows the static content generation made by Jekyll (useful for detecting errors).
The final step
Now you only need to configure the access to the web site.
In order to do it, you only need to link your website to
/var/apuntes/_site/. And as we have delegated the static content generation to Jekyll, and automated the generation to every time it get's updated, the content served will always be the last available.
Of course, if you want to keep the content protected, you only need to add a Restriction Policy via an
.htaccess, but again, that isn't the main point of this post.
I hope this merge of things that aren't usually related will be useful for someone.