Weekend Nerdiness

Posted by Phil Weber on February 28, 2023

During the Great Twitter Migration of 2022, I spun up my own Mastodon server, hoping to cultivate a community of fellow voiceover artists. I had an account with Vultr, so I provisioned a fairly beefy VPS with 2 vCPUs and 4GB RAM, plus 40GB of block storage for media, for $25/month.

Meanwhile, I had a small media and file server at home with a third-generation Core i3 and 4GB RAM. It worked well, but was due for an upgrade.

Three months later, I am still the only user on my Mastodon server. So a couple of weeks ago, I ordered a refurbished ThinkCentre M900 Tiny (6th-gen i5, 16GB RAM, 256GB SSD) for $127. This past weekend, I migrated Mastodon from Vultr to my home server.

When I initially installed Mastodon in the cloud, I installed it directly on the host; on my home server, I wanted to run Mastodon in Docker containers. Mastodon provides instructions for migrating an installation to new machine, but they assume a bare-metal install; it took me a few attempts to find the right commmands to:

  1. Create a mastodon user in the Postresql database inside the container;
  2. Get the database backup from the old server into the container;
  3. Create a new empty Mastodon database owned by the mastodon user; and,
  4. Run pg_restore inside the container to restore the backup.

Once I had migrated the database, installing Mastodon itself was fairly straightforward. There are a number of good guides online for installing Mastodon using Docker Compose.

But when I tried to start it, the Web container complained that it couldn’t connect to the Redis container. After extensive trial and error, I discovered that everything worked if I disabled UFW, the firewall on the host. It turns out that Docker does not play nicely with UFW, and requires low-level configuration changes to iptables. Since I had to configure iptables anyway, I simply uninstalled UFW and used iptables directly.

Next problem: I use port forwarding on my (ISP-provided) router to get traffic from the Internet to my home server. The router doesn’t support NAT loopback (hairpinning), so devices on my home network could not connect to my Mastodon instance using its public URL.

Dashboard showing Mastodon resource usage

The solution was to deploy a private DNS server on my network that routes internal requests for https://voiceover.actor/ to my server’s private IP address, and forwards other queries to my upstream DNS servers.

Finally…success! Mastodon is running happily on my home server, using an average of about 2% CPU and 25% RAM, and saving me $25/month compared to hosting in the cloud. My new server will pay for itself in 6 months!


Leave a comment