Skip to content

h4-io/cleaning_script

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 

Repository files navigation

mastodon-cleanup.sh

A maintenance script for a self-hosted Mastodon instance. It reclaims disk space by running the standard tootctl cleanup tasks — pruning dead remote accounts, unreferenced statuses, cached remote media, link-preview thumbnails, and orphaned files — in a form that is safe to schedule and easy to monitor.

It wraps the same commands you were already running, and adds the things that matter for an unattended job: single-instance locking, timestamped logging, per-step error handling, a non-zero exit code on failure, a dry-run mode, and tunable retention windows.

What it does

Each run executes these steps in order. The orphan sweep runs last on purpose, so that files dereferenced by the earlier steps get cleaned up too.

# Command What it removes
1 accounts prune Remote accounts that never interacted with a local user
2 statuses remove Unreferenced statuses (from relays, unfollowed remotes, no replies/interactions) older than STATUSES_DAYS
3 media remove Cached remote media attachments older than MEDIA_DAYS
4 media remove --prune-profiles Cached remote avatars (optional, off by default)
5 media remove --remove-headers Cached remote headers/banners (optional, off by default)
6 preview_cards remove Local link-preview thumbnails older than PREVIEW_CARDS_DAYS
7 media remove-orphans Files on disk that no longer belong to any attachment

Only flags that each subcommand actually supports are passed, so nothing errors out on an unknown option.

Requirements

  • A working Mastodon install with tootctl at MASTODON_HOME/bin/tootctl (default /home/mastodon/live/bin/tootctl).
  • bash, and flock (from util-linux, present on essentially all Linux distros) for single-instance locking. Without flock the script still runs, just without overlap protection.
  • Run it as the mastodon system user (the one that owns the install), not as root.

Installation

# Place it somewhere the mastodon user can execute, e.g. the home dir
sudo -u mastodon cp mastodon-cleanup.sh /home/mastodon/mastodon-cleanup.sh
sudo -u mastodon chmod +x /home/mastodon/mastodon-cleanup.sh

# Make sure the log directory exists and is writable by the mastodon user
sudo mkdir -p /var/log/mastodon
sudo chown mastodon:mastodon /var/log/mastodon

Configuration

Everything is configured through environment variables, so you don't have to edit the script. Defaults match tootctl's own defaults, so out of the box the script behaves like plain tootctl.

Variable Default Description
MASTODON_HOME /home/mastodon/live Path to the Mastodon checkout
TOOTCTL $MASTODON_HOME/bin/tootctl Full path to the tootctl binstub
RAILS_ENV production Rails environment
STATUSES_DAYS 90 Age (days) before unreferenced statuses are removed
MEDIA_DAYS 7 Age (days) before cached remote media/avatars/headers are removed
PREVIEW_CARDS_DAYS 180 Age (days) before preview-card thumbnails are removed (keep ≥ 14)
CONCURRENCY 5 Worker threads for tasks that support --concurrency
MEDIA_REMOVE_PROFILES 0 Set 1 to also drop cached remote avatars
MEDIA_REMOVE_HEADERS 0 Set 1 to also drop cached remote headers/banners
LOG_FILE /var/log/mastodon/cleanup.log Log destination (falls back to stdout if unwritable)
LOCK_FILE /tmp/mastodon-cleanup.lock Lock file for single-instance protection
ENV_FILE (none) Optional file sourced before running (see rbenv/rvm note)
DRY_RUN 0 Set 1 (or pass --dry-run) to preview without deleting
VERBOSE 0 Set 1 (or pass --verbose) for extra tootctl output

Command-line flags override the env vars: --dry-run, --verbose, --help.

Tuning retention

If your goal is aggressive disk savings on a small instance, lower the windows, e.g. STATUSES_DAYS=14 MEDIA_DAYS=3. Do not set PREVIEW_CARDS_DAYS below 14 — Mastodon won't re-fetch a preview card until the link is posted again after two weeks, so deleting recent cards just leaves blank previews.

Usage

# Dry run first — see what would be removed without deleting anything.
# (The 'statuses remove' step is skipped in dry-run: tootctl has no dry run for it.)
./mastodon-cleanup.sh --dry-run

# Normal run
./mastodon-cleanup.sh

# Tighter retention + also prune avatars and headers, just for this run
STATUSES_DAYS=14 MEDIA_DAYS=3 MEDIA_REMOVE_PROFILES=1 MEDIA_REMOVE_HEADERS=1 \
  ./mastodon-cleanup.sh

Scheduling

Option A — cron (run as the mastodon user)

sudo crontab -u mastodon -e
# Optional: email cron output/errors to you
MAILTO=you@example.com

# Run every Sunday at 04:00. The script writes its own timestamped log.
0 4 * * 0 /home/mastodon/mastodon-cleanup.sh

Option B — systemd service + timer

/etc/systemd/system/mastodon-cleanup.service:

[Unit]
Description=Mastodon cleanup (tootctl maintenance)
After=network-online.target

[Service]
Type=oneshot
User=mastodon
Group=mastodon
# Optionally tune retention here:
# Environment=STATUSES_DAYS=14
# Environment=MEDIA_DAYS=3
ExecStart=/home/mastodon/mastodon-cleanup.sh

/etc/systemd/system/mastodon-cleanup.timer:

[Unit]
Description=Run Mastodon cleanup weekly

[Timer]
OnCalendar=Sun *-*-* 04:00:00
Persistent=true

[Install]
WantedBy=timers.target

Enable it:

sudo systemctl daemon-reload
sudo systemctl enable --now mastodon-cleanup.timer
systemctl list-timers mastodon-cleanup.timer   # check next run
journalctl -u mastodon-cleanup.service         # view output

Logging & exit codes

  • Every step is logged with a timestamp, the exact command run, and its duration, to both the console and LOG_FILE.
  • The run ends with a summary line: number of steps, number of failures, and total time.
  • Exit 0 if all steps succeeded; exit 1 if any step failed (so cron MAILTO or a systemd OnFailure= handler can alert you). A run skipped because another is already in progress also exits 0.

Notes & safety

  • First run can take a long time. statuses remove is a computationally heavy operation that builds temporary database indices; on a large instance the first cleanup can run for hours. Consider running it once by hand inside tmux/screen before trusting it to a scheduler.

  • media remove-orphans is slow, and on S3-compatible object storage it lists every object, which can incur API request charges.

  • rbenv/rvm and cron PATH. Cron runs with a minimal environment. If your Ruby is managed by rbenv/rvm, tootctl may fail to find Ruby. Point ENV_FILE at a small script that sets things up, e.g.:

    # /home/mastodon/cleanup.env
    export PATH="$HOME/.rbenv/bin:$PATH"
    eval "$(rbenv init -)"

    then run with ENV_FILE=/home/mastodon/cleanup.env.

  • Run as mastodon, not root. The script warns if it detects it is running as root.

  • Related command not included: tootctl accounts cull (remove remote accounts that no longer exist) is a heavier, network-dependent task that queries every remote server. It's intentionally left out of the routine job; run it manually now and then if you want.

References

About

A mastodon media cleaning script

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages