Looking Back and Looking Forward

Looking back at 2018

With respect to work…

I switched the workplace from Srivilliputhur to Madurai, from BSNL broadband to Airtel broadband, from ADSL to VDSL. I have had a lot of downtimes with BSNL last year. Fortunately, I had JioFi, as a backup, at that time (I was one of the early adapters of Jio 4g in general). However, as more users joined Jio 4g network, the overall speed reduced after each passing month. I used Airtel around 10 years ago (when Airtel had only ADSL), when I was in Madurai. Never had any issue with Airtel.

I still go home (to Srivilliputhur), mainly on weekends, primarily for trekking on Saturdays. Srivilliputhur has one of the best places for trekking and it allows us to be closer with the nature, that in turn helps me to sharpen my saw at work. Trekking is allowed only on weekends. So, I still use BSNL broadband at home, along with JioFi as a backup. At work, I solely rely on Airtel broadband for now. However, I might opt for ACT Fibernet at any time in the near future. The main caveat with ACT Fibernet is that they only offer shared public IP and they use double-NAT. Their network isn’t reliable in general, either. The packets are lost at random. Their customer support isn’t as good as Airtel’s, to solve any technical issues. So, I might use it only for heavy downloading and uploading, not for series work.

Apart from the change in workplace, I bought the following items to improve my workflow…

Mikrotik router/s: I bought two hAP ac2, one for work and another for home. In general, Mikrotik products are hidden gems. They offer enterprise grade hardware (and software) at a nominal rate. I already use the work router as a VPN server to connect to it whenever I am away from work. I plan to use both routers as load balancers with automatic failover. If you’d like to know more details on how to achieve this, look forward to more detailed info at my tiny web page blog.

Jabra Elite 65t: To speak with more clarity when on call with clients. It has 4 mics, btw.

BenQ GW2480 monitor: Initially, I bought it to have it for the dual-monitor setup. But, it ended-up on its own desk and computer at home.

Raspberry Pi: I bought Raspberry Pi 3 Model B+ (with NoIP camera), mainly to remove ads from my network using home based pi-hole.net server. I already use pi-hole for BSNL. With BSNL, it is easy to filter the IP range. With Airtel, the range was widespread. So, I quickly turned to Raspberry Pi for help. It works well as a simple pi-hole.net server.

Looking forward to 2019

My wishlist or goals for 2019 are…

  • Writing regular blog posts, at least once per month.
  • Sharing more of my thoughts and tips through social media.

Nothing more for now. I’d like to keep it simple so that they could be accountable when I look back at my goals at the end of the year.

Brotli on Nginx

Brotli compression was introduced by Google, exactly 3 years ago. It is yet to come by default with the standard Nginx packages of OS vendors or the official Nginx repo. Google maintains its own repo for brotli support on Nginx web server. However, it’s been two years since we had the last commit. Fortunately, a Googler, named Eugene Kliuchnikov, continues to develop a fork of Google’s repo. There are even plan to merge both repos. Still, there isn’t an easy way to compile Nginx from source.

While searching the internet for any existing solutions, I found a couple of excellent solutions.

Both provide step by step guidelines on how to compile Nginx from source, along with brotli compression support. Since, I like to automate things, I put together all the steps mentioned by the above articles and created a single script that does the following…

  • Compiles Nginx from source with brotli support
  • Removes any existing installation of Nginx
  • Installs the new Nginx version (with brotli support, of course)
  • Starts or restarts Nginx

Here’s the complete code…

#!/usr/bin/env bash

# use it while developing / testing.
# you may use it in production as well.
# set -o errexit -o pipefail -o noclobber -o nounset
# set -x

# compile Nginx from the official repo with brotli compression

[ ! -d /root/log ] && mkdir /root/log

# logging everything
exec > >(tee -a ${log_file} )
exec 2> >(tee -a ${log_file} >&2)

