Migrated VPS

black server racks on a room

When I started hosting this website on DigitalOcean about 9 years ago, the version of Ubuntu that was all the rage was 14.04 LTS. So I started my hosting journey with that. Pretty soon though, 16.04 came along and since I was ever active on my server, I upgraded to that using nothing more than a few apt update commands. Since then, other than a few forced efforts to secure the OS and install what I needed for experimentation, I didn’t do much to upgrade the underlying software.

So it happened that, when at the beginning of the year I tried to upgrade from PHP 7.3 to 7.4 (a process which failed), I was made aware of the fact that the chasm between where my software stack is and where it ought to be is rather large. I tried running a straightforward upgrade from 16.04 to 20.04. The blocker was mysql. Apparently, no matter what third party repos I tried, the upgrade from what I was running to whatever’s the current just wasn’t possible. Well, it may be possible, but it would not be easy. The recommended path, on multiple websites, forums, and blogs, was to just fire up a new VPS and migrate my websites and services manually. Daunting.

When I learnt of this, I realized that the amount of time and effort it would take was too much for me to give at that moment. Family needs and other projects held precedence. Right now, I wouldn’t say those needs have abated, just that I’ve adjusted to both those asks, and I’ve given myself enough time and another factor for this migration – money. DigitalOcean is a nice provider in that they’ll only charge me for what I use through the number of days that I use it. I know this is sort of the norm everywhere now, but it’s a nice-to-have and a nice-to-mention nevertheless. Instead of doing the entire migration within the span of a few hours, tiring myself, and increasing the odds of a failed migration, I spread the entire project over the last few days. I moved my other WordPress install first, the one whose failure wouldn’t affect me directly and personally. It’s a side project that we’ve gotten side-tracked from. I’d be totally fine if it craps out.

Moving WordPress seemed daunting, until I realized that I have a tool that can make it extremely easy. I’ve been backing up this website to Dropbox using UpdraftPlus for the longest time. It’s fast, easy, and totally a background process which has not needed my input since I set it up. I checked it out and sure enough, it’s got a pretty straightforward restore process too, included in the free version of the plugin. Of course, they offer paid tools for much easier migration. But I reckoned the free one has got to work just as well. UpdraftsPlus creates a bunch of separate zip files for the database, uploads, themes, plugins, and “other”. All you have to do to migrate is to create a fresh install of WordPress, install the plugin and drop the files into the interface and then hit restore.

This blog’s backup comes in at about 750 MB, while the other site is about 160 MB. I did the latter first, and since it stayed up just fine over the last few days, while for the first time in my life I ran two VPS in parallel in DigitalOcean, I ported over this blog as well as the other applications and sites which I wanted to keep. It ended up being a good housekeeping too, since most of the active nginx sites were not doing anywhere and thus were liable to be security issues. Plus, it gave me a chance to really start from scratch.

Over the years, I let the older VPS grow organically and get cluttered as all in-use systems do. When I was attacked by a script kiddie trying to get into this site and wreak havoc (at which they partially succeeded), I installed fail2ban and went aggressive with it, to the point where I got locked out of SSH quite a few times and had to recover via console. I installed multiple versions of node to run shortlived telegram bots or expressJS apps. I installed numpy to create a webUI for an experiment my brother wanted to run. I also created a series of scripts to run via cron – to periodically free up space and memory, to pull in data and recycle logs.

All of this had become a sore point for me anyways. The services running on the VPS often went down. The APIs responded only half the time. The downtime was somewhat acceptable till it wasn’t.

So this new VPS, well, I’ll run it as clean as I can for as long as I can. Of course, I’ll get hit by something or the other and I’ll have to respond with better security measures. But I wasn’t running any firewall before and ubuntu 20.04 seems to be running ufw by default, which is nice. I was also able to update PHP from v7.3 all the way to v8.0, which is nice, but came with it’s own set of challenges. One function in WordPress and another in a homegrown bookmarking tool were failing since they don’t work in PHP 8.0, so I had to spend some time figuring that out. But it’s good to have the latest software and to hope I’ll keep things updated better this time around.

All in all, a good experience. My old VPS is now sitting in shutdown mode. I’ll let it sit for a couple weeks, while I test out the new system and see if I forgot to move some settings or such. I know it’ll cost me almost twice as much for the month to run both machines in parallel, but it’s worth the peace of mind I’m getting.

