what changes
| Feature | Upstream Mastodon | On bolha |
|---|---|---|
| Post length | 500 characters | 1200 characters |
| Profile bio | 500 characters | 1200 characters |
| Profile metadata | 4 fields | 24 fields |
| Poll options | 4 options of 50 characters | 12 options of 60 characters |
| Short mutes | 6 hours and up | 10, 30 or 60 minutes |
| Markdown in posts | not available | headings, lists and highlighted code |
| Self-destructing posts | not available | from 15 minutes to 24 hours |
| API rate limits | default | doubled |
| Theme | default | Tangerine UI, in 5 colors |
details
The composer gets a button to write in Markdown. Code blocks are highlighted per language (highlight.js, with a set of common languages) and headings from H1 to H6 have distinct sizes. Instances that do not understand Markdown receive the post already converted to HTML.
An hourglass in the composer sets how long the post lives: 15 or 30 minutes, 1, 2, 4, 6, 12 or 24 hours. When the time comes the post is deleted as if its author had deleted it: it is gone for everyone and the deletion is sent to other instances. Each remote instance decides whether to honor it, as with any deletion in the fediverse.
The request limits per account, per token, for paging and for media were doubled. People using multi-column clients (the advanced interface, Phanpy, Elk) ran out of the upstream limit within minutes. Login, sign-up and password reset limits are unchanged.
The mute dialog gained 10, 30 and 60 minute options, next to the long durations that already existed.
for client developers
Both new features show up in the post creation API. The instance publishes the accepted durations in configuration.statuses.expirations, in the /api/v2/instance response.
# post that deletes itself in one hour (expires_in in seconds)
curl -X POST https://{domain}/api/v1/statuses \
-H "Authorization: Bearer $TOKEN" \
-d "status=gone in an hour" \
-d "expires_in=3600"
# markdown post
curl -X POST https://{domain}/api/v1/statuses \
-H "Authorization: Bearer $TOKEN" \
-d "content_type=text/markdown" \
--data-urlencode $'status=# title\n\n```python\nprint("hi")\n```'
source code
The code is public, under the same AGPL-3.0 license as Mastodon. Each version is a branch with the bolha commits applied on top of the upstream tag, so you can read exactly what changes.
docker images
The images live in a public registry, no login needed. There are two per version, as in upstream Mastodon: web (also used by sidekiq) and streaming. Builds are linux/amd64 only.
# pull the current version
docker pull registry.gutocarvalho.net/images/mastodon:v4.7.3-web-bolha-tangerine-prod-2
docker pull registry.gutocarvalho.net/images/mastodon:v4.7.3-streaming-prod-1
| Version | Web image | Streaming image |
|---|---|---|
| 4.7.3 current | v4.7.3-web-bolha-tangerine-prod-2 | v4.7.3-streaming-prod-1 |
| 4.7.2 | v4.7.2-web-bolha-tangerine-prod-1 | v4.7.2-streaming-prod-1 |
| 4.7.1 | v4.7.1-web-bolha-tangerine-prod-1 | v4.7.1-streaming-prod-1 |
| 4.7.0 | v4.7.0-web-bolha-tangerine-prod-1 | v4.7.0-streaming-prod-1 |
| 4.6.4 | v4.6.4-web-bolha-tangerine-prod-4 | — |
| 4.5.3 | v4.5.3-web-bolha-tangerine-prod-1 | v4.5.3-streaming-prod-1 |
See every tag in the registry →
docker compose
Start from the upstream Mastodon docker-compose.yml and change only the three image lines. Everything else (database, Redis, .env.production, volumes) stays the same, and no new environment variable is needed.
Back up your database first.
Swap the images in
docker-compose.yml:services: web: image: registry.gutocarvalho.net/images/mastodon:v4.7.3-web-bolha-tangerine-prod-2 sidekiq: image: registry.gutocarvalho.net/images/mastodon:v4.7.3-web-bolha-tangerine-prod-2 streaming: image: registry.gutocarvalho.net/images/mastodon:v4.7.3-streaming-prod-1Pull, run the migrations and start:
docker compose pull docker compose run --rm web bundle exec rails db:migrate docker compose up -d
Check the version and the limits:
curl -s https://{domain}/api/v2/instance | jq '.version, .configuration.statuses'
- Use the image for the same Mastodon version you already run, or follow the upstream upgrade notes for the target version first.
- The migrations only add three columns and one index. On a table with 41 million posts, the index took about 100 seconds.
- Self-destructing posts depend on sidekiq processing the
defaultandschedulerqueues. If you split queues across processes, check both. - To go back to upstream Mastodon, just swap the images back. Long posts and extra metadata stay in the database.
who runs it
Instances running this build:
Tell @gutocarvalho@bolha.us and we will add you to this list.