How to Upgrade a Self-Hosted Mastodon Instance Safely
🔍 WiseChecker

How to Upgrade a Self-Hosted Mastodon Instance Safely

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.

  1. Back up the database and configuration files
    Run pg_dump -Fc mastodon_production > /tmp/mastodon_backup.dump to create a compressed PostgreSQL backup. Copy the .env.production file and the public/system directory to a safe location outside the server. These contain all user-uploaded media.
  2. 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.
  3. Drain the Sidekiq job queue
    Stop the Sidekiq service with systemctl stop mastodon-sidekiq. Then run cd /home/mastodon/live && RAILS_ENV=production bin/tootctl sidekiq killall to remove all pending jobs. This prevents old jobs from failing after the upgrade.
  4. Stop the Mastodon web and streaming services
    Run systemctl stop mastodon-web and systemctl stop mastodon-streaming. This ensures no new requests reach the application while you update the code.
  5. 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 with rbenv install 3.2.2 && rbenv global 3.2.2. Update Node.js using nvm install 20 or your package manager.
  6. 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).
  7. Install updated Ruby gems and JavaScript packages
    Run bundle install --deployment --without development test to install new gems. Then run yarn install --frozen-lockfile to install JavaScript dependencies. These commands may take several minutes.
  8. Run database migrations
    Execute RAILS_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.
  9. Precompile assets
    Run RAILS_ENV=production bin/rails assets:precompile. This generates updated CSS and JavaScript files. Skipping this step can cause broken layouts or missing icons.
  10. Restart Mastodon services
    Exit the mastodon user session. Start all services: systemctl start mastodon-web mastodon-streaming mastodon-sidekiq. Check their status with systemctl status mastodon-web to confirm they are active.
  11. Disable maintenance mode
    Return to the admin panel and toggle maintenance mode off. The instance is now live with the new version.
  12. 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 at journalctl -u mastodon-web -f for 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.