Skip to content

Rexit

Rexit maintains a private, incremental archive of Reddit messages and media on infra-services.

  • URL: https://rexit.infra.realemail.app
  • Host: infra-services
  • Internal Studio port: 3210 in Compose and the Traefik service label; inventory still records 8080 and needs reconciliation
  • Data: /srv/rexit
  • Schedule: weekly, Sunday around 03:20 America/Los_Angeles
  • Authentication: Authentik forward auth plus the Rexit owner session
  • Backup: Tier 1 Restic with an offsite B2 copy

Design

The same Rexit image provides two isolated workloads. A profile-gated exporter runs from rexit-export.service; the always-on Archive Studio serves search, curation, and guarded filesystem management. Only Studio joins the Traefik network.

Images are pulled by semantic version tag during predeploy.sh. Komodo skips compose pull (auto_pull = false) so deploy does not need Harbor credentials in the Periphery Docker config. Both workloads run as UID/GID 65532. Studio stores durable curation state beside the archive, while the exporter uses both systemd and application-level locks to prevent overlapping exports.

Operator commands

sudo systemctl start rexit-export.service
sudo journalctl -fu rexit-export.service
systemctl list-timers rexit-export.timer

The service emits Node Exporter textfile metrics. Prometheus warns on missing or failed runs and pages when no export has succeeded for eight days.

Troubleshooting

Ansible check failed at secret parsing

The source role explicitly runs its two read-only SOPS decryption tasks during --check; other tasks keep their normal inherited check-mode behavior. Checks need SOPS, encrypted inputs and usable key access, and handle decrypted values in memory. They are not secret-free preflights. Both producers, parsers and validation remain protected by no_log; do not disable it or print registered secret output.

Each decryption has a 60-second task-action timeout, including normal apply. Nonzero exits, timeouts, malformed JSON and missing required fields fail closed. The timeout is not a whole-play deadline or proof of remote process cancellation.

Confirm the deployed revision and preserve the failed invocation before choosing an action. Do not reset a failed unit, force an apply or start an export merely to clear a check failure. The source repair and synthetic tests do not establish live convergence or export/backup health. See the service operating contract for the dry-run prerequisites and limits.

Export failed

  1. Inspect journalctl -u rexit-export.service.
  2. Confirm the bearer token is current in services/rexit/.env.sops.yaml.
  3. Confirm the Harbor robot account can pull reg.realemail.app/rexit/rexit:<version>.
  4. Confirm /srv/rexit is owned by UID/GID 65532 and has free space.
  5. Reapply the rexit Ansible tag, then start the service manually.

Studio unavailable

  1. Confirm an export has produced /srv/rexit/manifest.json.
  2. Check docker logs rexit-studio.
  3. Check the Komodo rexit pre-deploy, deploy, and post-deploy stages.
  4. Confirm /etc/rexit/studio-password exists and is readable by UID 65532.
  5. Verify the authentik@file middleware is healthy.

Lock contention

Do not delete a lock while an export process is running. Check systemctl status rexit-export.service and docker ps first. A stale .rexit.lock file is harmless because the operating-system lock, not the file's existence, controls ownership.

Restore validation

Run:

sudo /opt/homelab/backups/restore-test.sh rexit

The test restores into an isolated temporary directory and validates the manifest, SQLite database, hardened gallery, and a deterministic media sample. See the service source README for full secret, deployment, and recovery details.