Note
Want to learn more about Mastodon? Click below to find out more in a video.
Mastodon is a free, open-source social network server based on ActivityPub where users can follow friends and discover new ones. On Mastodon, users can publish anything they want: links, pictures, text, and video. All Mastodon servers are interoperable as a federated network (users on one server can seamlessly communicate with users from another one, including non-Mastodon software that implements ActivityPub!)
Note
This is a fork of Mastodon v4.5.9 with the Ruby on Rails backend replaced by a Python/FastAPI backend. The REST API, ActivityPub federation, and background workers are all implemented in Python. The React frontend and Node.js streaming server are unchanged.
Part of the Fediverse. Based on open standards, with no vendor lock-in. - the network goes beyond just Mastodon; anything that implements ActivityPub is part of a broader social network known as the Fediverse.
Real-time, chronological timeline updates - updates of people you're following appear in real-time in the UI via the Node.js streaming server.
Media attachments - upload and view images and videos attached to the updates.
Safety and moderation tools - private posts, locked accounts, phrase filtering, muting, blocking, reporting, and moderation.
OAuth2 and a straightforward REST API - full OAuth2 provider with the Mastodon-compatible REST and Streaming APIs.
| Component | Technology |
|---|---|
| REST API + ActivityPub | FastAPI (Python 3.12+) |
| Database | PostgreSQL 14+ |
| Cache + pub/sub | Redis 7+ |
| Background jobs | arq (async Redis queue) |
| Streaming API (WebSocket/SSE) | Node.js 20+ |
| Web UI | React + Redux + TypeScript, built with Vite |
| Schema migrations | Alembic |
| Reverse proxy | nginx |
- Docker + Docker Compose (or Podman with
docker-compose) - OR for native dev: Python 3.12+, uv, Node.js 20+, PostgreSQL 14+, Redis 7+
# Clone and enter the repo
git clone <repo-url>
cd mastodon
# Build images and start the stack
docker compose build
docker compose up -d
# Run database migrations (first time only)
docker compose exec python uv run alembic upgrade head
# The API is now available at http://localhost:3000
curl http://localhost:3000/api/v1/instance
curl http://localhost:3000/_py/health| Service | Description | Port |
|---|---|---|
proxy |
nginx reverse proxy (entry point) | 3000 |
python |
FastAPI/uvicorn with hot-reload | 8000 (internal) |
arq |
Async background worker | β |
stream |
Node.js WebSocket/SSE streaming server | 4000 (internal) |
vite |
Frontend dev server | 3036 |
db |
PostgreSQL 14 | 5432 (internal) |
redis |
Redis 7 | 6379 (internal) |
docker compose ps # check service status
docker compose logs -f # follow all logs
docker compose logs -f python # FastAPI logs only
docker compose down # stop all services
docker compose down -v # stop + delete volumes# Install Python deps
uv sync
# Install JS deps
yarn install
# Run migrations
uv run alembic upgrade head
# Start all processes
bin/dev # uses honcho (installed via uv) or overmind if availablebin/dev starts: FastAPI (:8000), arq, Node.js streaming (:4000), Vite, and nginx proxy (:3000).
# Python (pytest)
uv run pytest
uv run pytest tests/routers/test_statuses.py # single file
uv run pytest -k "timeline" # filter by keyword
# JavaScript/TypeScript (Vitest)
yarn test:js run
yarn test:js run path/to/file.test.ts
# Type checking
uv run mypy app/python
yarn typecheck
# Linting
uv run ruff check app/python
yarn lint# Apply pending migrations
uv run alembic upgrade head
# Generate a new migration from model changes
uv run alembic revision --autogenerate -m "describe the change"
# Downgrade one step
uv run alembic downgrade -1app/python/ FastAPI backend
main.py App factory + lifespan
settings.py Config (reads DB_*, REDIS_*, etc. env vars)
db.py Async SQLAlchemy engine + session
deps.py FastAPI dependency injection
routers/ API endpoint handlers (one file per resource)
models/ SQLAlchemy ORM models
schemas/ Pydantic request/response schemas
services/ Business logic
workers/ arq background workers
federation/ ActivityPub + HTTP signatures
auth/ OAuth2 + token resolution
policies/ Visibility / authorization checks
common/ Shared utilities (snowflake IDs, pagination, etc.)
lib/ HTML sanitization, hashtag/mention extraction
alembic/ Database migrations
env.py Alembic environment (imports all models)
versions/ Migration files
tests/ pytest test suite
routers/ API endpoint tests
federation/ ActivityPub tests
auth/ Auth tests
common/ Utility tests
app/javascript/ React + Redux frontend (unchanged from upstream)
streaming/ Node.js WebSocket/SSE streaming server (unchanged)
config/nginx/
dev.conf nginx config for native dev (upstream: 127.0.0.1)
docker.conf nginx config for Docker Compose (upstream: service names)
Dockerfile.python Docker image for FastAPI + arq
docker-compose.yml Full dev stack
The Python app reads configuration from environment variables (with .env.development as fallback for local dev). Key variables:
| Variable | Default | Description |
|---|---|---|
MASTODON_ENV |
development |
Runtime environment |
DB_HOST |
localhost |
PostgreSQL host |
DB_PORT |
5432 |
PostgreSQL port |
DB_USER |
mastodon |
PostgreSQL user |
DB_PASS |
(empty) | PostgreSQL password |
DB_NAME |
mastodon_development |
PostgreSQL database |
REDIS_HOST |
localhost |
Redis host |
REDIS_PORT |
6379 |
Redis port |
LOCAL_DOMAIN |
localhost:3000 |
Instance domain |
SECRET_KEY_BASE |
(empty) | Secret for token signing |
S3_ENABLED |
false |
Use S3 for media storage |
Mastodon is free, open-source software licensed under AGPLv3.
You should read and understand the CODE OF CONDUCT.
AI-assisted contributions are governed by the project's AI Contribution Policy.
Licensed under GNU Affero General Public License as stated in the LICENSE:
Copyright (c) 2016-2025 Eugen Rochko & other Mastodon contributors
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
details.
You should have received a copy of the GNU Affero General Public License along
with this program. If not, see https://www.gnu.org/licenses/