# Defining return code check function
check_result() {
    if [ $1 -ne 0 ]; then
        echo "Error: $2"
        exit $1

export DEBIAN_FRONTEND=noninteractive

printf '%-72s' "Updating apt repos..."
apt-get -qq update
echo done.

printf '%-72s' "Installing pre-requisites..."
apt-get -qq install dpkg-dev build-essential zlib1g-dev libpcre3 libpcre3-dev unzip
echo done.

codename=$(lsb_release -c -s)

# function to add the official Nginx.org repo
nginx_repo_add() {
    distro=$(gawk -F= '/^ID=/{print $2}' /etc/os-release)
    codename=$(lsb_release -c -s)
    if [ "$codename" == "juno" ] ; then

    if [ "$distro" == "elementary" ] ; then

    [ -f nginx_signing.key ] && rm nginx_signing.key
    curl -LSsO http://nginx.org/keys/nginx_signing.key
    check_result $? 'Nginx key could not be downloaded!'
    apt-key add nginx_signing.key &> /dev/null
    check_result $? 'Nginx key could not be added!'
    rm nginx_signing.key

    # for updated info, please see https://nginx.org/en/linux_packages.html#stable
    nginx_branch= # leave this empty to install stable version
    # or nginx_branch="mainline"

    if [ "$nginx_branch" == 'mainline' ]; then

    [ -f /etc/apt/sources.list.d/nginx.list ] && rm /etc/apt/sources.list.d/nginx.list
    echo "deb ${nginx_src_url} ${codename} nginx" > /etc/apt/sources.list.d/nginx.list
    echo "deb-src ${nginx_src_url} ${codename} nginx" >> /etc/apt/sources.list.d/nginx.list

    # finally update the local apt cache
    apt-get update -qq
    check_result $? 'Something went wrong while updating apt repos.'

case "$codename" in
        echo "Distro: $codename"
        echo 'Warning: Could not figure out the distribution codename. Continuing to install Nginx from the OS.'

cd /usr/local/src
apt-get source nginx
apt-get build-dep nginx -y

git clone --recursive https://github.com/eustas/ngx_brotli

cd /usr/local/src/nginx-*/
# modify the existing config
grep -wq '--add-module=/usr/local/src/ngx_brotli' debian/rules || sed -i -e '/\.\/configure/ s:$: --add-module=/usr/local/src/ngx_brotli:' debian/rules

# build the updated pacakge
dpkg-buildpackage -b

# optional
# install the updated package in the current server
cd /usr/local/src
dpkg -i nginx*.deb

# take a backup
[ ! -d ~/backups/ ] && mkdir ~/backups
mv nginx*.deb ~/backups/

# remove all the sources and apt sources file
cd ~/
rm -rf /usr/local/src/nginx*
rm -rf /usr/local/src/ngx_brotli
rm /etc/apt/sources.list.d/nginx.list
apt-get -qq update

# hold the package nginx from updating accidentally in the future by someone else!
apt-mark hold nginx

# stop the previously running instance, if any
nginx -t && systemctl stop nginx

# start the new Nginx instance
nginx -t && systemctl start nginx

This has been made as a Github repo for Nginx Brotli compression. Please check it out for updates and support.

Please remember that Brotli is a new standard (even though, it is 3 years old). It works best if assets are compressed already. Nginx takes time to compress on the fly, especially using brotli. If you still wish to use it dynamically, you may want to check it Akamai’s in-depth research on how brotli fairs with gzip in terms of size and speed. Nevertheless, brotli does make a site a bit leaner, thus faster!

I am hiring!

I’ve been a freelancer since 2008. So, it’s been a decade. I am currently looking for a freelance system admin with keen interests in hosting WordPress and PHP sites. Even though, the hosting market, especially the WordPress hosting market, has some big names in it, there are still plenty of problems to solve.

If you have interests in open source technologies and if you have contributed to open source, that’d be awesome. But, it isn’t mandatory. If you know your stuff, or if you can learn stuff, that’s more than enough. At the same time, communication is a big part of our job.

Continue reading “I am hiring!”

Local LEMP Box

I develop sites locally, then migrate the changes to the staging site or to the live site. I never make changes without testing them in my local server. I already have a repo to bootstrap a live server with Nginx, MySQL, PHP and a few more other goodies. However, there are lot of areas to improve to speed-up the development of local sites. For example, PhpMyAdmin runs on its own domain named https://pma.dev (it doesn’t exist on the internet, just a local domain). Since, I do not expose my local server to the internet, I wouldn’t want to enter the credentials whenever I type it in my browser. It saves time! So, here’s my next project… local LEMP server.

Note: This works only on Linux servers and desktops (such as Juno from Elementary OS). Particularly tested on Ubuntu 18.04 based distros. There are a number of alternatives available if you wish you to develop sites locally on a mac or on a Windows PC. Since, I host most of the sites on the latest LTS version of Ubuntu, it make sense to closely resemble the live environment.

Continue reading “Local LEMP Box”

Uptime Monitoring

WordPress is easy to use. Behind the scene, it is a complex piece of software, running on PHP and MySQL. Monitoring the uptime of WordPress sites may seem straightforward. But, in reality, it is easy to miss the downtime using conventional methods.

Let me provide you with an example. Let’s take this site… tinywp.in . I monitor this site using multiple uptime monitoring services. They keep watching the home page at https://www.tinywp.in and see if it shows any errors. They notify me in case of the following errors

Continue reading “Uptime Monitoring”

Please don’t hire me!

Please do not hire me because the cost of living in the country where I live is way cheaper than where you live. Just because the cost of living is lower doesn’t mean you can hire my services at a fraction of rate charged by the tech people from your own country!

Of course, the cost of food and real estate are much cheaper here. The cost of food is rapidly increasing here due to globalization of food industry. However, as my life resolves around IT and products related to IT, the cost of tech products are always higher than whichever country you live in!

To illustrate with an example, iPhone X (64GB model) costs USD 999 in US. Here, the same model costs INR 87400 or approximately USD 1378 upon currency conversion. All hardware products are priced higher due to reasons only known to the retailers. Software products aren’t cheap here either, just because the cost of living is way cheaper!

Continue reading “Please don’t hire me!”

Oops Moments in DevOps

A post on a new year is usually about resolutions! But, isn’t the best time to revisit the last year’s mistakes and resolve to never repeat it this year (and years to come)?! Since, my strong skills are with DevOps, I’d like to share some oops moments (you may call them blunders) that you’d never want to do it, if you are starting on DevOps or if you just want to understand where things go wrong in DevOps. In general, you go by the defaults, you’d be in trouble in the future. Whatever software you use, make sure you understand the default values and what each of them does! Here are the top three mistakes that I did… Continue reading “Oops Moments in DevOps”

Excluding iPad from wp_is_mobile!

Mobile Detect Logo
Mobile Detect Logo by Dragoș Gavrilă!

wp_is_mobile function in WordPress considers iPad as mobile! This scenario creates issues on iPad, iPad Pro, or any relevant tablets. To be precise, iPads are shown a mobile version of a site rather than the desktop version! Searching the internet didn’t yield a clean way to overcome this situation. Heck, there are even plugins to detect mobile devices and to exclude iPads from being mobiles.

Continue reading “Excluding iPad from wp_is_mobile!”