Join me on Mastodon!
The entire concept of Mastodon sounds interesting. You host, own and control what your own social media site and still be able to connect with people on other instances. I wanted to host my own instance since I heard of it. Unfortunately, or fortunately, I have no intention of seriously moderating it so we'll see how long it lasts.
I have a Raspberry Pi 4B with 2GB of RAM which turns out to be sufficient for this purpose. Like this server, I use cloudflared tunnels which is good because I don't have to port forward and expose my device to the Internet, but the setup was a bit more complicated. Also, it's free as long as you have a domain on Cloudflare (which is also one of the cheapest domain registry if you only plan on using the free tier).
For the SMTP server, I used the free tier on SMTP2GO, which gave me 200 free emails a day, 1000 a month. Hosting my own SMTP server is not impossible - a post (poolp.org) - but I can't be bothered to deal with that right now. I'll consider doing so only when traffic exceeds the free limit. There are other services like SendGrid, Mailgun or Amazon SES which also offer free services.
First, you have to create an email on your domain. On the Cloudflare dashboard, go to your domain and choose Email Routing. Create a new address and link it to one of your existing email addresses (e.g. Gmail). Here's the youtube video I followed. You can then use this email to create an account on SMTP2GO. Here's the getting started guide (SMTP2GO).
In the SMTP2GO dashboard, you first have to create a verified sender. This basically allows you to send emails on the verified domain for [email protected]. Or you can create a single sender email to allow sending emails with [email protected]. Follow this DNS setup guide (SMTP2GO) to add the DNS records needed to Cloudflare. Then, still on SMTP2GO, you have to create a new SMTP User that your mastodon instance will use to authenticate itself to send emails through your verified sender. You can use any username, just remember it for later during Mastodon setup. Remember this too: SMTP server: mail.smtp2go and SMTP port: 2525.
I followed this tutorial, which did work, but you might have to use a magnifying glass to get the ads out of your peripheral vision. A lot of it overlaps with the official docs, so just splice the information together and preferably use the official one which is more up to date. I realised later on that I could have used Docker, so feel free to try that.
If you have 2 GB of RAM like me, you should create a swapfile (using disk space as RAM) before running the asset precompilation step RAILS_ENV=production bundle exec rails assets:precompile
or it will likely fail. The compilation takes 10-30mins to complete. I had the browser open when I ran it and it froze my Pi. I left it overnight, assuming it would complete eventually, but it was still unresponsive the next day and I had to restart it. That was before I created the swapfile.
count=4M
will allocate 4GB of disk space for the swapfile. I don't know how much you need, I just did 4. 1 would probably work.
dd if=/dev/zero of=/swapfile.img bs=1024 count=4M
mkswap /swapfile.img
sudo swapon /swapfile.img
free -m
This answer on stack exchange has more information.
Another thing to note: when you receive the confirmation email from Mastodon for your SMTP server it may appear in junk mail.
Debugging might come in handy.
# open the editor:
$ nano ~/live/.env.production
# add these two lines:
RAILS_LOG_LEVEL=debug
LOG_LEVEL=silly
# run this to start the log output:
$ journalctl -xf -u mastodon-*
For the "Acquiring an SSL certificate" section, instead of using Let's Encrypt, you can generate an SSL certificate from Cloudflare. On your Cloudflare dashboard, go to your domain > SSL/TLS > Origin Server > Create Certificate. Save the private key to a file called privkey.pem and the other key to fullchain.pem. In /etc/nginx/sites-available/mastodon, uncomment the lines under # Uncomment these lines once you acquire a certificate
and place the keys in the corresponding directory. Don't forget to change all instances of example.com in the file to your domain name. Then run systemctl restart nginx
. Follow the rest of the setup guide from there.
Now, it won't work yet because you haven't connected to cloudflare using a cloudflared tunnel. Presenting: another guide (Cloudflare) for setting up your cloudflared tunnel, wow! In your tunnel, add two public hostnames, like so:
I don't know why setting Origin Server Name and enabling No TLS Verify is necessary (it works without either), but this guy did it.
You should be able to access the Mastodon page on your domain. You can login with the admin account with the password from the earlier steps. If you forgot to record that, this documentation (tootctl) might be helpful. In the Administration settings, you can allow user sign ups which is needed for users to create an account on your instance. I thought I messed up when I couldn't create an account.
As a final touch, I designed a server banner and favicon (which you can add in the settings).
In the end, I didn't figure out why I need nginx to be running since it doesn't make sense to have a reverse proxy and cloudflared tunnel at the same time. On the other hand, I don't know much about nginx and I could be completely misunderstanding the whole infrastructure.
I can't really ascertain the security of the server on the network level. I think it works... until I get my first DoS attack. Since I never exposed my device, the main threat is a vulnerability in one of my servers that lets you gain unauthorized access to data on the device. But, my servers are pretty straightforward and none of them take or store any user information (as of 22 October) apart from this Mastodon server. As long as Mastodon has no vulnerabilities I should be fine. Despite that, user data is still at risk internally with the irresponsible lack of data backups. If I had the budget I would backup data on a NAS or use an object storage service.
I found out after setting up that I can't upload any files to it other than videos and images, which is unfortunate. On the topic of uploads, I have to figure out how limit the upload size so my meagre 64GB MicroSD card doesn't beg to be reformatted when some ill-mannered actor decides to cause unoptimised terrorism. For now, I'll just add a warning in the server description that user data may or may not meet premature expiration, and leave signing up on an on-approval basis.