I'll go through the steps to setup a Mastodon instance on Fedora Server. This guide is based on the original Install from source guide in the Mastodon documentation, but includes Fedora-specific tweaks such as packages, file path differences, and SELinux policies. I'll first go through prerequistes and basic setup, and then branch off in the style of a choose-your-own-adventure. Section 2 is for installing a new Mastodon instance; Section 3 is for Migrating from an existing Mastodon instance; Section 4 is for setting up Mastodon with Nginx and Certbot; Section 5 is for setting up Mastodon with Caddy; Section 6 covers SELinux policy modules that need to be enabled for some critical services and executables to work.
This guide presumes the following:
I'll come back and update the guide as necessary for new releases of the software.
Become the root user and install the following packages:
dnf install postgresql-server postgresql-contrib ImageMagick ImageMagick-devel ffmpeg-free ffmpeg-free-devel libpq libpq-devel libxml2-devel libxslt-devel file git-core '@c-development' '@development-tools' protobuf-devel pkgconf-pkg-config nodejs bison openssl-devel libyaml-devel readline-devel zlib-devel ncurses-devel libffi-devel gdbm-devel redis libidn-devel libicu-devel jemalloc-devel perl-FindBin
Install corepack and set the yarn version:
npm install -g corepack corepack enable yarn set version classic
Add the mastodon user, then switch to it:
adduser -m -U mastodon su - mastodon
As the mastodon user, install rbenv and rbenv-build:
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
Install the required Ruby version:
RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 3.0.6 rbenv global 3.0.6
Install bundler:
gem install bundler --no-document
Return to the root user:
exit
Setup postgresql:
postgresql-setup --initdb --unit postgresql systemctl enable --now postgresql
Become the postgresql user and run psql:
su - postgres
psql
In the psql prompt, create the database role:
CREATE USER mastodon CREATEDB; \q
Go back to the root user:
exit
Become the mastodon user:
su - mastodon
Check out the Mastodon code:
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)
Install Ruby and JavaScript dependencies:
Note that the version of NodeJS installed on Fedora uses OpenSSL3, but Mastodon requires a version of Node with OpenSSL1.1. We can remedy this by using export NODE_OPTIONS=--openssl-legacy-provider
.
bundle config deployment 'true' bundle config without 'development test' bundle install -j$(getconf _NPROCESSORS_ONLN) export NODE_OPTIONS=--openssl-legacy-provider yarn install --pure-lockfile
This is the end of the prerequisites and basic setup. Choose one of the options below to continue.
=>
|
After running the steps from the previous section, we can now run the interactive setup wizard to setup a new Mastodon instance:
cd /home/mastodon/live export NODE_OPTIONS=--openssl-legacy-provider RAILS_ENV=production bundle exec rake mastodon:setup
This will:
Choose one of the options below to continue.
=>
|
After running the steps from the prerequisites and basic setup section, we can now start migrating the data from an existing Mastodon instance.
Stop the mastodon systemd services:
systemctl stop mastodon-web mastodon-sidekiq mastodon-streaming
Become the mastodon user:
su - mastodon
Dump the postgresql database to /home/mastodon/mastodon_production.dump
:
pg_dump -Fc mastodon_production -f mastodon_production.dump
Copy the following files from the old server machine to the same paths on the new server machine using rsync or whatever method you think best:
/home/mastodon/live/public/system
directory, which contains user-uploaded images and videos. This is not required if you're using S3.
/home/mastodon/live/.env.production
, which contains the server config and secrets.
/home/mastodon/mastodon_production.dump
Ensure the Redis server is started:
systemctl enable --now redis
Become the mastodon user:
su - mastodon
Create an empty database:
createdb -T template0 mastodon_production
Import the postgresql database:
pg_restore -Fc -U mastodon -n public --no-owner --role=mastodon -d mastodon_production mastodon_production.dump
Precompile Mastodon's assets:
cd live export NODE_OPTIONS=--openssl-legacy-provider RAILS_ENV=production bundle exec rails assets:precompile
Rebuild the home timelines for each user:
RAILS_ENV=production ./bin/tootctl feeds build
Go back to root user:
exit
As root, start the Mastodon systemd services:
systemctl enable --now mastodon-web mastodon-sidekiq mastodon-streaming
You can now update your DNS settings to point to the new server machine, rerun Certbot to update LetsEncrypt, etc. If you still need a web server setup, you can choose one of the options below, otherwise you can continue with section 6. SELinux.
=>
|
|
The Mastodon repository provides an Nginx configuration. On Fedora, the Nginx configuration path is /etc/nginx/conf.d
.
Become root on your Fedora Server and install Nginx and Certbot:
dnf install nginx certbot python3-certbot-nginx
Copy the Nginx configuration:
cp -v /home/mastodon/live/dist/nginx.conf /etc/nginx/conf.d/mastodon.conf
Edit /etc/nginx/conf.d/mastodon.conf
and change example.com
in the server_name
directive to your Mastodon domain. You can make any other adjustments you need.
Ensure the syntax of the Nginx configuration is okay:
nginx -t
To acquire an SSL certificate, ensure the HTTP ports are open in your firewall:
firewall-cmd --zone=FedoraServer --permanent --add-service=http firewall-cmd --zone=FedoraServer --permanent --add-service=https firewall-cmd --reload
Now run Certbot to obtain the certificate (change example.com to your domain):
certbot --nginx -d example.com
Enable and start Nginx:
systemctl enable --now nginx.service
You can now go to section 6. SELinux
=>
Add the Caddy repository and install Caddy:
dnf install 'dnf-command(copr)' dnf copr enable @caddy/caddy dnf install caddy
Create or edit the Caddyfile at /etc/caddy/Caddyfile
:
example.com { @local { file not path / } @local_media { path_regexp /system/(.*) } @streaming { path /api/v1/streaming/* } @cache_control { path_regexp ^/(emoji|packs|/system/accounts/avatars|/system/media_attachments/files) } root * /home/mastodon/live/public log { output file /var/log/caddy/mastodon.log } encode zstd gzip handle_errors { rewrite 500.html file_server } header { Strict-Transport-Security "max-age=31536000" } header /sw.js Cache-Control "public, max-age=0" header @cache_control Cache-Control "public, max-age=31536000, immutable" handle @local { file_server } reverse_proxy @streaming { to http://localhost:4000 transport http { keepalive 5s keepalive_idle_conns 10 } } reverse_proxy { to http://localhost:3000 header_up X-Forwarded-Port 443 header_up X-Forwarded-Proto https transport http { keepalive 5s keepalive_idle_conns 10 } } }
To allow Caddy to access files in the user home directory, the executable bit needs to be set on the parent directories of the files being served:
chmod +x /home/mastodon/live/public chmod +x /home/mastodon/live chmod +x /home/mastodon chmod +x /home
You can now go to section 6. SELinux
=>
At this point, a web server should be running, but if SELinux is in enforcing mode, you will get a 502 Bad Gateway error if you try to browse to your Mastodon domain. The problem is that SELinux is not allowing the web server daemon to access files in /home/mastodon/live
. This can be verified by running:
ausearch -m AVC -ts recent
This can be fixed by setting the following SELinux booleans:
setsebool -P httpd_read_user_content=1 setsebool -P httpd_enable_homedirs=1
You'll need to set an SELinux policy to allow Caddy to write to /var/log/caddy
:
module caddy 1.0; require { type httpd_log_t; type httpd_t; class file write; } #============= httpd_t ============== allow httpd_t httpd_log_t:file write;
Save this to a file named caddy.te
. Now check, compile, and import the module:
checkmodule -M -m -o caddy.mod caddy.te semodule_package -o caddy.pp -m caddy.mod semodule -i caddy.pp
Set the SELinux booleans for httpd:
setsebool -P httpd_read_user_content=1 setsebool -P httpd_enable_homedirs=1
Restart Caddy.
SELinux also denies the /home/mastodon/.rbenv/shims/bundle
executable. This can be verified by looking at journalctl -xeu mastodon-web.service
and ausearch -m AVC -ts recent
.
You'll need the following SELinux policy for bundle to work:
module bundle 1.0; require { type init_t; type user_home_t; class file { execute execute_no_trans open read }; } #============= init_t ============== allow init_t user_home_t:file { execute execute_no_trans open read };
Save this to a file named bundle.te
. Now check, compile, and import the module:
checkmodule -M -m -o bundle.mod bundle.te semodule_package -o bundle.pp -m bundle.mod semodule -i bundle.pp
Restart the Mastodon systemd services:
systemctl restart mastodon-web mastodon-streaming mastodon-sidekiq
Your Mastodon instance should now be up and running!
If you have any questions, want to report any errors, or have any suggestions for improving this article, you can find me at the following places. You can also open up an issue in the GitHub interface.
Last updated: 2023-08-30
=> tech guides archive | hyperreal.coffee This content has been proxied by September (ba2dc).Proxy Information
text/gemini