Migrating from Tumblr to WordPress on VPS



I’ve had enough with Tumblr. It’s been randomly messing up with <, >, & characters in the Markdown editor. And by that I mean it removed a random subset of content between, before, or after those characters. Or replaced the characters with something else. Or whatever.

Then it randomly removed the closing / character in img tags. Then it randomly put <p>, <map> (???) and whatever tags at random places in random posts. Then it started replacing my hi-res Imgur images with low-res images copied to Tumblr hosting.

This was the final stab. The last nail in the coffin. This is where I draw the line. Tumblr, I officially hate you. I’m done with you. The free hosting, the free custom domain, the free SSL are all very-very nice, but it’s worthless if you screw up all my content.

Over the weekend I finished migrating my Tumblr blog to self-hosted WordPress. There are still rough edges, but the rest is just cleanup, no further know-how required, so now I want to share my experience with you.



You need a Linux (CentOS) instance to serve WordPress. Yes, you could go for WordPress hosting instead of a VPS, but it won’t be much cheaper (WordPress hosting starts at $3, VPS at $5), and you’ll get a lot of cherry-picked limitations pushed down on you. Since this is the very reason I’m migrating from Tumblr, that road was out of the question.

Anyhow, complete the CentOS 7 done right on Vultr tutorial to get your Linux instance up and running.


Obtain an HTTPS certificate via Cloudflare and free Let’s Encrypt to be used by the web server.


Install the Nginx webserver to serve the WordPress site. Make sure to select php when asked about the server method.

Then you need to add a rewrite rule for permalinks to work properly, and also change the document root from /var/www/html to /var/www/html/wordpress. Edit your host config, probably /etc/nginx/conf.d-enabled/host.conf (but YMMV) like so:

root /var/www/html/wordpress;
include srv-php.conf;

