
This article provides a guide demonstrating how to install and run Mastodon server on AlmaLinux VPS.
What is Mastodon?
Mastodon is a social networking platform similar to X/Twitter, but with one major difference: no single company controls the entire network.
Instead, Mastodon is made up of independently operated servers called instances. Each instance can have its own rules, moderators, and community focus, while users on different instances can generally follow and interact with one another.
A few key ideas:
- Decentralized: There isn’t one central Mastodon website controlling everyone. You choose a server when creating an account.
- Federated: Those independent servers communicate using the ActivityPub protocol. Together they form part of the broader Fediverse.
- Twitter-like experience: You can post short messages, images, videos, polls, follow people, reply, favorite, and boost other people’s posts.
- Usernames include the server: An account might look like
@radwebhosting@mastodon.social, somewhat like an email address. - Different moderation policies: Each server operator decides what is permitted on their server and which other servers it will communicate with.
- Open source: Mastodon’s server software is open source, so organizations and individuals can operate their own Mastodon servers.
One useful way to picture it is email combined with Twitter. Gmail and Outlook are separate services, but a Gmail user can email an Outlook user. Similarly, someone on one Mastodon server can usually follow someone on another Mastodon server.
This is also why Mastodon can be interesting for a company: you can run something like social.example.com, control your own community and moderation policies, and still participate in the larger Mastodon/Fediverse network.
This guide installs Mastodon directly from source on an AlmaLinux VPS, using PostgreSQL, Redis, Nginx, systemd, and Let’s Encrypt SSL.
It is written for Mastodon 4.6.x. As of August 2026, the latest stable release is Mastodon 4.6.4. Mastodon 4.6 requires Ruby 3.3+, PostgreSQL 14+, Redis 7+, Node.js 22+, libvips 8.13+, and FFmpeg 5.1+.
Mastodon’s official source-installation documentation currently targets Ubuntu 24.04 and Debian 13, so the operating-system commands below have been adapted for AlmaLinux while preserving Mastodon’s standard deployment layout.
Recommended VPS specifications
For a small personal or community Mastodon instance, start with approximately:
- CPU: 2-4 vCPU
- RAM: 4 GB minimum; 8 GB recommended
- Storage: 40-80 GB SSD/NVMe minimum
- OS: AlmaLinux 9 x86_64
- IPv4: Public static IPv4 recommended
- Domain: social.example.com
Storage consumption can grow rapidly because Mastodon caches media from remote instances. For a public instance, object storage such as S3-compatible storage is eventually preferable to keeping all media on the VPS.
See Also: Install and Configure SOCKS Proxy Server on Rocky Linux VPS
You will also need an SMTP provider. Mastodon uses email for account confirmation, password resets, notifications, and administrative messages. The official installation prerequisites explicitly include an SMTP/email-delivery service.
SEE ALSO: Configure Postfix MTA for Use with Mastodon
Throughout this guide, replace social.example.com with your actual Mastodon hostname.
Before proceeding, create an A DNS record such as:
social.example.com -> YOUR_VPS_IPV4
Verify it:
dig +short social.example.com
Compare AlmaLinux VPS Plans
How to Install and Run Mastodon Server on AlmaLinux VPS
To install and run Mastodon server on AlmaLinux VPS, follow the steps provided below:
-
Connect to the VPS and Update AlmaLinux
ssh root@YOUR_SERVER_IP
Update all installed packages:
dnf update -y
Reboot if a new kernel was installed:
reboot
Reconnect afterward.
Check the operating system:
cat /etc/almalinux-release
-
Enable EPEL and CRB
A number of Mastodon dependencies are supplied through EPEL and CRB.
Install EPEL:
dnf install -y epel-release
Enable CRB:
See Also: 🚀 Deploy Virtualmin on AlmaLinux VPS (5 Minute Quick-Start Guide)
dnf config-manager --set-enabled crb
AlmaLinux documentation recommends EPEL and CRB for software and development dependencies outside the base repositories.
Refresh the metadata:
dnf makecache
-
Install development packages
Install basic build tools:
dnf groupinstall -y "Development Tools"
Install the libraries Mastodon and Ruby commonly require:
dnf install -y \ git \ curl \ nano \ wget \ tar \ file \ gcc \ gcc-c++ \ make \ autoconf \ bison \ pkgconf-pkg-config \ openssl-devel \ libyaml-devel \ readline-devel \ zlib-devel \ libffi-devel \ gdbm-devel \ libicu-devel \ libidn2-devel \ libxslt-devel \ jemalloc \ jemalloc-devel \ protobuf-compiler \ nginx \ certbot \ firewalld \ libidn \ libidn-devel \ python3-certbot-nginx \ policycoreutils-python-utils
-
Install libvips
Mastodon 4.6 uses libvips for image processing; ImageMagick is no longer supported as the Mastodon 4.6 image-processing backend.
Install it:
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm dnf install -y http://rpms.remirepo.net/enterprise/remi-release-9.rpm dnf --enablerepo=remi install -y vips vips-devel vips-tools
Verify:
vips --version
You need at least libvips 8.13 for Mastodon 4.6.
-
Install FFmpeg
Mastodon needs FFmpeg for video and audio processing.
If
ffmpegis already available from your enabled repositories:dnf install -y ffmpeg
Verify:
ffmpeg -version
Mastodon 4.6 requires FFmpeg 5.1 or newer. Also keep FFmpeg fully patched: Mastodon specifically advised non-Docker installations to use a fixed FFmpeg release after a critical 2026 FFmpeg vulnerability.
If AlmaLinux cannot find
ffmpeg, enable RPM Fusion Free and then install it:dnf install -y https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-$(rpm -E %rhel).noarch.rpm dnf update --refresh dnf install -y ffmpeg
-
Install Node.js 22
AlmaLinux 9’s current AppStream includes Node.js 22 packages, which satisfies Mastodon 4.6’s Node 22+ requirement.
Check available streams/packages first:
dnf module list nodejs
If Node.js 22 appears as a module:
dnf module reset nodejs -y dnf module enable nodejs:22 -y dnf install -y nodejs npm
Otherwise, on newer AlmaLinux 9 releases where it is available directly:
dnf install -y nodejs npm
Verify:
node --version npm install -g corepack
You should see Node 22 or newer:
v22.x.x
Enable Corepack, which Mastodon uses to select the appropriate Yarn release:
corepack enable
Mastodon’s official installation process likewise uses Corepack for Yarn.
Check:
yarn --version
-
Install PostgreSQL 16
Mastodon 4.6 requires PostgreSQL 14 or newer. PostgreSQL 16 is a good choice for a new installation.
Current RHEL-family documentation lists PostgreSQL 16 as available for AlmaLinux 9.
Check available PostgreSQL modules:
dnf module list postgresql
Reset any previously selected stream:
dnf module reset postgresql -y
Enable PostgreSQL 16:
See Also: How to Run Self-Hosted Link-in-Bio Tool with LinkStack on AlmaLinux VPS
dnf module enable postgresql:16 -y
Install it:
dnf install -y \ postgresql \ postgresql-server \ postgresql-contrib \ postgresql-devel
Initialize the database:
postgresql-setup --initdb
Enable and start PostgreSQL:
systemctl enable --now postgresql
Check:
systemctl status postgresql
And:
psql --version
-
Create the Mastodon PostgreSQL user
The simplest local setup uses PostgreSQL peer authentication, where the Linux
mastodonaccount corresponds to a PostgreSQL role namedmastodon. This is also the approach recommended in Mastodon’s standard source-install documentation.Open PostgreSQL:
sudo -u postgres psql
Create the role:
CREATE USER mastodon CREATEDB;
Exit:
\q
You do not need to create the Mastodon database manually because the Mastodon setup task can do that.
-
Install Redis 7+
Redis stores caches and queues used by Sidekiq and other Mastodon components.
Mastodon 4.6 requires Redis 7.0 or newer.
Redis publishes an RPM repository specifically compatible with AlmaLinux 9.
Create:
sudo tee /etc/yum.repos.d/redis.repo << 'EOF' [Redis] name=Redis baseurl=http://packages.redis.io/rpm/rockylinux9 enabled=1 gpgcheck=1 EOF
with the Redis repository configuration documented for AlmaLinux 9, import its official signing key, and then install:
dnf install -y redis
Enable Redis:
systemctl enable --now redis
Check:
redis-server --version
and:
redis-cli ping
Expected result:
PONG
Do not expose Redis port
6379publicly. Mastodon only needs to connect to it locally. -
Create the Mastodon system user
Create an unprivileged account:
useradd -m -s /bin/bash mastodon
Check it:
id mastodon
You should now have:
/home/mastodon
Mastodon itself should never run as root.
-
Download Mastodon
Switch users:
su - mastodon
Clone Mastodon:
git clone https://github.com/mastodon/mastodon.git live && cd live
The official installation procedure selects the newest stable version tag rather than running directly from the development branch.
Select the newest stable tag:
git checkout "$(git tag -l | grep '^v[0-9.]*$' | sort -V | tail -n 1)"
Check the version:
git describe --tags
At the time this guide was written, the latest stable release is
v4.6.4released July 27, 2026. -
Install Ruby with rbenv
Do this while logged in as
mastodon.Mastodon’s official installation procedure recommends rbenv, because the repository specifies its required Ruby version and rbenv simplifies future upgrades.
Install rbenv:
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
Add it to the shell:
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc echo 'eval "$(rbenv init - bash)"' >> ~/.bashrc source ~/.bashrc
Install ruby-build:
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
Return to Mastodon:
See Also: 🚀 How to Deploy MongoDB on Ubuntu VPS (5 Minute Quick-Start Guide)
cd ~/live
The repository contains a
.ruby-versionfile, so rbenv can install the exact required Ruby release automatically.Install it with jemalloc support:
RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install
Set the repository’s Ruby version:
rbenv local "$(cat .ruby-version)"
Verify:
ruby --version
Mastodon 4.6 requires Ruby 3.3 or newer.
-
Install Ruby and JavaScript dependencies
Install Bundler if required:
gem install bundler --no-document rbenv rehash
Configure Bundler for production:
bundle config set deployment true bundle config set without development test
Install Ruby dependencies:
bundle install
Enable Corepack for this account as well if necessary:
corepack enable
Install JavaScript packages:
yarn install --immutable
If the installed Mastodon version does not accept
--immutable, use the exact Yarn command indicated by that release’s documentation or lockfile. Current 4.6 update instructions use immutable Yarn installs. -
Run the Mastodon setup wizard
Remain logged in as
mastodon:cd ~/live RAILS_ENV=production bin/rails mastodon:setup
This is Mastodon’s official interactive installer. It creates
.env.production, initializes the database schema, and builds the application assets.The exact questions can change slightly between Mastodon versions. A typical configuration looks like:
Domain name: social.example.com Do you want to enable single user mode? No Are you using Docker to run Mastodon? No PostgreSQL host: /var/run/postgresql PostgreSQL port: 5432 PostgreSQL database: mastodon_production PostgreSQL user: mastodon PostgreSQL password: [leave blank when using peer authentication] Redis host: localhost Redis port: 6379 Redis password: [leave blank unless you configured one]
The wizard will also generate application secrets.
SMTP configuration
Enter your SMTP provider information. For example:
SMTP server: smtp.example.net SMTP port: 587 SMTP username: YOUR_SMTP_USERNAME SMTP password: YOUR_SMTP_PASSWORD SMTP authentication: plain SMTP OpenSSL verify mode: peer E-mail address to send e-mails "from": Mastodon <notifications@example.com>
Use the exact host, port, authentication method, TLS settings, username, and password supplied by your mail provider.
When prompted, allow the installer to:
prepare the database compile assets
You can also let the wizard create your initial administrator account.
The resulting configuration is stored at:
/home/mastodon/live/.env.production
Protect it:
chmod 600 ~/.env.production
Exit back to root:
exit
-
Review the Mastodon configuration
As root:
sudo -u mastodon nano /home/mastodon/live/.env.production
Important settings will resemble:
LOCAL_DOMAIN=social.example.com DB_HOST=/var/run/postgresql DB_USER=mastodon DB_NAME=mastodon_production REDIS_HOST=localhost REDIS_PORT=6379 SMTP_SERVER=smtp.example.net SMTP_PORT=587 SMTP_LOGIN=YOUR_SMTP_USERNAME SMTP_PASSWORD=YOUR_SMTP_PASSWORD SMTP_FROM_ADDRESS=notifications@example.com
Never publish this file. It contains secrets that can compromise your Mastodon installation.
-
Configure Nginx
Mastodon includes an Nginx configuration template. The official installation documentation recommends copying this template and modifying it for your hostname.
See Also: 🚀 Deploy Docmost on Ubuntu VPS
On AlmaLinux, use
/etc/nginx/conf.dinstead of Debian’ssites-availablelayout:cp /home/mastodon/live/dist/nginx.conf /etc/nginx/conf.d/mastodon.conf
Edit it:
nano /etc/nginx/conf.d/mastodon.conf
Replace every occurrence of:
example.com
with:
social.example.com
Confirm that the document root is:
root /home/mastodon/live/public;
Temporarily leave the SSL certificate directives disabled until Certbot has obtained the certificate.
Test Nginx:
nginx -t
If successful:
syntax is ok test is successful
Enable Nginx:
systemctl enable --now nginx
-
Configure SELinux
Do not disable SELinux simply to make Mastodon work.
First allow Nginx to traverse the Mastodon home directory:
chmod o+x /home/mastodon
Give the Mastodon public directory the appropriate web-server SELinux context:
semanage fcontext -a -t httpd_sys_content_t "/home/mastodon/live/public(/.*)?" restorecon -Rv /home/mastodon/live/public
Mastodon’s Nginx frontend also needs permission to connect to the Mastodon application processes on localhost:
setsebool -P httpd_can_network_connect 1
Confirm SELinux remains enforcing:
getenforce
Expected:
Enforcing
-
Configure firewalld
Check whether firewalld is running:
systemctl status firewalld
If you use it, allow HTTP and HTTPS:
firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https firewall-cmd --reload
Verify:
firewall-cmd --list-services
You should see at least:
http https ssh
Do not open PostgreSQL
5432, Redis6379, Mastodon Puma3000, or streaming4000to the Internet for this single-server configuration. -
Obtain a Let’s Encrypt SSL certificate
Make sure:
social.example.com
already resolves publicly to the VPS.
Then obtain the certificate:
certbot certonly --nginx -d social.example.com
Mastodon’s official setup also uses Certbot/Let’s Encrypt before enabling the final HTTPS configuration.
Your certificate should be stored under:
/etc/letsencrypt/live/social.example.com/
Edit:
nano /etc/nginx/conf.d/mastodon.conf
Enable or set:
ssl_certificate /etc/letsencrypt/live/social.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/social.example.com/privkey.pem;
Test:
nginx -t
Restart:
systemctl restart nginx
Test certificate renewal:
certbot renew --dry-run
-
Install the Mastodon systemd services
Mastodon provides service definitions for its three principal application components:
See Also: How to Restore Your Website Using JetBackup in cPanel (Fast 5 Step Guide)
mastodon-web mastodon-sidekiq mastodon-streaming
Copy them:
cp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/
This is also Mastodon’s official deployment method.
Inspect them:
grep -E 'User=|WorkingDirectory|ExecStart' /etc/systemd/system/mastodon-*.service
Make sure they reference:
User=mastodon /home/mastodon/live
Reload systemd:
systemctl daemon-reload
Enable and start all Mastodon processes:
systemctl enable --now \ mastodon-web \ mastodon-sidekiq \ mastodon-streaming
The official Mastodon installation instructions use the same three units.
-
Verify all Mastodon services
Check:
systemctl status mastodon-web
systemctl status mastodon-sidekiq
systemctl status mastodon-streaming
All three should report:
active (running)
Check the backend ports:
ss -lntp | grep -E '3000|4000'
Typically:
127.0.0.1:3000 127.0.0.1:4000
The services should remain bound locally and be accessed externally only through Nginx.
-
Check the website
Open:
https://social.example.com
You should see the Mastodon interface.
You can also test locally:
curl -I https://social.example.com
A normal response should include an HTTP success or redirect status rather than a
502 Bad Gateway. -
Create or promote the administrator account
If you did not create an administrator during
mastodon:setup, create one from the command line:su - mastodon cd ~/live RAILS_ENV=production bin/tootctl accounts create admin \ --email admin@example.com \ --confirmed \ --role Owner
Mastodon will output a generated password.
Sign in immediately and change it to a strong password.
If the user already exists, assign the appropriate administrative role using the
tootctl accountscommands supported by your installed Mastodon release.Exit:
exit
-
Verify email delivery
Email is one of the most common sources of problems on a new Mastodon server.
Watch Sidekiq:
journalctl -u mastodon-sidekiq -f
Then generate an email from Mastodon—for example, a password reset or account confirmation.
If messages fail, verify:
SMTP hostname SMTP port SMTP username SMTP password TLS mode sender/domain verification SPF DKIM DMARC
For production use, an external transactional email provider is generally more reliable than trying to deliver mail directly from the VPS.
-
Useful log commands
Follow Mastodon’s web-service logs:
journalctl -u mastodon-web -f
Sidekiq:
journalctl -u mastodon-sidekiq -f
Streaming:
journalctl -u mastodon-streaming -f
Nginx:
tail -f /var/log/nginx/error.log
PostgreSQL:
journalctl -u postgresql -f
Redis:
journalctl -u redis -f
View recent errors from all Mastodon units:
journalctl \ -u mastodon-web \ -u mastodon-sidekiq \ -u mastodon-streaming \ --since "30 minutes ago"
-
Common 502 Bad Gateway troubleshooting
First check the Mastodon web process:
See Also: How to Install Prometheus on Debian VPS
systemctl status mastodon-web
Then:
journalctl -u mastodon-web -n 100 --no-pager
Check whether port 3000 is listening:
ss -lntp | grep 3000
Test the application directly:
curl -I http://127.0.0.1:3000
If that works but Nginx returns
502, check:nginx -t tail -100 /var/log/nginx/error.log
On AlmaLinux, an SELinux denial is also a common cause. Check:
ausearch -m AVC -ts recent
Make sure:
setsebool -P httpd_can_network_connect 1
has been applied.
-
Test PostgreSQL and Redis
As the
mastodonLinux user:sudo -u mastodon psql mastodon_production
If PostgreSQL peer authentication is configured correctly, this should connect without requesting a password.
Exit:
\q
Redis:
redis-cli ping
Expected:
PONG
-
Check Mastodon from Rails
Run:
su - mastodon cd ~/live RAILS_ENV=production bin/rails runner 'puts Mastodon::Version.to_s'
This should print your installed Mastodon version.
Exit:
exit
-
Back up Mastodon
At minimum, back up three things:
PostgreSQL database .env.production uploaded/local media
For PostgreSQL:
sudo -u postgres pg_dump -Fc mastodon_production > /root/mastodon-$(date +%F).dump
Back up configuration:
cp /home/mastodon/live/.env.production \ /root/mastodon-env-$(date +%F)
If using local file storage, back up:
/home/mastodon/live/public/system
A proper production deployment should copy backups to a different server or object-storage provider rather than leaving them on the Mastodon VPS.
-
Updating Mastodon
Always read the release notes for every version you are crossing before upgrading. Mastodon frequently includes release-specific database migrations or asset-build instructions. The project explicitly warns administrators to read skipped-release upgrade notes.
First back up the database.
Then:
su - mastodon cd ~/live
Fetch releases:
git fetch --tags
Determine the stable release you want to install and check it out, for example:
git checkout v4.6.4
Update Ruby if
.ruby-versionchanged:RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install
Install updated Ruby dependencies:
bundle install
Install frontend dependencies:
yarn install --immutable
Run database migrations:
RAILS_ENV=production bundle exec rails db:migrate
Precompile assets when required:
RAILS_ENV=production bundle exec rails assets:precompile
Exit:
exit
Restart Mastodon:
systemctl restart \ mastodon-web \ mastodon-sidekiq \ mastodon-streaming
Current Mastodon 4.6 non-Docker upgrade notes explicitly call for dependency installation, asset compilation when required, and restarting Mastodon processes.
-
Basic production security checklist
Keep AlmaLinux updated:
dnf update -y
Keep SELinux enabled:
getenforce
Keep PostgreSQL and Redis restricted to localhost.
Only expose externally:
22/tcp SSH 80/tcp HTTP 443/tcp HTTPS
For SSH, consider:
SSH keys instead of passwords PermitRootLogin prohibit-password Fail2ban or equivalent protection a non-default administrative account
Also make sure you have:
See Also: How to Install GoToSocial on Rocky Linux VPS (10 Minute Launch Guide 🚀)
automated off-server database backups media backups/object storage working SSL renewal working SMTP delivery SPF DKIM DMARC filesystem monitoring adequate disk-space alerts
-
Optional: use object storage
For anything beyond a tiny instance, moving Mastodon media to S3-compatible object storage is worth considering.
It prevents cached federated media from consuming your VPS system disk and makes future server migrations easier.
Typical
.env.productionoptions include settings for:S3_ENABLED S3_BUCKET S3_REGION S3_HOSTNAME AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY
Consult the Mastodon configuration documentation for the exact variables appropriate to your object-storage provider and Mastodon release.
Restart the Mastodon services after changing
.env.production. -
Optional: full-text search
Mastodon can operate without Elasticsearch/OpenSearch, but installing a compatible search backend provides substantially better full-text search capabilities.
Mastodon 4.6 lists Elasticsearch 7.x as recommended, with OpenSearch also supported.
For a small VPS, consider leaving search disabled initially because Elasticsearch/OpenSearch can consume significant additional RAM.
-
Final service check
Run:
systemctl is-active nginx systemctl is-active postgresql systemctl is-active redis systemctl is-active mastodon-web systemctl is-active mastodon-sidekiq systemctl is-active mastodon-streaming
Each should return:
active
Check certificates:
certbot certificates
Check disk space:
df -h
Check memory:
free -h
Check Mastodon:
curl -I https://social.example.com
At this point your AlmaLinux VPS should be running a production-style Mastodon stack:
Internet | v Nginx :443 | +----> Mastodon Web / Puma :3000 | +----> Mastodon Streaming :4000 Mastodon | +----> PostgreSQL | +----> Redis | +----> Sidekiq | +----> SMTP provider
Nginx handles the public HTTP/HTTPS connections, Mastodon’s Rails/Puma process serves the application, the streaming service handles real-time connections, Sidekiq processes background jobs, PostgreSQL stores persistent application data, and Redis handles queues and transient/cache data.
This follows Mastodon’s standard three-service systemd architecture while adapting the package management, Nginx layout, firewall, PostgreSQL initialization, and SELinux configuration for AlmaLinux.
Conclusion
You now know how to install and run Mastodon server on AlmaLinux VPS.









