Running a Mastodon instance requires storing large amounts of user-uploaded media. By default, Mastodon saves these files on the local filesystem of your server. This approach can quickly fill up disk space and makes scaling your instance harder. Self-hosted object storage with MinIO offers a reliable, S3-compatible alternative that keeps your media separate from your application server.
MinIO is an open-source object storage server that works with the Amazon S3 API. It runs on your own hardware or virtual machine, giving you full control over your data without relying on external cloud providers. Setting up MinIO for a Mastodon instance involves installing the MinIO server, creating a bucket and access keys, and configuring the Mastodon environment file to use S3 storage.
This guide walks through the entire process step by step. You will learn how to install and configure MinIO on Ubuntu 22.04, create the required bucket and credentials, and edit the Mastodon .env.production file to enable S3 media storage. By the end, your instance will store all user uploads in MinIO instead of local disk.
Key Takeaways: MinIO Setup for Mastodon
- MinIO server installation: Download the binary, set up systemd service, and configure the data directory for persistent storage.
- MinIO Console and bucket creation: Access the web UI, create a bucket named “mastodon”, and generate access key and secret key for Mastodon.
- Mastodon .env.production edits: Set S3_ENABLED=true, S3_BUCKET=mastodon, S3_ENDPOINT, and AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
Understanding MinIO and Its Role in Mastodon
Mastodon stores user-uploaded media such as images, videos, and audio files. Each post with media attaches a file that must be served to other users and federated instances. The default local storage method keeps these files in the public/system directory of the Mastodon application. As your instance grows, this directory consumes more disk space and can become a bottleneck for backups and server migrations.
Object storage separates the media files from the application server. Mastodon supports the Amazon S3 API for storing and serving media. MinIO implements the same API, so Mastodon treats it like any other S3 provider. The benefit is that you can host object storage on the same LAN or a different machine, scale storage independently, and use standard S3 tools for backup and replication.
What MinIO Requires
MinIO runs as a single binary with minimal dependencies. For a small Mastodon instance, a dedicated virtual machine or a container with 2 CPU cores and 4 GB RAM is sufficient. MinIO needs a persistent data directory, typically a mounted volume or a separate disk. The MinIO server listens on port 9000 for the S3 API and port 9001 for the web console. You must open these ports in your firewall if they are not on the same machine as Mastodon.
Prerequisites Before You Start
This guide assumes you have the following ready:
- A Mastodon instance already running on Ubuntu 22.04
- Root or sudo access to the Mastodon server
- A separate server or virtual machine for MinIO (or you can install MinIO on the same machine if you have enough disk space)
- A static IP address or DNS name for the MinIO server
- Ports 9000 and 9001 open on the MinIO server firewall
Steps to Install and Configure MinIO for Mastodon
- Download and install the MinIO server binary on Ubuntu 22.04
SSH into your MinIO server. Run the following commands to download the MinIO binary, make it executable, and move it to /usr/local/bin:wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/local/bin/ - Create a system user and data directory for MinIO
Create a dedicated system user for MinIO:sudo useradd -r minio-user -s /sbin/nologin. Create the data directory:sudo mkdir -p /data/minio. Set ownership:sudo chown minio-user:minio-user /data/minio. - Set up the MinIO environment file
Create or edit/etc/default/miniowith these values:MINIO_VOLUMES="/data/minio"
MINIO_OPTS="--console-address :9001"
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=YourStrongPassword123
ReplaceYourStrongPassword123with a strong password. The root user and password are used to log into the MinIO Console. - Create a systemd service file for MinIO
Create/etc/systemd/system/minio.servicewith this content:[Unit] Description=MinIO Documentation=https://docs.min.io Wants=network-online.target After=network-online.target [Service] User=minio-user Group=minio-user EnvironmentFile=-/etc/default/minio ExecStart=/usr/local/bin/minio server $MINIO_VOLUMES $MINIO_OPTS Restart=always LimitNOFILE=65536 [Install] WantedBy=multi-user.target
- Start and enable the MinIO service
Runsudo systemctl daemon-reload, thensudo systemctl start minio. Enable the service to start at boot:sudo systemctl enable minio. Check status:sudo systemctl status minio. - Access the MinIO Console and create a bucket
Open a web browser and go tohttp://your-minio-server-ip:9001. Log in with the root user and password from step 3. Click Buckets in the left menu, then Create Bucket. Name the bucketmastodonand leave the default settings. Click Create. - Generate access keys for Mastodon
In the MinIO Console, click Access Keys in the left menu, then Create Access Key. Copy the Access Key and Secret Key values. Store them securely; you will not see the secret key again. - Edit the Mastodon .env.production file
On your Mastodon server, open/home/mastodon/live/.env.productionwith sudo. Add or update these lines:S3_ENABLED=true S3_BUCKET=mastodon AWS_ACCESS_KEY_ID=your-access-key-from-step-7 AWS_SECRET_ACCESS_KEY=your-secret-key-from-step-7 S3_ENDPOINT=http://your-minio-server-ip:9000 S3_PROTOCOL=http S3_HOSTNAME=your-minio-server-ip:9000 S3_ALIAS_HOST=your-minio-server-ip:9000
If your MinIO server uses HTTPS, change
S3_PROTOCOLtohttpsand adjust the hostname accordingly. - Restart Mastodon services
Run these commands to apply the changes:sudo systemctl restart mastodon-web
sudo systemctl restart mastodon-sidekiq
sudo systemctl restart mastodon-streaming - Test that media uploads go to MinIO
Log into your Mastodon instance as any user. Upload an image in a new post. After posting, open the MinIO Console, click Buckets, then click themastodonbucket. You should see the uploaded file appear inside a folder structure.
Common Issues After Setting Up MinIO with Mastodon
Media Uploads Fail with 403 Forbidden Error
This error usually means the access key or secret key is wrong, or the bucket permissions are incorrect. Verify the keys in .env.production match the ones generated in the MinIO Console. Also check that the bucket name is exactly mastodon and that the bucket policy allows public read access. In the MinIO Console, go to the mastodon bucket, click Anonymous, and set Read Only for the bucket and its contents.
Mastodon Cannot Reach the MinIO Server
If Mastodon cannot connect to MinIO, check the network connectivity between the two servers. From the Mastodon server, run curl http://your-minio-server-ip:9000. You should get an XML response. If the connection times out, ensure the MinIO server firewall allows incoming traffic on port 9000. Also confirm that the MinIO service is running: sudo systemctl status minio.
Existing Media Files Are Not Migrated to MinIO
This setup does not automatically move existing local files to MinIO. To migrate existing media, you must copy the contents of /home/mastodon/live/public/system to the MinIO bucket using an S3-compatible tool like aws-cli or mc (the MinIO client). After copying, update the database records to point to the new URLs. This is an advanced step and should be tested on a staging instance first.
Local Storage vs MinIO Object Storage for Mastodon
| Item | Local Storage | MinIO Object Storage |
|---|---|---|
| Storage location | Application server disk | Separate server or volume |
| Scalability | Limited by server disk slots | Add disks or nodes independently |
| Backup complexity | Must include entire public/system directory | Use S3 tools for incremental backups |
| Performance | Direct local disk I/O | Network-dependent, but can be faster with dedicated hardware |
| Cost | No extra software cost; requires disk space | Free open source; need separate server or VM |
After completing this setup, your Mastodon instance stores all new media uploads in MinIO. This separates media from the application server, making backups and scaling easier. Next, configure MinIO with TLS using a reverse proxy like Nginx to serve media over HTTPS. An advanced tip: set up MinIO in distributed mode across multiple nodes for high availability and automatic replication.