For full disclosure, I should say that I run three social networks now and they all run on the Mastodon platform, I’ve installed all three. I am biased, I’m not running Diaspora or anything else and I’m not running a forum on an established commercial website. And frankly on Mastodon all I do is run servers; the network seems to take care of itself after installing Mastodon.
What really started out as a fun Docker project turned into a full-on passion and a new way to interact with people that was not based on Twitter, Facebook and the rest of the commercial based social network offerings available. I’ve discovered new ideas, trends and people I wouldn’t have discovered in the noise of Twitter and I refuse to submit myself to the tracking that comes with Facebook (across the entire web).
Let’s start with what Mastodon is – Mastodon is an open source software project that aims to be a replacement for Twitter. The interface uses the style of a popular Twitter client and has real time streaming updates across servers so that users can interact with each other in a familiar fashion. You can mention, reply, boost, favorite and directly message (away from the eyes of the world). All of this bundled into a free and open source software package that uses a common protocol to federate with other servers creating what we’d call the “Fediverse”.
Mastodon hits the basics and more. What honestly intrigues me most, and has pulled me into it, is the real-time nature of the tool. How you use it, what privacy settings you use and what the server is setup to do is what makes the experience more or less like Facebook or Twitter (or entirely different). I have one network that’s all private and operates like a Facebook – and another that is totally open and each user’s profiles are public like Twitter.
But neither Twitter or Facebook offer the same real time view. Right now as I write this there are things I’m missing. It’s missed, there isn’t much hope of catching up – I follow too many people. While it feels ephemeral it isn’t actually. That amazing post from a few hours ago, it’ll get boosted again and I’ll see it next time I check. And when I check, I can watch it stream by me.
And this is where it’s the most fun. I have a long day, I get up early and I go to bed late. I can watch the stream in the early morning and see a whole set of (European technotrash) people posting and boosting statuses and throughout the day watch it turn as the sun moves it’s light across the Earth (to Japanese technotrash). It slows down, but the Fediverse never sleeps. New shifts take over, new people sign in, and the flow of ideas keeps going.
Social networks are what you make of it
And Mastodon is almost for everyone. In the first 24 hours of setting up my server I was following everyone from Alt-Right Nazis to Tri-Gender Iron Front members. And oddly, I was interacting with both almost immediately too (beyond a follow or a follow request). I was in the wild west trying to find friends and it was easy to find them in the Fediverse (but easy to be blocked for making those same friends as well).
One of the things that makes the Fediverse stand strong, though also fragments it, is the idea that you can decide to block those people you do not like. I’m sure my aforementioned and newfound Nazi and Iron Front friends have already blocked each other. You too get to decide if you want to wholesale block an instance based on their political views (or even lack thereof, speaking of nihilists) or their views on gender, race, or you get to federate with them and follow their posts as too if you’d like.
Surely this isn’t an article to describe how Mastodon works – there are others that do that well, and even videos that describe how it all fits together. What I find most interesting isn’t how it works but instead that it does work, and it works well. Beyond the live updates, the constant flow of information in the timeline I have found that people do actually like interacting on the platform.
I follow a lot of people, as I said, and I reach out to a lot of them. Their funny jokes I try to add onto and make a bit funnier, their questions I reply to and their polls I make my opinions known on. And I have to say for a group of total strangers, people just posting and following and interacting with blind faith that people are interested in the same things, everyone seems to mesh well together. At least, they interact with each other, they take the time and they seemingly respect each other at some level as human beings. There is a fair level of blocking, to the point of #Fediblock becoming a trending tag at one point recently, but overall people are genial.
For this reason, and the freedom inherent in the software – it’s freely available and open source code – we have to say it’s not lame. We are suggesting you leave Twitter and Facebook behind and join and support the Fediverse.
How Do I Join?
Mastodon is actually just a piece of software and not the entire story, but super easy to join – there are other options as well, including Soapbox FE, Pleroma, and others. And it turns out you can do it your own way as well regarding your first step. You do not have to run any software of your own you can join an existing server, and of which, there are many. Or you can roll your own server using the software mentioned above.
But I’m curious on how to run Mastodon!
Well, if you wanted to play in Docker as I did and setup a Mastodon server I can help guide you down the path to getting a server up and running in short order. I won’t be writing a guide to installing Docker, because it is a base package to any operating system and there are guides for all flavors of Linux out there already (as well as Mac OSX and Windows 10 PRO).
I can relay the steps of installing Docker that I used prior, though I’m using Debian 10 so it’s specific for me.
Installing Docker in Debian 10
First we need to install the basics on Debian to prepare for Docker. This includes the basic security certificates if you don’t have them, CURL and other base software;
sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ software-properties-common
Then you’ll need to get the Docker PGP key to authenticate the packages come from Docker and not from someone else – and add it to APT’s key-ring in one line;
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
Then you can (optionally, though you should) verify the APT key;
sudo apt-key fingerprint 0EBFCD88
You should see the below (or similar – see their Debian guide to be sure);
pub 4096R/0EBFCD88 2017-02-22 Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 uid Docker Release (CE deb) <firstname.lastname@example.org> sub 4096R/F273FCD8 2017-02-22
Update your local cache of APT repositories and packages, it’s time!
sudo apt-get update
And install Docker!
sudo apt-get install docker-ce docker-ce-cli containerd.io
Now you have Docker (and Docker Compose) installed if you didn’t have it installed already and can start downloading and installing Mastodon.
Mastodon can be built from source and run or it can be run from existing Docker containers. Because you can easily mix up the master branch with the currently released version that’s stable I suggest doing a mixture of the two things – fetching the source from Github and using it as your basis for running the pre-built Mastodon Docker containers.
Install Git for Github
After you’ve determined where on your Linux system you’re going to store Mastodon you’ll need to copy the current stable branch from Github and copy the files down. If you don’t have git installed, let’s install it now!
sudo apt-get install git
Grab the Mastodon v3.2.1 source code from Github
You’ll want to be careful here and not grab the master branch, and instead target for the lastest release of Mastodon, v3.2.1 – and you can do this by grabbing a particular Github branch which will get you the docker-compose.yml file and others you’ll need to get going.
We’re going to achieve this by cloning only a certain branch from Github using git;
git clone --branch v3.2.1 https://github.com/tootsuite/mastodon.git mastodondirectory /usr/local/mastodon
Notice we are calling to the v.3.2.1 branch specifically and we are stashing the files in the ‘/usr/local/mastodon‘ directory (which you can choose as mentioned above).
Now we mentioned that you can build Mastodon from source, and the files we pulled from Github do this by default. If you notice the docker-compose.yml file right now defaults to build everything you just pulled – you’ll see it in the line below where the Mastodon web services are called out (web block);
web: build: . image: tootsuite/mastodon
If you don’t want to do this and use the pre-built containers, which we lamely suggest, we need to change all three places we see “build” to comment out this line.
Web Docker Service:
web: #build: . image: tootsuite/mastodon
Streaming Docker Service:
streaming: #build: . image: tootsuite/mastodon
SidekIQ Docker Service:
sidekiq: build: . image: tootsuite/mastodon
And while we’re at it, let’s fix all three places to ensure we pull v3.2.1 of Mastodon from Docker Hub;
web: #build: . image: tootsuite/mastodon:v3.2.1 ## scroll down to streaming streaming: #build: . image: tootsuite/mastodon:v3.2.1 ## scroll down to sidekiq ## sidekiq: build: . image: tootsuite/mastodon:v3.2.1
Now we’re almost setup to start running the Mastodon Docker Compose files and setting up the server. We’ll need to copy an example Production file over for us to use from the git repository;
cp .env.production.sample .env.production
Let’s not do anything with this file other than set our postgres or our “db” user up. We’ll need to do that before we can run the setup and get a successful connection test. What we’ll want to do is edit this section:
# PostgreSQL # ---------- DB_HOST=/var/run/postgresql DB_USER=mastodon DB_NAME=mastodon_production DB_PASS= DB_PORT=5432
And setup our own Postgresql user details. While this image/container won’t be exposed to the outside world let’s make the password long and random (we recommend generating a non-special character key from LastPass).
# PostgreSQL # ---------- DB_HOST=postgresql DB_USER=databaseuser687 DB_NAME=mastodon_production DB_PASS=Z3vGzE5WzOo5Vhj83uvc6op7Sj DB_PORT=5432
Keep these settings handy or the text file open if you can, you’ll need them for the next steps when we generate the rest of the values in this file.
Setting Up Mastodon For the First Time
sudo docker-compose run --rm web bundle exec rake mastodon:setup
The above will launch the ruby setup for Mastodon using the Mastodon CLI and we’ll generate the values for the setup in .env.production. Doing this will also download the needed container images from Docker Hub for the first time.
Starting mastodondirectory_db_1 ... done Starting mastodondirectory_redis_1 ... done Pulling web (tootsuite/mastodon:v3.2.1)... v3.2.1: Pulling from tootsuite/mastodon d72e567cc804: Pull complete 0f3630e5ff08: Pull complete b6a83d81d1f4: Pull complete 1aa4cf3a1701: Pull complete 9a84b78a19cb: Pull complete b790fb18ff52: Pull complete 9a89c1b2e6ed: Pull complete 420601ca9a5f: Pull complete fb8dcb3732a4: Pull complete 2bc41d47dd50: Pull complete 60263769a4f2: Pull complete 9bba9cfb5051: Pull complete 58c1bc840dea: Pull complete Digest: sha256:41cd5fb48d8b15ec806f08ab06fec98df33ec9b83a1f879e0fb30da9994018dc Status: Downloaded newer image for tootsuite/mastodon:v3.2.1
Next you’ll be asked a series of question which will pertain to your Docker setup. For this install we’ve not changed any default passwords (bad idea) but we’re running with enough to get us going and our Postgresql database will not face the outside world through Docker.
To get started you’ll have to answer which domain name you intend to use – this isn’t to be changed later so we have to assume you’ve thought this through. Example.com always works;
Your instance is identified by its domain name. Changing it afterward will break things. Domain name: example.com
Next you’ll have to decide if you’ll want others to be able to register on your instance. This is more fun but if you aren’t intending to keep the server running that’s unfair as those users will have built up their social presence.
Single user mode disables registrations and redirects the landing page to your public profile. Do you want to enable single user mode? (y/N)
And now the key question – are we using Docker? And the default aligns to that in which we are indeed doing, we are using Docker to run Mastodon;
Are you using Docker to run Mastodon? (Y/n)
Next you’ll be asked a series of questions that pertain to the docker-compose.yml and .env.production files you’ve edited. They will be which server names would be used and which is the username and password for the Postgres database. In this remember the server name or location is the name of the Docker service (db for postgres, redis for redis);
PostgreSQL host: db PostgreSQL port: 5432 Name of PostgreSQL database: mastodon_production Name of PostgreSQL user: databaseuser687 Password of PostgreSQL user: (hidden)
Then for Redis (no password):
Redis host: redis Redis port: 6379 Redis password: Redis configuration works! 🎆
Now you have to answer or decide if you want to use an S3 bucket to store your images. This is a bit of an advanced configuration so we’ll be skipping it here and answering no;
Do you want to store uploaded files on the cloud? No
Then we configure email. We have two main choices – we can send email from localhost using Sendmail or we can use a service like Mailgun which allows for SMTP services including a free tier that you would likely remain under their threshold to start.
To setup Sendmail/localhost email services;
Do you want to send e-mails from localhost? yes E-mail address to send e-mails "from": email@example.com Send a test e-mail with this configuration right now? Yes Send test e-mail to: firstname.lastname@example.org
Or we can try Mailgun;
Do you want to send e-mails from localhost? No SMTP server: smtp.mailgun.org SMTP port: 587 SMTP username: email@example.com SMTP password: (hidden) SMTP authentication: plain SMTP OpenSSL verify mode: peer E-mail address to send e-mails "from": firstname.lastname@example.org Send a test e-mail with this configuration right now? Yes Send test e-mail to: email@example.com
Ultimately this and other settings from the setup will be written back to .env.production outside of the container (if you correctly choose yes at this step in the setup);
This configuration will be written to .env.production Save configuration? (Y/n)
If you want to be safe collect the output and be sure it makes its way into .env.production that you created and edited earlier.
# Generated with mastodon:setup on 2020-11-23 20:05:57 UTC LOCAL_DOMAIN=pivpn.xyz SINGLE_USER_MODE=false SECRET_KEY_BASE=6b15f0WzOo5Vh65525db6970dffd32ff786adafa89 OTP_SECRET=e4fd904867WzOo57aea95VWzOo5Vh412f867aea95792f VAPID_PRIVATE_KEY=BjI0tZWzO7aea95o5VhziP5W7aea957M-u9gU= VAPID_PUBLIC_KEY=BBGz1wIq2j_7aea956I3cXIbs= DB_HOST=db DB_PORT=5432 DB_NAME=mastodon_production DB_USER=databaseuser687 DB_PASS=Z3vGzE5WzOo5Vhj83uvWzOo5Vhc6op7Sj REDIS_HOST=redis REDIS_PORT=6379 REDIS_PASSWORD= SMTP_SERVER=smtp.mailgun.org SMTP_PORT=587 SMTP_AUTH_METHOD=plain SMTP_OPENSSL_VERIFY_MODE=peer SMTP_FROM_ADDRESSfirstname.lastname@example.org SMTP_LOGINemail@example.com SMTP_PASSWORD=asdfasdf9iupasdiopsdfaiopasfdpifasd
Then you’ll be asked to create the database for the first time – this is dangerous if you’re already live so be careful!
Now that configuration is saved, the database schema must be loaded. If the database already exists, this will erase its contents. Prepare the database now? (Y/n)
The final step is compiling CSS/JS assets. This may take a while and consume a lot of RAM. Compile the assets now? (Y/n)
When you’re complete you’ll get a nice Mastodon logo in your terminal!
All done! You can now power on the Mastodon server 🐘
We are getting towards the end of our guide. We’ve linked to some places to find an instance of your own as well as shown the basic setup of how to get Mastodon running. Now we have an instance but it’s not up and running yet.
Before we start Mastodon for the first time we have a permissions issue with the public folder. The public folder is where Mastodon stores it’s images in the federation as well as your own posts. You’ll need to run a chown job on this folder to make sure the permissions match the container’s permissions, but you only have to do this one time;’
sudo chown -R 991:991 public
Now you’re ready to fire up the server for the first time. This is easy, you can run Mastodon and watch the logs like this;
sudo docker-compose up
Though I imagine you’ll really not care about the logs and want it running unobtrusively in the background;
sudo docker-compose up -d
You can still watch the logs with docker by combining the ability to run in the background and docker’s built in ability to watch logs (tail, follow);
sudo docker-compose up -d && docker-compose logs -f
At this point you basically have Mastodon up and running, you just need to expose it to yourself and the world. For this I suggest running a reverse proxy and using Nginx to do this is the best way (though I have run Mastodon behind Apache2 without issues).
The bonus of this is that the Mastodon development team has given us Nginx configuration examples to work from that already optimized for Mastodon (here). You’ll find the example too in the “dist” folder in the files you pulled from Github. It only takes some small changes to get this working with Nginx.
Here are the steps I took to making this work with Nginx running on the host machine (not as a container);
- Copied nginx.conf to my sites-available folder.
- Edited the file to update;
- Server Name Directive (two locations)
- Root folder directive (two locations)
That was basically it. After copying down the Mastodon Github distribution I got a huge head start. Be sure to clone the proper release tag from Github and avoid the master branch – other guides tend to miss this.