This article is my personal snippet for running Mastodon instance on Ubuntu 20.04 from source. I use self-signed certificate instead of cerbot because the instance will be run behind Cloudflare reverse proxy.
The asciinema video below is the whole process I install Mastodon instance (for reference)
Or the whole YouTube video:
Before starting, there are several things that need to be fulfilled:
- Fresh Ubuntu
20.04server with root access.
- Domain name (or sub-domain) for the Mastodon instance (in this case I'm using
vr4.meand the Mastodon instance will be accessed from
- SMTP Server for email delivery service.
Preparing the system
First, make sure the Ubuntu server we're using is up to date.
apt update && apt upgrade
apt install -y curl wget gnupg apt-transport-https lsb-release ca-certificates
curl -sL https://deb.nodesource.com/setup_16.x | bash -
wget -O /usr/share/keyrings/postgresql.asc https://www.postgresql.org/media/keys/ACCC4CF8.asc echo "deb [signed-by=/usr/share/keyrings/postgresql.asc] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/postgresql.list
Update and install required system package:
apt update apt install -y \ imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core \ g++ libprotobuf-dev protobuf-compiler pkg-config nodejs gcc autoconf \ bison build-essential libssl-dev libyaml-dev libreadline6-dev \ zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev \ nginx redis-server redis-tools postgresql postgresql-contrib \ certbot python3-certbot-nginx libidn11-dev libicu-dev libjemalloc-dev
corepack feature and set Yarn version to
corepack enable yarn set version classic
Install Ruby with
rbenvmust be installed for a single Linux user, therefore, first we must create linux user where Mastodon services will be running as (we'll create
adduser --disabled-login mastodon
Then switch to
su - mastodon
mastodon user, proceed to install
git clone https://github.com/rbenv/rbenv.git ~/.rbenv cd ~/.rbenv && src/configure && make -C src echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc echo 'eval "$(rbenv init -)"' >> ~/.bashrc exec bash git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
Once Ruby environment setup is done, we can than install the required Ruby version and
RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 3.0.4 rbenv global 3.0.4 gem install bundler --no-document
Return to the root user:
Setting up PostgreSQL
For optimal performance, you may use pgTune to generate an appropriate configuration and edit values in
/etc/postgresql/15/main/postgresql.conf before restarting PostgreSQL with
systemctl restart postgresql.
Now, create a PostgreSQL user that Mastodon service could use. The easiest way is with
ident authentication so the PostgreSQL user does not have a separate password and can be used by the Linux user with the same username.
Open PostgreSQL prompt:
sudo -u postgres psql
psql prompt, execute:
CREATE USER mastodon CREATEDB; \q
The core system requirement is now ready, now we can move forward to setting up Mastodon instance along with it's dependency.
Setting up Mastodon
It is time to download the Mastodon code. Switch to the
su - mastodon
git to download the latest
stable release of Mastodon:
git clone https://github.com/mastodon/mastodon.git live && cd live git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)
bundle config deployment 'true' bundle config without 'development test' bundle install -j$(getconf _NPROCESSORS_ONLN) yarn install --pure-lockfile
Run the interactive setup wizard:
RAILS_ENV=production bundle exec rake mastodon:setup
The command above will be:
- Create a configuration file
- Run asset pre-compilation
- Create the database schema
The configuration file is saved as
In my case, I want Mastodon instance can be accessed from
https://social.vr4.me but use my main domain identity to serve
@[email protected] (instead of
@[email protected]) So I need to change
LOCAL_DOMAIN configuration value to
vr4.me and add
WEB_DOMAIN=social.vr4.me in the
.env.production file configuration. Please refer to documentation on configuration for more detailed information.
When done with the configuration we can switch back to
Setting up Nginx
Copy the Nginx configuration template that comes from Mastodon repository:
cp /home/mastodon/live/dist/nginx.conf /etc/nginx/sites-available/mastodon ln -s /etc/nginx/sites-available/mastodon /etc/nginx/sites-enabled/mastodon
/etc/nginx/sites-available/mastodon and replace
example.com to our domain name (in my case
As I said before, the instance will be serve behind Cloudflare reverse proxy and I don't want to use certbot to issue my SSL certificate. So I use my own self-signed certificate.
If you want to use certbot to issue the SSL certificate:
systemctl reload nginx certbot --nginx -d social.vr4.me
social.vr4.me with your domain name.
Setting up Mastodon systemd services
systemd service templates from the Mastodon directory to
cp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/
Finally, start and enable Mastodon services:
systemctl daemon-reload systemctl enable --now mastodon-web mastodon-sidekiq mastodon-streaming
Wait for a few minutes and try to access your instance from your web browser, and enjoy your self-hosted Twitter alternative!
If you want to join my instance, please do so : https://social.vr4.me/invite/G2BtoAfD. The data stored somewhere in Indonesia.