Plus, this migration got me in touch with some projects I’d forgotten! I regularly use my liveblog, but completely forgot about “SomeDay”, a bookmark/linkblog of articles I didn’t finish reading and hope to, some day. It’s got an RSS feed and all, so maybe you can find something in there that you might want to read, today.

Links to everything currently hosted on my new VPS –

this blog


scratch.nikhco.in – a minimal writing tool with local browser storage and ability to start a TogetherJS session to collaborate with others in real time.


someday.nitinkhanna.com – I haven’t read these articles yet. Maybe you should try?

Fixing Jetpack’s Stats module

Despite the hate that Jetpack gets for being a bloatware plugin, it is one of my favorite and the first step whenever I setup a new WordPress install. However, Jetpack does have a few irritating habits that I cannot overlook. One of these is the stats module. The module actually does pretty well, posting data to the wordpress.com dashboard and making it easy for me to quickly glance at the number of visitors I’ve had for the day.

However, every so often the module craps out and logs a large number of visits from crawlers, bots and spiders as legitimate hits, since those are not in the official list of crawlers, bot and spiders to look out for. To fix this, I went out to look for the list and to add to it. One quick GitHub code search later, I found that the file class-jetpack-user-agent.php is responsible for hosting the list of non-humans to look out for. What I found inside was actually a pretty comprehensive list of software, but one that definitely needed extending.

If you want to do what I did, find the file in your WP installation at –

Inside the file, look for the following array variable –

You’ll see that the array already contains common bots like alexa, googlebot, baiduspider and so on. However, I deepdived (meaning did a sublime text search) into my access.log files and found some more. To extend the array, simply look for the last element (which should be yammybot) and extend it as follows –
'yammybot', 'ahrefsbot', 'pingdom.com_bot', 'kraken', 'yandexbot', 'twitterbot', 'tweetmemebot', 'openhosebot', 'queryseekerspider', 'linkdexbot', 'grokkit-crawler', 'livelapbot', 'germcrawler', 'domaintunocrawler', 'grapeshotcrawler', 'cloudflare-alwaysonline',

Note that you want to leave in the last comma, and you want all the entries in lower case. This doesn’t actually matter, because the PHP function that does the string compare is case-insensitive, but it just looks neater. You’ll also notice that I’ve added the precise names of the bots, like ‘grokkit-crawler’ and ‘clousflare-alwaysonline’ but you can be less specific and save yourself some pain. This will, however, affect your final stats outcome.

Notes –

  1. Some of the bots are pretty interesting. I saw tweetmemebot, which is from a company called datasift, which seems to be in the business of trawling all social networks for interesting links and providing meaningful insights into them. Another was twitterbot. Why the heck does twitter need to send out a bot? We submit our links to it willingly! Also interesting were livelapbot, germcrawler and kraken. I have no idea why they’re looking at my site.
  2. Although Jetpack does not have a comprehensive list of bots, it still does a pretty good job. I found the main culprit of the stats mess in my case. Turns out, CloudFlare, in an effort to provide their AlwaysOnline service (which is enabled for my site), looks at all our pages frequently and this doesn’t sit well with Jetpack. I hope this tweak will fix this now.
  3. Although this fix is currently in place, every time the Jetpack plugin gets updated, all these entries will disappear. That’s why this blog post is both a tutorial for you all and a reminder and diary entry for me to make this change every time I run a Jetpack update. However, if someone can tell me a way to permanently extend Jetpack, or if someone can reach out to the Jetpack team (hey Nitin, why don’t you file a GitHub issue against this?) it’ll be awesome and I’ll be super thankful!

Update – I was trying to be hip and did a fork of Jetpack and GitHub, made the changes and then tried to make a pull request. Turns out, I don’t know how to do that, so I opened an issue instead. It sits here.

Ghost: My comments

Ghost showed up on Kickstarter yesterday and like any good blogging platform, it’ll be judged, commented on, loved and hated. So let me start early. I don’t like it. I love the idea, I loved the beginning, I just don’t like the execution. Here are the two reasons why –

  1. NodeJS? Really?

NodeJS is all the rage right now. Every developer is discovering the strange and amazing things you can do with, of all the things, JavaScript and is running from pillar to post to launch a real-time, fast and easily scalable app as soon as possible. Of course, this means that there are some really nice apps out there. But is NodeJS ready?

Well, define ready.

