---
title: "Deploy Mastodon"
description: "Social network server that connects to the wider fediverse"
category: "Other"
url: https://railway.com/deploy/mastodon-server
---

# Deploy Mastodon

Social network server that connects to the wider fediverse

**[Deploy Mastodon on Railway](https://railway.com/template/mastodon-server)**

- **Creator:** A3A
- **Category:** Other

## Template content

### sidekiq-scheduler https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/mastodon.svg

- **Source:** https://github.com/gridalpha/mastodon-railway
- **Health check:** /metrics

### sidekiq https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/mastodon.svg

- **Source:** https://github.com/gridalpha/mastodon-railway
- **Health check:** /metrics

### Redis https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/redis.svg

- **Image:** redis:8.2
- **Start command:** `/bin/sh -c "rm -rf $RAILWAY_VOLUME_MOUNT_PATH/lost+found/ && exec docker-entrypoint.sh redis-server --requirepass $REDIS_PASSWORD --save 60 1 --dir $RAILWAY_VOLUME_MOUNT_PATH"`

### streaming https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/mastodon.svg

- **Image:** ghcr.io/mastodon/mastodon-streaming:v4.7.0
- **Health check:** /api/v1/streaming/health
- **Public domain:** Yes

### mailpit https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/mailpit.svg

- **Image:** axllent/mailpit:latest
- **Health check:** /livez
- **Public domain:** Yes

### web https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/mastodon.svg

- **Source:** https://github.com/gridalpha/mastodon-railway
- **Health check:** /health
- **Public domain:** Yes

### media https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/mastodon.svg

- **Source:** https://github.com/gridalpha/mastodon-railway
- **Health check:** /healthz
- **Public domain:** Yes

### Postgres https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/postgresql.svg

- **Image:** ghcr.io/railwayapp-templates/postgres-ssl:18

## Buckets

- **mastodon-media**

## Documentation

![Mastodon logo](https://www.investopedia.com/thmb/5s3BHoTW_i01Z5aW_3xqciXRvgk=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Mastodon_Social-Media1-91aa9eedeb7e48d4b1dde12759ec4afb.png)

# Deploy and Host Mastodon on Railway

Mastodon is an open-source social network server that speaks ActivityPub, the protocol behind Threads, Pixelfed and PeerTube. Running your own instance means you own the moderation rules and the data, while members still follow and are followed by anyone on any other fediverse server. Communities, newsrooms and companies self-host it so their timeline is not somebody else's product.

Deploy Mastodon on Railway and you get the full production layout, not a single container: a Puma web service, a Node streaming service for live timelines, a Sidekiq worker tier, a dedicated scheduler, PostgreSQL, Redis, an object storage bucket, a signing gateway that serves that bucket publicly, and a Mailpit inbox so signup mail works immediately. To self-host Mastodon well you need all of that wired together, and this template does it for you.

![Mastodon web, streaming and Sidekiq services on Railway](https://res.cloudinary.com/rroe4rtk/image/upload/v1788041768/mastodon-architecture.png)

## Getting Started with Mastodon on Railway

Open the `web` service's public URL. An owner account is created on the first boot from `MASTODON_ADMIN_USERNAME` (default `admin`) and `MASTODON_ADMIN_PASSWORD`, so there is no setup wizard: sign in at `/auth/sign_in` with `admin@` and that password, both readable in the `web` service's variables, then change it under **Preferences → Account**. Post from the composer first; if it appears in the timeline immediately, the web service, PostgreSQL and the streaming socket are healthy. Attach an image to a second post to exercise the rest — the upload goes to the bucket, Sidekiq makes the thumbnail and the media gateway serves it back, so a rendering image proves storage end to end. Then fill in the server name, description and rules under **Administration → Server Settings**: that text is what other servers show when someone discovers you.

New signups arrive as applications rather than instant accounts. Review them under **Moderation → Accounts** and switch to open or invite-only when you are ready.

![Mastodon home timeline showing a post with a chart attachment](https://res.cloudinary.com/rroe4rtk/image/upload/v1788041770/mastodon-home-timeline.png)
![Mastodon moderation screen listing a pending account application](https://res.cloudinary.com/rroe4rtk/image/upload/v1788041771/mastodon-admin-pending-accounts.png)
![Sidekiq showing separate worker and scheduler queue processes](https://res.cloudinary.com/rroe4rtk/image/upload/v1788041772/mastodon-sidekiq-busy-processes.png)

## About Hosting Mastodon

Each instance holds its own accounts and posts and exchanges signed ActivityPub messages with every server its members follow, so a small instance still reaches the whole network. Teams self-host to set their own moderation policy, keep member data in their own infrastructure, or run a members-only community that still federates.

Key features:

- Chronological home, local and federated timelines with no ranking algorithm
- 500-character posts, polls, content warnings, alt text and quote posts
- Moderation tooling: reports, appeals, account approvals, domain blocks
- A documented REST and streaming API dozens of mobile clients speak
- Web Push notifications, two-factor auth and single sign-on hooks

How the services fit together: **web** runs Puma and serves the interface, the API and inbound federation. **streaming** is a Node process pushing live timeline updates over WebSockets from its own domain. **sidekiq** runs the background queues — federation, thumbnails, e-mail — and scales to more replicas; **sidekiq-scheduler** runs the cron-shaped queue alone and stays at one replica. **Postgres** holds accounts and posts, **Redis** backs the cache, queues and pub/sub, and the **bucket** holds every avatar, header and attachment plus cached remote media. **media** is a signing gateway making those files publicly readable without exposing the bucket, and **mailpit** captures outgoing mail until you connect a real relay.

## Why Deploy Mastodon on Railway

Railway removes the parts of a Mastodon install that usually take a weekend.

- Every service, database and bucket provisioned and wired in one click
- Private networking between web, workers, Postgres and Redis
- Managed PostgreSQL and Redis with backups and metrics
- Object storage for media, so no disk fills with attachments
- Health checks and restart policies per role
- Scale the worker tier from the dashboard

## Common Use Cases

- A community server where a moderation team sets the rules, not a platform
- A newsroom or research group publishing to the fediverse from its own domain
- A private, invite-reviewed instance that still federates with public servers

## Dependencies for Mastodon

- `ghcr.io/mastodon/mastodon:v4.7.0` — Rails app, used by web and both Sidekiq services
- `ghcr.io/mastodon/mastodon-streaming:v4.7.0` — streaming API, pinned to the same release
- PostgreSQL 18 — accounts, posts, relationships and moderation records
- Redis 8 — cache, Sidekiq queues and streaming pub/sub
- Railway object storage — avatars, headers, attachments, cached remote media
- `axllent/mailpit:latest` — capture-only SMTP server and web inbox
- Boot logic and media gateway: `https://github.com/gridalpha/mastodon-railway`

### Environment Variables Reference

| Variable | Purpose |
|---|---|
| `LOCAL_DOMAIN` | Federation identity. **Cannot be changed after the first boot** |
| `MASTODON_ROLE` | Selects the role this container runs |
| `SECRET_KEY_BASE` | Session signing key; also seeds the Web Push keypair |
| `ACTIVE_RECORD_ENCRYPTION_*` | At-rest encryption keys; the app will not start if blank |
| `MASTODON_ADMIN_PASSWORD` | Password for the owner account created on first boot |
| `S3_ALIAS_HOST` | Public hostname media URLs are written with |
| `STREAMING_API_BASE_URL` | WebSocket origin handed to clients |
| `SMTP_SERVER` | Mail relay; points at Mailpit until you change it |

### Deployment Dependencies

- Source and issues: https://github.com/mastodon/mastodon
- Self-hosting docs: https://docs.joinmastodon.org/admin/install/
- Images: https://github.com/mastodon/mastodon/pkgs/container/mastodon
- Ruby 4.0 and Node 24, supplied by the official images

## Hardware Requirements for Self-Hosting Mastodon

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 2 vCPU total | 4+ vCPU |
| RAM | 2 GB | 4–8 GB |
| Storage | Postgres volume plus object storage | Grows with cached remote media |
| Runtime | Ruby 4.0, Node 24 | Supplied by the official images |

A quiet instance fits the minimum column. Federation traffic grows the bill: every account your members follow means inbound deliveries and cached remote media. Add worker replicas before web replicas.

## Self-Hosting Mastodon

Upstream ships a production `docker-compose.yml`:

```
git clone https://github.com/mastodon/mastodon.git
cd mastodon
cp .env.production.sample .env.production
docker compose run --rm web bundle exec rails mastodon:setup
docker compose up -d
```

That writes the generated secrets into `.env.production`. Web Push keys are a matched pair, so they are generated rather than invented:

```
docker compose run --rm web bundle exec rails mastodon:webpush:generate_vapid_key
docker compose run --rm web bin/rails db:encryption:init
```

You still need a reverse proxy with TLS, a mail relay and a bucket for uploads. The Railway template handles all of that and migrates on boot.

## Is Mastodon Free to Self-Host?

Mastodon is free and open source under the AGPL-3.0 licence, with no paid tier, seat limits or feature gates. The only cost of self-hosting Mastodon is infrastructure: on Railway you pay for compute, the managed Postgres and Redis, and the object storage your instance uses. Costs rise with member count and cached remote media.

## FAQ

**What is Mastodon?**
An open-source, self-hostable social network server. It speaks ActivityPub, so accounts on your server follow and are followed by accounts on any other fediverse server, with no central company in the middle.

**What does this Railway template deploy?**
A complete instance: the Puma web service, the streaming service, a Sidekiq worker tier, a dedicated scheduler, PostgreSQL, Redis, an object storage bucket with a signing gateway in front of it, and a Mailpit inbox.

**Why does self-hosted Mastodon need Redis and object storage?**
Redis carries the Sidekiq queues, the Rails cache and the pub/sub channel the streaming service reads. Object storage holds every avatar, header and attachment plus cached media from servers your members follow — that grows fast and does not belong on a disk.

**How do I change my Mastodon server's domain after deploying?**
You do not. `LOCAL_DOMAIN` goes into every ActivityPub identifier your server emits, so changing it breaks existing follows. Attach your custom domain to the `web` service and set `LOCAL_DOMAIN` to it before anyone signs up.

**How do I send real e-mail from self-hosted Mastodon?**
Mailpit captures mail so confirmation and password-reset flows work immediately, but never delivers it. Point the `SMTP_*` variables at a real provider before inviting members. Any SMTP host works.

**Can I scale Mastodon's background workers on Railway?**
Yes — raise the replica count on the `sidekiq` service as federation traffic grows. Leave `sidekiq-scheduler` at one replica: it runs the recurring jobs, and a second copy would run each of them twice.

**How do I enable full-text search in self-hosted Mastodon?**
Search over your own posts needs Elasticsearch, left out to keep the footprint small. Add an Elasticsearch service, set `ES_ENABLED`, `ES_HOST` and `ES_PORT` on the web and Sidekiq services, then run `tootctl search deploy`.


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/mastodon-server
