How to Self-Host Mastodon on a VPS
Start your own corner of the fediverse. This guide installs a Mastodon instance on a VPS with Docker and covers the email and storage decisions that trip people up.

Mastodon is the open-source, federated social network at the heart of the fediverse. Running your own instance means you control the rules, the data and the branding — whether it's a personal single-user server or a community. This guide covers a Docker install and, just as importantly, the operational decisions (email and storage) that make or break a Mastodon server.
Know what you're signing up for
Mastodon is more demanding than most self-hosted apps: it needs a working transactional email provider, benefits from object storage for media, and federation means your storage grows as you follow accounts on other servers. Budget 2 GB+ RAM and be ready to attach block storage for media. With that understood, let's build it.
Prerequisites
- A VPS with 2 GB+ RAM and Docker + Docker Compose — run Docker on a VPS.
- A domain (this becomes your instance name and can't change), with an A record.
- An SMTP provider for account and notification emails.
Get the Compose file and configure
Clone Mastodon and copy the sample environment file:
git clone https://github.com/mastodon/mastodon.git ~/mastodon
cd ~/mastodon
cp .env.production.sample .env.production
Generate the required secrets:
docker compose run --rm web bundle exec rake secret
Run that a few times and paste the values into SECRET_KEY_BASE and OTP_SECRET in .env.production. Then set your domain, database, Redis, and SMTP settings:
LOCAL_DOMAIN=social.example.com
SMTP_SERVER=smtp.yourprovider.com
SMTP_PORT=587
SMTP_LOGIN=postmaster@example.com
SMTP_PASSWORD=change-me
SMTP_FROM_ADDRESS=notifications@social.example.com
Getting email DNS right is essential or confirmation emails vanish into spam — see SPF, DKIM and DMARC explained.
Prepare the database and assets
docker compose run --rm web bundle exec rails db:setup
docker compose run --rm web bundle exec rails assets:precompile
docker compose up -d
Reverse proxy with HTTPS
Front Mastodon's web service (port 3000) and streaming (port 4000) with Caddy:
social.example.com {
reverse_proxy /api/v1/streaming* 127.0.0.1:4000
reverse_proxy 127.0.0.1:3000
}
Open the firewall for web and SSH:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Create your admin account
docker compose run --rm web bin/tootctl accounts create you \
--email you@example.com --confirmed --role Owner
Log in at https://social.example.com, set your profile, and start posting into the fediverse.
Managing storage growth
Media from accounts you federate with accumulates. Keep it in check with the built-in cleanup, run on a schedule:
docker compose run --rm web bin/tootctl media remove --days 14
For a larger instance, configure S3-compatible object storage in .env.production so media doesn't fill the VPS disk.
Day-two operations
Running a Mastodon instance is as much upkeep as setup. Get comfortable with tootctl, the admin command-line tool inside the web container:
- Prune remote media to reclaim disk:
tootctl media remove --days 14. - Clean up orphaned files:
tootctl media remove-orphans. - Manage accounts and moderation from the admin web UI under *Preferences → Administration*.
Run the media cleanup on a cron schedule so storage never creeps toward full — federation means you cache media from every server your users interact with.
Upgrading and moderation policy
Upgrade with care: pull the new images, then run any database migrations and asset recompilation the release notes specify:
cd ~/mastodon
git pull
docker compose run --rm web bundle exec rails db:migrate
docker compose run --rm web bundle exec rails assets:precompile
docker compose up -d
Set your instance rules early and, if you federate widely, decide whether to defederate from servers that don't share your moderation standards — that policy shapes the experience for everyone on your instance more than any technical setting.
Connecting your instance to the wider fediverse
A fresh Mastodon server can feel empty until it federates. Federation is passive — your server learns about remote accounts as your users follow them — so the fastest way to fill the federated timeline is simply to follow people. A couple of things help a new instance find its feet:
- Follow a few active accounts from your first login; their posts and boosts pull in more of the network.
- Add relay support if you want a busier public timeline on a small instance, though be mindful that relays increase inbound traffic and storage.
- Set up your profile and a pinned intro post so people who discover you have context.
Because Mastodon speaks the ActivityPub protocol, your instance can also interact with other fediverse software — you're joining a wider social web, not just other Mastodon servers. Keep your moderation and media-retention routines running as your instance grows, and it stays healthy and responsive.
FAQ
Can I run a single-user Mastodon instance?
Yes, and it's a popular setup. You still need email and a domain, but resource use stays modest with periodic media cleanup.
Why does Mastodon need so much storage?
Federation caches media from servers you interact with. Use scheduled cleanup and, for bigger instances, object storage to keep local disk under control.
Do I really need an email provider?
Yes — account confirmations, password resets and notifications all go by email. Use a transactional provider and configure SPF/DKIM/DMARC for deliverability.
Can my instance talk to other Mastodon servers?
Yes, that's the whole point. Once federation and DNS are correct, your users interact with anyone across the fediverse.
Ready to launch your instance? Deploy Mastodon on a capable NVMe VPS with block storage for media, and full root access throughout.