wiki: updates to existing articles

- 01-linux/networking/ssh-config-key-management.md
- 02-selfhosting/services/mastodon-instance-tuning.md (expanded)
- 05-troubleshooting/ansible-check-mode-false-positives.md — adds "Related
  pattern: command/shell skipped in check mode" section with the ebtables
  usrmerge diagnosis as worked example
- 05-troubleshooting/networking/windows-openssh-wsl-default-shell-breaks-remote-commands.md
- 05-troubleshooting/networking/windows-sshd-stops-after-reboot.md
- 05-troubleshooting/yt-dlp-fedora-js-challenge.md
This commit is contained in:
Marcus Summers 2026-04-21 09:15:31 -04:00
parent 2dbeb22ef9
commit 668891082e
6 changed files with 96 additions and 21 deletions

View file

@ -10,7 +10,11 @@ tags:
- remote-access
status: published
created: 2026-03-08
<<<<<<< Updated upstream
updated: 2026-04-14T14:27
=======
updated: 2026-04-18T11:13
>>>>>>> Stashed changes
---
# SSH Config and Key Management

View file

@ -1,11 +1,16 @@
---
title: "Mastodon Instance Tuning"
title: Mastodon Instance Tuning
domain: selfhosting
category: services
tags: [mastodon, fediverse, self-hosting, majortoot, docker]
tags:
- mastodon
- fediverse
- self-hosting
- majortoot
- docker
status: published
created: 2026-04-02
updated: 2026-04-02
updated: 2026-04-19T04:55
---
# Mastodon Instance Tuning
@ -28,34 +33,69 @@ The process depends on your deployment method (Docker vs bare metal) and Mastodo
## Media Cache Management
Federated content (avatars, headers, media from remote posts) gets cached locally. On a small instance this grows slowly, but over months it adds up — especially if you follow active accounts on large instances.
Federated content (avatars, headers, media from remote posts, preview cards) gets cached in S3. On an active single-user instance federating with large servers, this grows fast — the `majortoot` bucket hit **648 GB** with only ~7 GB of actual local content. The other ~620 GB was remote cache.
Reference: [Fedicache — Understanding Mastodon's media cache](https://notes.neatnik.net/2024/08/fedicache)
**Clean up cached remote media:**
### Check current usage
```bash
# Preview what would be removed (older than 7 days)
tootctl media remove --days 7 --dry-run
# Actually remove it
tootctl media remove --days 7
# For Docker deployments
docker exec mastodon-web tootctl media remove --days 7
# Bare metal (rbenv)
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
cd /home/mastodon/live
RAILS_ENV=production bin/tootctl media usage
```
**Automate with cron or systemd timer:**
Output breaks down by type with local vs total — the gap between those two numbers is all purgeable remote cache.
### Manual prune
Run these three commands to clear all remote cache types:
```bash
# Weekly cache cleanup — crontab
0 3 * * 0 docker exec mastodon-web tootctl media remove --days 7
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
export RAILS_ENV=production
cd /home/mastodon/live
# 1. Remote media attachments older than 7 days
bin/tootctl media remove --days=7 --concurrency=5
# 2. Remote avatars and headers (accounts not followed/following locally)
bin/tootctl media remove --prune-profiles --remove-headers --days=7 --concurrency=5
# 3. Preview card thumbnails older than 30 days
bin/tootctl preview_cards remove --days=30 --concurrency=5
```
**What gets removed:** Only cached copies of remote media. Local uploads (your posts, your users' posts) are never touched. Remote media will be re-fetched on demand if someone views the post again.
> **Note:** On a large cache (hundreds of GB, millions of objects), each command can take 3060+ minutes. Run in `tmux` to survive SSH disconnection.
**Storage impact:** On a single-user instance, remote media cache can still reach several GB over a few months of active federation. Regular cleanup keeps disk usage predictable.
### Automate with weekly cron
Deploy via `configure_mastodon_media_prune.yml` Ansible playbook. It installs a wrapper script and cron entry for the `mastodon` user.
Manual crontab entry:
```
0 3 * * 0 /home/mastodon/media-prune.sh
```
Log output goes to `/var/log/mastodon/media-prune.log`.
### Reduce S3 storage class costs
By default Mastodon uploads to S3 Standard ($0.023/GB/mo). Switching to Standard-IA halves the storage cost for infrequently accessed media:
```bash
# In /home/mastodon/live/.env.production
S3_STORAGE_CLASS=STANDARD_IA
```
Then restart Mastodon. New uploads will use Standard-IA ($0.0125/GB). Note the 30-day minimum charge per object — fine for media attachments, less ideal for very short-lived objects.
### What is and isn't removed
- ✅ **Removed:** Cached copies of remote users' media, avatars, headers, preview card thumbnails
- ✅ **Re-fetched on demand:** Remote media is pulled again if someone views the post
- ❌ **Never removed:** Your local posts' media, your account's avatar/header, Mastodon account export backups (`/backups/`)
- ❌ **Not affected:** PostgreSQL database, local disk usage outside S3
## Gotchas & Notes
- **Character limit changes break on upgrades.** Any source patch gets overwritten when you pull a new Mastodon release. Track your changes and reapply after updates.

View file

@ -11,7 +11,7 @@ tags:
- troubleshooting
status: published
created: 2026-04-18
updated: 2026-04-18T11:13
updated: 2026-04-19T04:57
---
# Ansible Check Mode False Positives in Verify/Assert Tasks
@ -118,6 +118,25 @@ Don't apply it to tasks that check pre-existing state (e.g., verifying a file ex
when: not ansible_check_mode
```
## Related pattern: `command` / `shell` skipped in check mode
The inverse problem shows up when a playbook registers output from `ansible.builtin.command` (or `shell`) and uses that output in a downstream conditional or `set_fact`. In check mode, `command` is **skipped by default** — the registered variable comes back with no `stdout`, and any `in` / containment check against it silently evaluates to False.
Saw this 2026-04-19 while writing `fix_ebtables_usrmerge.yml`. The play queried `update-alternatives --display ebtables` to detect whether a host ran the `nft` or `legacy` backend, then branched on that fact. Under `--check`, the query was skipped, the fact defaulted to `legacy` on every host, and the next task's existence check failed on the nft hosts (`/usr/bin/ebtables-legacy not found`). A real run was fine — but `--check` output looked like the playbook was broken.
**Fix:** force the detection task to run even in check mode, since it's a read-only query with no side effects.
```yaml
- name: Query current ebtables alternative
ansible.builtin.command: update-alternatives --display ebtables
register: alt_query
changed_when: false
failed_when: false
check_mode: false # force execution in --check so downstream conditionals see real data
```
Apply this to any `command`/`shell` task whose output feeds a `when:`, `set_fact`, or similar logic. Only safe when the task is genuinely read-only.
## Trade-off
Guarding with `when: not ansible_check_mode` means check mode won't validate these assertions. The benefit — no false failures — outweighs the gap because:

View file

@ -11,7 +11,11 @@ tags:
- powershell
status: published
created: 2026-04-03
<<<<<<< Updated upstream
updated: 2026-04-14T14:27
=======
updated: 2026-04-18T11:13
>>>>>>> Stashed changes
---
# Windows OpenSSH: WSL as Default Shell Breaks Remote Commands

View file

@ -10,7 +10,11 @@ tags:
- majorrig
status: published
created: 2026-04-02
<<<<<<< Updated upstream
updated: 2026-04-14T14:27
=======
updated: 2026-04-18T11:13
>>>>>>> Stashed changes
---
# Windows OpenSSH Server (sshd) Stops After Reboot

View file

@ -10,7 +10,11 @@ tags:
- deno
status: published
created: 2026-04-02
<<<<<<< Updated upstream
updated: 2026-04-14T14:27
=======
updated: 2026-04-18T11:13
>>>>>>> Stashed changes
---
# yt-dlp YouTube JS Challenge Fix (Fedora)