Setting up your own Mastodon, with Digital Ocean and Docker

Mastodon is the decentralized social network that all the tech blogs went nuts over last week.

Decentralized (aka federated) being the key word. There’s nothing stopping you from starting up your own Mastodon instance of your very own and inviting just your friends to it, to have your own moderation policies and community. This guide will help you get set up on Digital Ocean, with the Docker containerized version of a Mastodon system. You will also be using Mailgun for email

Updated 2018–01–18

Starting your droplet

Sign up for or log in to Digital Ocean and select “Create Droplet”. Instead of using a “distribution”, select “One-click apps” and Select Docker on 16.04:

I have tried this with both 512MB and 1GB of RAM, but neither are enough to compile the assets for the Mastodon Rails server. So let’s select 2GB of RAM:

Finally, so that you get ranked high on https://instances.mastodon.xyz/ enable IPv6 networking:

Now you can either associate an SSH private key with your droplet (recommended) or use the default method of getting a root password emailed to you. Start your droplet.

Setting up DNS

Once your droplet is created, you will need to create an A record (IPv4) and an AAA record (IPv6) at your registrar. Assuming you’re using Namecheap (and you should), first remove the parking page:

Then remove the redirect domain:

Click the trash can

Now add the following records, with your IP addresses (not mine):

Your Mastodon server will need to send outgoing email, especially when users register and need to confirm their addresses. For this we will use Mailgun. We will need to configure Mailgun in our DNS entries so that the domain can be confirmed.

Once you sign up for Mailgun, in domains, click “Add new domain”:

Now follow the instructions on the Mailgun page to add more DNS records to your domain:

Logging into your droplet

How to use SSH is beyond the scope of this tutorial, but Digial Ocean has some docs on the matter.

Assuming you have a shell, we will next want to update the server software:

# apt-get update
# apt-get upgrade
# reboot now

Then reconnect to your server. Next go to the Mastodon Github page and get the clone URL for the repository:

# git clone https://github.com/tootsuite/mastodon.git
# cd mastodon

Now we’re basically going to follow the instructions on the github page, but they’re a little wonky.

Editing your .env.production file

First, copy .env.production.sample to .env.production

# cp .env.production.sample .env.production
# nano .env.production

Now edit the file. The LOCAL_DOMAIN should be the full domain that your users will go to. In our case it is “towel.science”. But it could be “some.wacky.thing.whoknowswhat.xyz”. This is the domain that you configured A records for above.

Set LOCAL_HTTPS to true. We will be getting a cert from Let’s Encrypt and installing it soon.

For the SMTP_* lines, you’ll need your credentials from Mailgun. Simply click on your domain in the Mailgun interface and you’ll see the settings under Domain information:

SMTP_LOGIN is “Default SMTP Login” and SMTP_PASSWORD is “Default Password”. You should also change the SMTP_FROM_ADDRESS from notifications@example.com to notifications@towel.science (actually your domain).

We’re also going to need to fill out the section on Application secrets, but we can’t do that until we have built the containers once.

# docker-compose build

Now that we have the containers built, we can reach into the web container and generate our secrets using the rake secret command:

# docker-compose run --rm web rake secret
Creating mastodon_redis_1
Creating mastodon_db_1
92d4cfcd67a99a6adeb670ec4ac866611596c9792db310553f2a20b21516f27a2c95bcaf78944a6817cb05adcf0dcc47f9a21a756c30e27746f37abf4c928205

That last string is your secret. Open up .env.production again and paste it in for one of the three secrets you need (PAPERCLIP_SECRET, SECRET_KEY_BASE, OTP_SECRET). Repeat the rake secret command two more times to get the other two secrets.

Your environment file should be all set now and you should be ready to move on to the next step.

Protecting your web servers

By default, the docker containers expose their ports (3000 and 4000) to the outside world. There is a simple patch to prevent this: https://github.com/tootsuite/mastodon/pull/999/files

Basically, open up docker-compose.yml and change:

"3000:3000" to "127.0.0.1:3000:3000"

and

"4000:4000" to "127.0.0.1:4000:4000"

Opening ports

Speaking of opening ports to the outside world, your droplet comes with ufw enabled by default. In order to let the outside world communicate on port 80 (HTTP) and port 443 (HTTPS), you will have to open them on ufw. This is quite easy:

# ufw allow http
# ufw allow https

Getting a Let’s Encrypt certificate

The letsencrypt binary is already installed on your droplet, so simply do the following to get your certificate:

# letsencrypt certonly -d towel.science

Replacing towel.science with your full domain name, of course.

- Congratulations! Your certificate and chain have been saved at
 /etc/letsencrypt/live/towel.science/fullchain.pem.

The official Mastodon docs have a guide to auto-renewing your certificate with cron.

Starting Mastodon and migrating

Run this command to start the containers:

# docker-compose up -d

Now run the migrations, as detailed on the github readme:

# docker-compose run --rm web rails db:migrate
# docker-compose run --rm web rails assets:precompile

After this is done, it seems you’ll need to restart the docker containers:

# docker-compose stop
# docker-compose up -d

Installing nginx

Installing nginx is easy with apt-get:

# apt-get install nginx

Next, remove the default site from sites-enabled:

# rm /etc/nginx/sites-enabled/default

Now create a config file for your site and copy in the config here, which I have saved to it’s own gist here:

# wget https://gist.githubusercontent.com/audiodude/926abe2997f210ad55e6a674109008a2/raw/9037a39423253f439117ff1822776441e22ed506/example.com.conf -O /etc/nginx/sites-available/towel.science

Then edit the file and all you should have to do is change example.com to towel.science (but not that, your actual domain). Then link your site to sites-enabled.

# nano /etc/nginx/sites-available/towel.science
# ln -s /etc/nginx/sites-available/towel.science /etc/nginx/sites-enabled/
# service nginx restart

Hello Mastodon

Fire up your web browser to https://your.domain.example.com (https://towel.science is what we’ve been using in this example) and you should see a generic Mastodon welcome screen! Congratulations!

At this point you can sign up like a normal user for your own account.

If you don’t want anyone else to sign up and you’d like to use this Mastodon instance as your own personal playground, you can edit the .env.production file and uncomment the SINGLE_USER_MODE=true line. Then simply restart the docker containers:

# docker-compose stop
# docker-compose up -d

Either way, you most likely would like to become an admin on your own server that you just set up. Instructions for that are here. For docker, use the following command:

# docker-compose run --rm web rails mastodon:make_admin USERNAME=yourusername

Cron jobs

There are some cleanup jobs that should run once a day. Simply do:

# crontab -e

And drop the following in there:

0 10 * * * /usr/local/bin/docker-compose run --rm web rake mastodon:media:remove_remote
0 20 * * * /usr/local/bin/docker-compose run --rm web rake mastodon:push:refresh
0 30 * * * /usr/local/bin/docker-compose run --rm web rake mastodon:feeds:clear

That’s it!!

You’ve got a Mastodon instance running, congrats again!

If you liked this guide or for any feedback, feel free to toot at @audiodude@tiny.tilde.website

Final Note

This guide doesn’t cover backups or upgrading, which are both important topics to consider if you’re going to run anything more than a toy server. The official Mastodon docs on Github have some information about upgrading, but it doesn’t seem like anyone has written anything specific yet about backups. Generally, it’s going to look like rsync’ing a few specific directories and the DB to a remote service. These topics are left as an exercise to the reader.

Like what you read? Give Travis Briggs a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.