if (!-e $request_filename) {
        rewrite ^.*$ /index.php last;

include ssl.conf;


WordPress is very picky when it comes to database. It only supports MySQL and MariaDB. Which won’t even count as two, since MariaDB is a fork of MySQL, but whatever. I picked MariaDB for the seemingly better community support. Use the [MariaDB repo tool] to obtain the relevant info. At the time of writing, it worked like this:

cat << EOF > /etc/yum.repos.d/MariaDB.repo
# MariaDB 10.3 CentOS repository list - created 2018-08-16 13:21 UTC
# http://downloads.mariadb.org/mariadb/repositories/
name = MariaDB
baseurl = http://yum.mariadb.org/10.3/centos7-amd64

yum install MariaDB-server
systemctl start mariadb.service
systemctl enable mariadb.service

Now you need to create a database and a user assigned to that database. Enter the MariaDB management console:


Then perform the needed tasks (replace the password):

GRANT ALL PRIVILEGES ON wordpress.* TO "wordpress"@"localhost" IDENTIFIED BY "***";


Finally, some action. I normally use symlinks to use a static path while also keeping version information. I tried this with WordPress 4.9.8, but some really weird stuff happened then. When I tried to open https://noobient.com/, it redirected me to https://noobient.com-4.9.8/wp-admin/setup-config.php instead of https://noobient.com/wp-admin/setup-config.php. Why this happens is beyond me, but apparently WordPress doesn’t support this without huge hacks. So nevermind, forget symlinks.

Just download the latest release, extract it, then fix SELinux contexts:

wget https://wordpress.org/latest.tar.gz
tar xvf latest.tar.gz -C /var/www/html
restorecon -rv /var/www

Copy wp-config-sample.php to wp-config.php, fill in your DB name, user and password, then save. Now open your website’s address and finish the initial setup, it should be pretty straightforward.



Go to Settings / Permalinks, and select Day and name. Other formats might also work, but I’ve been using this one.

Importing Tumblr Posts

First thing first, if you use a custom domain on Tumblr, disable it, because the importer won’t work with it. Yes, that means downtime for your blog.

Then go to Tools / Import, and click Install Now under Tumblr. The tool will pretty much tell you all the steps, but here’s an outline. When you set up the Tumblr application, you may receive the following error:

url’s domain is not valid

To me this happened when my WordPress site used a domain that I used on Tumblr as a custom domain before. I switched to an other domain temporarily, and it instantly worked.

After the import is done, you should have all your content available on the WordPress site. Now you can switch back to the old domain.

One problem though: \ characters are apparently stripped from all posts. Ouch.


Install the Classic Editor plugin, then Markdown Editor as well. That’s it. HTML code will continue to work in posts, but you can switch to Markdown anytime you want, individually for each post. For easy conversions, I recommend Pandoc. Here’s an example command line:

pandoc --wrap=none -s conv_html.txt -f html --to gfm+backtick_code_blocks -o conv_md.txt

Paste the HTML code into conv_html.txt, run the Pandoc command, the converted markup will be found in conv_md.txt. Paste that into the post, hit Update, and you’re done.


It is important to install themes before doing the heavy customizations, since that often involves digging deep into the code. But that code is part of the theme, and if you switch themes, you’ll have to do that all over again.

TLDR pick your theme carefully, because if you decide to switch later, you’ll have to redo a lot of work.

In my tutorial, I’ll use the VW Startup theme.


Sitemaps are important to guide the search enginge crawlers through your site. Tumblr generates a sitemap automatically, in WordPress you need a plugin. Install the Google XML Sitemaps plugin. Your sitemap will be found under <site address>/sitemap.xml. Make sure to submit this to Google Search Console and any other relevant search engines.

Google Analytics / AdSense

Previously I had some PHP editing here, but luckily now we have the Google Site Kit plugin, which does all the heavy lifting for you. Easy as pie!



First off, install the Disqus Comment System plugin (for whatever reason it will show up as Disqus for WordPress in the plugin manager). At this point Disqus will have already replaced the built-in commenting, but comment counts are wrong. They always show 0, regardless of how many Disqus comments you actually have.

Comment Count

The basic steps are outlined in the article, Adding comment count links to your home page. Find out your Disqus shortname first.

Now edit the Theme Footer (footer.php), and add the following before the <?php wp_footer(); ?> code:

<script id="dsq-count-scr" src="//YOURSHORTNAME.disqus.com/count.js" async></script>

This was the generic part, but here comes the trick, because this is completely theme-dependent. The VW Startup theme uses template-parts/content.php and template-parts/single-post-layout.php for displaying content. You need to replace the relevant part in both files. It looks like this OOTB:

<i class="fa fa-comments" aria-hidden="true"></i>
<span class="entry-comments"></span><?php comments_number( __('0 Comment', 'vw-startup'), __('0 Comments', 'vw-startup'), __('% Comments', 'vw-startup') ); ?>

You have to disable the PHP code as it won’t work with Disqus, and also need to insert a link which points to #disqus_thread. Like so:

<i class="fa fa-comments" aria-hidden="true"></i>
<span class="entry-comments"><a href="<?php echo esc_url( get_permalink() ); ?>#disqus_thread"></a></span>
<?php /* comments_number( __('0 Comment', 'vw-startup'), __('0 Comments', 'vw-startup'), __('% Comments', 'vw-startup') ); */ ?>

Two-Factor Authentication

I recommend and use the Duo Two-Factor Authentication plugin. Duo is an established name in the security landscape, so established that it was even acquired by Cisco just recently. So they’re a pretty safe bet, I’d say. And it’s free for up to 10 users.

Anyhow, just install the plugin and follow the official documentation, Duo for WordPress. It’s pretty straightforward, really.


If you haven’t yet done so while acquiring the certificate, you probably want to enable Cloudflare for your site, because you can save a lot on your bandwidth. Which is rather crucial when you host your site on a VPS, as most of them include only 1TB of montly bandwidth in the plan. And it also helps protect your site from attacks.


I also use the

plugins, I recommend you check them out.

For PHP, I also recommend the following packages:

  • php-opcache
  • php-xml
  • php-gd
  • php-json
  • php-mbstring
  • php-pecl-zip

Aaand that’s it, guys, enjoy your fresh and shiny WordPress blog!