Upgrading a self-hosted Mastodon instance ensures you receive security patches, new features, and performance improvements. But a failed upgrade can cause downtime, data loss, or a broken federation connection. The primary risk is database schema changes that do not roll back cleanly if the upgrade stops mid-process. This article explains the exact steps to prepare, execute, and verify a Mastodon instance upgrade without losing data or connectivity.
Key Takeaways: Safe Mastodon Instance Upgrade
- Backup the database and system files before any upgrade: Use pg_dump for PostgreSQL and copy the .env.production and public/system directories.
- Read the official release notes on GitHub: Check for breaking changes, new dependencies, or manual migration steps in the changelog.
- Run the upgrade in maintenance mode: Enable maintenance mode in the Mastodon admin panel to prevent user activity during migration.
Understanding Mastodon Upgrade Risks and Requirements
Mastodon is built with Ruby on Rails and uses PostgreSQL as its database. Upgrades typically involve updating the Ruby version, Node.js, Yarn, and the Mastodon source code itself. The most dangerous step is the database migration, which modifies the schema. If the migration fails partway, the database may end up in an inconsistent state that is difficult to reverse manually.
A second risk is version incompatibility. Mastodon requires specific versions of Ruby, Node.js, and PostgreSQL. Upgrading only Mastodon without updating these dependencies can cause the application to crash on startup. The official Mastodon repository provides a docker-compose.yml file for Docker-based deployments and installation guides for manual setups. Always match the version requirements listed in the release notes.
The third common failure point is the Sidekiq background job queue. During an upgrade, old jobs may remain in the queue and fail when processed against the new code. This can lead to stuck notifications, broken timelines, or failed federation pushes. Draining the queue before the upgrade prevents these issues.
Steps to Upgrade a Self-Hosted Mastodon Instance Safely
The following steps assume you have SSH access to the server and are using a manual installation with systemd services. If you use Docker, adapt the commands to match your container setup. Always test the upgrade on a staging environment first if possible.
- Back up the database and configuration files
Runpg_dump -Fc mastodon_production > /tmp/mastodon_backup.dumpto create a compressed PostgreSQL backup. Copy the.env.productionfile and thepublic/systemdirectory to a safe location outside the server. These contain all user-uploaded media. - Enable maintenance mode in the Mastodon admin panel
Log in to your Mastodon admin interface. Go to Administration > Server Settings > Maintenance. Toggle the maintenance mode switch on. This shows a static page to visitors and prevents new posts, follows, or API calls during the upgrade. - Drain the Sidekiq job queue
Stop the Sidekiq service withsystemctl stop mastodon-sidekiq. Then runcd /home/mastodon/live && RAILS_ENV=production bin/tootctl sidekiq killallto remove all pending jobs. This prevents old jobs from failing after the upgrade. - Stop the Mastodon web and streaming services
Runsystemctl stop mastodon-webandsystemctl stop mastodon-streaming. This ensures no new requests reach the application while you update the code. - Update system dependencies
Check the release notes for required Ruby and Node.js versions. For example, if Mastodon v4.2 requires Ruby 3.2, update it withrbenv install 3.2.2 && rbenv global 3.2.2. Update Node.js usingnvm install 20or your package manager. - Pull the latest Mastodon source code
Switch to the mastodon user:su - mastodon. Navigate to the live directory:cd /home/mastodon/live. Fetch the latest release:git fetch origin && git checkout v4.2.1(replace the tag with the version you want). - Install updated Ruby gems and JavaScript packages
Runbundle install --deployment --without development testto install new gems. Then runyarn install --frozen-lockfileto install JavaScript dependencies. These commands may take several minutes. - Run database migrations
ExecuteRAILS_ENV=production bin/rails db:migrate. This applies any schema changes. Watch for errors in the output. If a migration fails, restore the backup and investigate the cause before retrying. - Precompile assets
RunRAILS_ENV=production bin/rails assets:precompile. This generates updated CSS and JavaScript files. Skipping this step can cause broken layouts or missing icons. - Restart Mastodon services
Exit the mastodon user session. Start all services:systemctl start mastodon-web mastodon-streaming mastodon-sidekiq. Check their status withsystemctl status mastodon-webto confirm they are active. - Disable maintenance mode
Return to the admin panel and toggle maintenance mode off. The instance is now live with the new version. - Verify federation and basic functions
Post a public status and check that it appears on the federated timeline. Send a direct message to a user on another instance. Confirm that the web interface loads without errors. Check the server logs atjournalctl -u mastodon-web -ffor any warnings.
Common Upgrade Failures and How to Handle Them
Database migration fails with a syntax error
This usually happens when the Ruby gem versions do not match the Mastodon release. Restore the database from the backup using pg_restore -d mastodon_production /tmp/mastodon_backup.dump. Then verify that you ran bundle install successfully and that the Gemfile.lock file is up to date. Try the migration again.
Sidekiq workers crash after upgrade
If you did not drain the queue before the upgrade, old jobs may reference removed classes or methods. Stop Sidekiq again and run bin/tootctl sidekiq killall. Then restart Sidekiq. If crashes persist, check the Sidekiq logs at /home/mastodon/live/log/sidekiq.log for specific error messages.
Web interface shows a blank page or 500 errors
This is often caused by missing precompiled assets. Run RAILS_ENV=production bin/rails assets:precompile again and restart the web service. If the issue continues, verify that the public/assets directory contains the compiled files and that the web server is pointing to the correct path.
Federation stops working after upgrade
Federation issues usually stem from an outdated Node.js version or a missing streaming service. Confirm that mastodon-streaming is running and that port 4000 is open in your firewall. Restart the streaming service with systemctl restart mastodon-streaming and test federation by following a remote account.
| Item | Manual Installation | Docker Installation |
|---|---|---|
| Backup method | pg_dump, cp for files | docker exec pg_dump, docker cp |
| Service stop | systemctl stop mastodon- | docker-compose down |
| Code update | git checkout tag | docker-compose pull |
| Dependency install | bundle install, yarn install | docker-compose build |
| Migration command | RAILS_ENV=production bin/rails db:migrate | docker-compose run web rails db:migrate |
| Service start | systemctl start mastodon- | docker-compose up -d |
You can now upgrade your Mastodon instance with confidence. Before each future upgrade, always review the changelog on the official Mastodon GitHub repository. As an advanced tip, set up a cron job that runs a nightly pg_dump to /var/backups so you always have a recent backup ready before any maintenance.