Subscribe to our YouTube Channel!
[Jul 12, 2021] New Video: How to Use Django Rest Framework Permissions (DRF Tutorial - Part 7)

Ask Vitor #4: WordPress or Self-Made Blog?

Ask Vitor #4: WordPress or Self-Made Blog?

Aviral Tiwari asks:

Is this blog made through Django or some blog engine like WordPress?


First of all, thanks Aviral for the great question!

The short answer is Jekyll + Django. Now, if you are interested in a little bit of the history of this blog and the technology stack behind it, keep reading!

This blog is powered by Jekyll, a static site generator written in Ruby. All the pages, all the HTML you see is managed by Jekyll. But at some point this year I had to create a small API using Django to provide a few services and enhance the user experience. So, it’s a little bit of a Frankenstein code.

The reason why I initially picked Jekyll was that I had no intention to write on a regular basis and honestly I did not expect the blog to grow as much as it did. Right now, the blog receives roughly 130,000 visits every month, and it has been such a great experience – writing articles, interacting with the readers, reading comments, starting discussions.

Anyway, Jekyll was a very convenient option, because you can host it using GitHub pages. So, all I needed was a domain name, and I didn’t have to bother about hosting.

It’s still holding up pretty well. The pages load fast enough. After all, it’s almost like having a fully cached website. The requests don’t touch the database, no code being executed, just serving plain HTML pages. The publishing process works pretty well. But as the blog grows, adding more articles and pages, functionalities like “Related posts” and “Read time,” it constantly keeps increasing the build time. Nowadays it’s taking 15~ seconds to build the source code into the website you see right now.

I wish I had started the blog using WordPress. I mean, it’s a good framework. Lot’s of websites are using it, it’s simple to get started, tons of helping material and tutorials on the Internet. It’s a great publishing tool. And after all, it’s not about using Python and Django for everything. It’s about using the right tools for the right problem.

Many of the things I had to do by hand regarding SEO, the organization of the blog content, templates, plugins you would get out-of-the-box using WordPress.

I started the blog using Jekyll, hosting on Github. Then at some point, I moved it to DigitalOcean so to have more control over the blog. This way I could serve it using https only and add some other features to it.

I like the DigitalOcean service; I’ve been using it for more than three years now. It’s very simple to setup, and I find it very inexpensive. I’ve been running the blog on its tiniest VPS (which costs U$ 5,00 per month) with no problem at all, and as you can see, the blog runs very smoothly. I’ve written a blog post about it, if you are interested in knowing more about Django deployment using DigitalOcean, you can read it here, or if you want to get a U$ 10,00 free credit on DigitalOcean, you can sign up using my referral link.

Technology Stack of the Blog


Responsible for generating the static website, converting the posts which are written using Markdown (actually it’s kramdown) into HTML pages using the templates I created.

Along with Jekyll, I use the following Ruby gems:


As I mentioned at the beginning of this post, at some point, I had to create a small API using Django to help me handle some of the features of the blog to make it more dynamic and also to help me automate a few tasks, such as its deployment.

Bubbles from Dragon Ball Z

This was when Bubbles was born – my Django powered helper. I named it after the monkey that helps King Kai’s on the Dragon Ball Z anime.

Among other duties, Bubbles is responsible for:

  • Deploying the website when I push new code to a specific branch of my Github repository;
    • It involves waiting for a webhook call from Github;
    • Pulling the new code on my DigitalOcean server;
    • Building the Jekyll website;
    • Testing if the build was successful;
    • Updating the public directory where NGINX serves the website;
  • Consuming the Google Analytics API to grab the page views data I display in the posts;
  • Consuming the Disqus API to generate a list of last comments displayed on the homepage;
  • Processing the questions forms submitted in the Ask a Question page and sending the emails to the person who sent me the question and notifying myself.
  • Validating the Google Invisible Recaptcha in some pages.

He lives under the /api/ URL. I instructed NGINX to serve all the requests except those URLs under /api/. Those requests are delegated to my Gunicorn workers that pass the tasks to Bubbles so he can do his thing.

Below is what part of my NGINX server block looks like:

server {


    location /api/ {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_redirect off;
        proxy_pass http://bubbles_web_server;

    location / {
        try_files $uri $uri/ $uri.html =404;

Back in the days, I used to be good with CSS. But nowadays with all the Bootstrap stuff around I got lazy and rusty. I wanted to play around with the CSS a little bit, so I decided to use Skeleton boilerplate and build my CSS on top of it. The result is what see right now.

Basically what I use in the client-side:

Other Resources

I also use PostgreSQL and Memcached in the web server because some of the APIs I consume have rate limit per hour and also to make the access to the data faster.

Other than that I have a Travis CI setup that builds the blog upon every push; it checks the Jekyll build, search for broken links and check the HTML structure (if there are any broken tag, an img tag without the “alt” property and so on).

For writing, I use my favorite text editor which is Sublime Text 2. I have a few macros and snippets for creating the code snippet tags I frequently use in the posts, and I also have an English spell checker.


I hope you enjoyed reading this post and finding out more about the underlying technologies that run this blog.

I intend to move away from the Jekyll at some point. It’s great, but as the blog grows, it starts to get a little bit challenging to keep developing and writing with it. I thought about moving to WordPress, but I wanted to take the opportunity to create a Django project from scratch, and as I develop it, create a series of posts explaining the whole process.