How to Move Mastodon Media Storage From Local to Backblaze B2
🔍 WiseChecker

How to Move Mastodon Media Storage From Local to Backblaze B2

Mastodon instances generate large amounts of media files from user uploads and cached remote content. Storing these files on the same server as your database and application code quickly fills disk space and can degrade performance. Moving media storage to Backblaze B2 reduces server disk usage and lowers hosting costs. This article explains how to configure your Mastodon instance to use Backblaze B2 as the primary media storage backend.

Key Takeaways: Migrating Mastodon Media to Backblaze B2

  • .env.production configuration: Setting S3-compatible environment variables redirects Mastodon’s Active Storage to Backblaze B2.
  • rails assets:precompile and db:migrate: Required commands after changing storage provider to apply the new configuration.
  • Existing media migration: Use tootctl media commands to copy existing local files to the B2 bucket and remove local copies.

ADVERTISEMENT

Understanding Mastodon Media Storage and Backblaze B2

Mastodon uses Ruby on Rails Active Storage to manage file attachments. By default, Active Storage saves files to the local filesystem under public/system. This location includes user-uploaded images and videos, custom emoji, and cached media from federated instances. On a busy instance, this directory can exceed tens of gigabytes within weeks.

Backblaze B2 is an object storage service that is S3-compatible. Mastodon’s Active Storage can be configured to use any S3-compatible provider by setting environment variables. The migration involves changing these variables, running Rails commands to update the application, and copying existing files to the B2 bucket. No code changes are required. The entire process takes about 30 minutes for a small instance.

Prerequisites for this guide:

  • Root or sudo access to the Mastodon server
  • A Backblaze B2 account with an application key that has write and read permissions
  • A B2 bucket created with default settings (public or private; Mastodon will handle access)
  • Mastodon v3.5 or later (older versions require additional gems)

Steps to Configure Mastodon for Backblaze B2 Storage

  1. Create a Backblaze B2 bucket and application key
    Log into your Backblaze account. Navigate to B2 Cloud Storage and click Create a Bucket. Name the bucket something like mastodon-media. Set the bucket type to Private. After creation, go to App Keys and click Generate New Application Key. Select the bucket you just created. Allow read and write access. Copy the Key ID and Application Key values. Keep these secure.
  2. Stop the Mastodon web and sidekiq processes
    On your server, stop the services to prevent file writes during the configuration change. Run: sudo systemctl stop mastodon-web and sudo systemctl stop mastodon-sidekiq. Also stop the streaming API service if you use it: sudo systemctl stop mastodon-streaming.
  3. Edit the Mastodon .env.production file
    Open /home/mastodon/live/.env.production with a text editor. Locate the section for S3 storage. If it does not exist, add the following lines. Replace placeholders with your actual values:
    S3_ENABLED=true
    S3_BUCKET=mastodon-media
    S3_REGION=us-west-001
    AWS_ACCESS_KEY_ID=your_backblaze_key_id
    AWS_SECRET_ACCESS_KEY=your_backblaze_application_key
    S3_ENDPOINT=https://s3.us-west-001.backblazeb2.com
    S3_PROTOCOL=https
    S3_HOSTNAME=s3.us-west-001.backblazeb2.com
    S3_ALIAS_HOST=https://your-bucket-name.s3.us-west-001.backblazeb2.com
    

    The S3_REGION and S3_ENDPOINT values depend on your B2 bucket region. Find the correct endpoint in the Backblaze B2 dashboard under the bucket details. Do not use quotes around the values.

  4. Run Rails asset precompilation and database migration
    Switch to the mastodon user: sudo -i -u mastodon. Navigate to the live directory: cd /home/mastodon/live. Run: RAILS_ENV=production bundle exec rails assets:precompile. This command generates new asset files that include the S3 configuration. Then run: RAILS_ENV=production bundle exec rails db:migrate. This updates the database schema if needed.
  5. Restart Mastodon services
    Exit the mastodon user shell. Run: sudo systemctl start mastodon-web, sudo systemctl start mastodon-sidekiq, and sudo systemctl start mastodon-streaming. Check the service status: sudo systemctl status mastodon-web. Ensure all services are active and running.
  6. Copy existing media files to Backblaze B2
    Mastodon provides the tootctl tool for media management. Run the following command to upload all local media to B2: RAILS_ENV=production bin/tootctl media remove --days=0. This command removes local media that is older than 0 days (i.e., all media) but only after ensuring the files exist in the remote storage. Wait for the command to finish. Then run: RAILS_ENV=production bin/tootctl media usage to verify that the media count and size match the remote bucket.
  7. Remove the local media directory
    After confirming all files are in B2, delete the local media directory to free disk space. Run: sudo rm -rf /home/mastodon/live/public/system. This action cannot be undone. Only perform this step after verifying your B2 bucket contains all files.

ADVERTISEMENT

Common Issues When Moving Mastodon Media to Backblaze B2

Media uploads fail after switching to B2

This usually indicates incorrect S3_ENDPOINT or S3_HOSTNAME values. Verify that the endpoint matches the Backblaze B2 region exactly. Also confirm that the application key has write permissions. Check the Mastodon logs at /home/mastodon/live/log/production.log for S3-related error messages.

Existing media files not accessible after migration

The tootctl media remove command only removes files that are already stored remotely. If you deleted local files before uploading them to B2, the media will be missing. To recover, you must restore the local files from a backup and rerun the migration steps in the correct order. Always verify B2 bucket contents before deleting local files.

New media saves locally instead of to B2

The S3_ENABLED variable must be set to true exactly. Trailing spaces or incorrect capitalization will cause Mastodon to ignore the S3 configuration. After editing the .env file, restart all Mastodon services and test by uploading a new post with an image. Check the production log to confirm the file path points to the B2 endpoint.

Mastodon Local Storage vs Backblaze B2

Item Local Storage Backblaze B2
Storage location Server filesystem Remote object storage
Cost Server disk cost (included in VPS) Pay per GB stored and downloaded
Scalability Limited by disk size Virtually unlimited
Backup requirement Must back up media separately B2 includes 99.999999999% durability
Server load File operations consume CPU and I/O Offloads file serving to CDN edge

After moving media to Backblaze B2, your Mastodon instance will store all user-uploaded and cached media remotely. The server disk usage will drop significantly, reducing backup size and extending the life of your SSD. Monitor the B2 bucket usage from the Backblaze dashboard to track costs. For large instances, consider enabling the S3_ALIAS_HOST with a custom subdomain to improve load times through a CDN.

ADVERTISEMENT