Of course. Ready means that the next time some layman decides to set up a blog on the Internet, can (s)he purchase a simple hosting plan, upload a couple of NodeJS files and be up in 5 minutes? No. You have to rent a VPS or invest in Amazon AWS, upload files via git and then know how to develop locally and push out changes to the repo in the cloud(Notice all those keywords I threw there, developer?) In other words, you better be a developer and please don’t expect every Tom, Dick and Thorsten to be able to use this technology.

The ghost blog tries hard to defend its decision to go with JS based on the argument that it’s the future and is robust and allows innovation. It leaves out the fact that until the GoDaddies of the web hosting world don’t come out with NodeJS support in their basic plans, you’re not going anywhere with this blogging platform other than the few platforms that specifically support this technology. Oh, and your own computer.

  1. What about WordPress?

When Ghost was first introduced, O’Nolan talked about how WP changed his life and how it was awesome and awful at the same time and how his plan is to take the WP Core and rewrite parts of it to make it awesome-awesome. He meant it. He was going to fix WordPress with just a plugin. But then he didn’t. He’s going to keep the WP format, so that themes and plugins can be easily converted. He’s going to make tools to import from WP so that people can shift to Ghost ASAP. He’s going to take from WP and literally give nothing back. Ever.

I did not expect this. Well, the folks at WordPress probably did. They understand that WP is open source and people can easily add or take as they want. But I did not expect that instead of solidifying and giving better direction to WP, John would just steal from WP so blatantly and try to replace one good platform with another. He could have worked on the Core, he could have made it so much better as to force Automattic to consider his direction as the right path forward. He could have influenced the lives of so many WP lovers in such a positive way, but instead he chose to give up all that just because it would be a little more difficult to make the same stuff in PHP than it is in NodeJS. He gave up on the entire idea and instead focussed himself on getting people to drop WP and come to Ghost, leaving behind the entire essence of the platform that he’s clearly got a lot to thank for.

I’m a big proponent of WordPress. When friends come to me with even a semi-serious resolve to start a blog, I tell them of the cheap and easy hosting plans out there, how they can just upload a bunch of files and run an install script by opening a link in a browser and can search for and edit plugins and themes right from inside the web app and be running a blog in 5 flat minutes.

Now, when people will ask me about Ghost, the “better WordPress”, I’m just going to tell them that it’s not worth the effort and that it’s not ready for prime time. That’s because, NodeJS being such a nascent technology, we can’t expect to see large-scale adoption of the platform any time soon. We won’t see people being enabled to quickly setup a blog without too much hassle and we won’t see ghost being the de facto standard for someone just stepping into the world of blogging. You thought App.net was a country club? Wait till Ghost comes out.


This whole thing seems too much like a rant? As O’Nolan says, “Haters gonna hate.”

Auto-refresh for Fever on AppFog

Today, I got asked something about my “Installing Fever on AppFog” tutorial. Fever has an inbuilt module to refresh your RSS feeds periodically but this module doesn’t work on all types of servers and it certainly doesn’t work on AppFog. Shaun, being the good guy that he is, lists out a way to set up a curl command with a cron job to refresh the feeds automatically. Unfortunately, AppFog doesn’t support crontab directly either. So, I got asked if there’s a solution for this. After a little bit of Googling and finding this solution on stackoverflow, I built up a working solution specific to Fever on Appfog. The detail follows – Continue reading

Feedafever for ~Free

I’ve been reading Chris Anderson’s “Free” and while I pay for the occasional service or app, my endeavor is to get as much as I can, for free.

Fever, an RSS reader that’s clever, quick and time-saving, is a recent purchase that I’m finding to be just amazing. What’s more amazing is that the product is worth $30 but I found someone who didn’t need it any more so he sold me his activation key for much lower… Continue reading

Feedafever for ~Free

I’ve been reading Chris Anderson’s “Free” and while I pay for the occasional service or app, my endeavor is to get as much as I can, for free.

Fever, an RSS reader that’s clever, quick and time-saving, is a recent purchase that I’m finding to be just amazing. What’s more amazing is that the product is worth $30 but I found someone who didn’t need it any more so he sold me his activation key for much lower…

Anyways, the look and feel of Fever is great and despite the really small app ecosystem, I’m really enjoying the app. The only problem? I’m a fan of RSS and follow just about any blog or feed that I find on the Internet. That’s kind of why I needed Fever – it has features such as sorting the feeds based on their relative “hotness” and presenting it in a very coherent format. But all those feeds being polled so many times were causing a bit of a problem – too much storage and too much bandwidth.

Continue reading