Maintainerr Setup Guide - ajgillis04/GillisDockerDepot GitHub Wiki

Introduction

Maintainerr is an automated media cleanup tool that integrates with Plex, Sonarr, Radarr, and Overseerr. It uses rule-based logic to identify stale or unwatched content and supports dry-run auditing, tagging, and safe deletion workflows.

Prerequisites

  • Docker installed
  • API keys for Plex, Sonarr, Radarr, and Overseerr (if applicable)

Configuration Steps

Step 1: Container Setup (maintainerr.yaml)

Ensure your container is configured with correct user permissions and settings:

services:
  maintainerr:
    container_name: maintainerr.${HOST_NAME}
    hostname: maintainerr.${HOST_NAME}.local
    image: ghcr.io/jorenn92/maintainerr:latest
    environment:
      PUID: ${PUID}
      PGID: ${PGID}
      TZ: ${TZ}
      DOMAINNAME: ${DOMAINNAME}
      HOST_NAME: ${HOST_NAME}
    networks:
      - mediaserver
    ports:
      - "${MAINTAINERR_PORT}:6246"
    volumes:
      - ${DOCKERDIR}/maintainerr/data:/opt/data
      - ${DOCKERDIR}/logs/maintainerr:/var/log
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
      - "homepage.group=Media"
      - "homepage.name=Maintainerr"
      - "homepage.icon=maintainerr.png"
      - "homepage.href=https://maintainerr.${DOMAINNAME}/"
      - "homepage.description=Automated media cleanup and maintenance"

⚠️ Important: Set PUID and PGID to match a valid user/group on the host. Run id <your-user> to confirm, and chown -R the mounted volumes accordingly.

Step 2: Start the Container

Use the following command to start Maintainerr:

docker compose -p mediaserver -f docker-compose-server1.yaml up --detach

Step 3: Accessing the Maintainerr UI

  1. Open your browser and navigate to http://<your-ip-address>:6246.
  2. Log in with your Maintainerr credentials (if enabled).
  3. Navigate to the Settings tab to begin setup.

Step 4: Initial Integration Setup

Maintainerr supports direct integration with your media stack. This step ensures all services are connected and authenticated.


πŸ“Ί Plex Integration

  1. Go to the Settings β†’ Plex tab.
  2. Enter your Plex server IP and port (default: 32400).
  3. Paste your Plex token (found via Settings β†’ Account β†’ Show Advanced).
  4. Click Test Connection to verify.
  5. Click Save.

Maintainerr Plex Setup


🎬 Radarr Integration

  1. Go to Settings β†’ Radarr.
  2. Enter your Radarr IP, port, and API key.
  3. Click Test Connection.
  4. Click Save.

Maintainerr Radarr Setup


πŸ“Ί Sonarr Integration

  1. Go to Settings β†’ Sonarr.
  2. Enter your Sonarr IP, port, and API key.
  3. Click Test Connection.
  4. Click Save.

Maintainerr Sonarr Setup


πŸ“₯ Overseerr Integration

  1. Go to Settings β†’ Overseerr.
  2. Enter your Overseerr IP, port, and API key.
  3. Click Test Connection.
  4. Click Save.

Maintainerr Overseerr Setup


πŸ“Š Tautulli Integration (Optional)

  1. Go to Settings β†’ Tautulli.
  2. Enter your Tautulli IP, port, and API key.
  3. Click Test Connection.
  4. Click Save.

Maintainerr Tautulli Setup


πŸ”” Notifications

  1. Go to Settings β†’ Notifications.
  2. Choose your preferred method (e.g., Discord, Telegram, Gotify).
  3. Enter the webhook or token.
  4. Customize message templates if needed.
  5. Click Test Notification.
  6. Click Save.

Maintainerr Notifications


Step 5: Rule Configuration

Go to the Rules on the left side menu

Movies Ruleset

  • Uses Plex.viewCount, Radarr.dateAdded, and Radarr.tags to identify stale or unwatched movies.
  • Supports fallback logic if Radarr metadata is missing.
  • Example: delete if not tagged save, never watched, and added >2 years ago.

TV Shows Ruleset

  • Uses Sonarr.status, Plex.sw_allEpisodesSeenBy, Plex.sw_lastWatched, and Overseerr.isRequested.
  • Example: delete if request fulfilled, show ended, fully watched, and last watched >182 days ago.

Tags

You can add tags in Radarr / Sonarr to ensure media is protected or included.

  • Use list-import for items imported from lists (I added list-import on each Import List).
  • Use save to protect items from deletion.

maintaineer tv rules maintaineer movies rules

RULES

maintaineer tv rules TV Rules

mediaType: SHOWS
rules:
  - "0":
      - firstValue: Overseerr.isRequested
        action: EQUALS
        customValue:
          type: boolean
          value: "true"
      - operator: AND
        firstValue: Sonarr.tags
        action: NOT_CONTAINS_PARTIAL
        customValue:
          type: text
          value: save
  - "1":
      - firstValue: Overseerr.isRequested
        action: EQUALS
        customValue:
          type: boolean
          value: "true"
      - operator: AND
        firstValue: Sonarr.status
        action: EQUALS
        customValue:
          type: text
          value: ended
      - operator: AND
        firstValue: Plex.sw_allEpisodesSeenBy
        action: CONTAINS
        lastValue: Overseerr.addUser
      - operator: AND
        firstValue: Plex.sw_lastWatched
        action: BEFORE
        customValue:
          type: custom_days
          value: "182"
  - "2":
      - firstValue: Overseerr.isRequested
        action: EQUALS
        customValue:
          type: boolean
          value: "true"
      - operator: AND
        firstValue: Plex.sw_viewedEpisodes
        action: EQUALS
        customValue:
          type: number
          value: 0
      - operator: AND
        firstValue: Plex.sw_lastEpisodeAddedAt
        action: BEFORE
        customValue:
          type: custom_days
          value: "182"

maintaineer movies rules Movies Rules

mediaType: MOVIES
rules:
  - "0":
      - firstValue: Overseerr.isRequested
        action: EQUALS
        customValue:
          type: boolean
          value: "true"
      - operator: AND
        firstValue: Plex.seenBy
        action: CONTAINS
        lastValue: Overseerr.addUser
      - operator: AND
        firstValue: Plex.lastViewedAt
        action: BEFORE
        customValue:
          type: custom_days
          value: "182"
      - operator: AND
        firstValue: Radarr.tags
        action: NOT_CONTAINS_PARTIAL
        customValue:
          type: text
          value: save
  - "1":
      - operator: OR
        firstValue: Overseerr.isRequested
        action: EQUALS
        customValue:
          type: boolean
          value: "true"
      - operator: AND
        firstValue: Plex.viewCount
        action: EQUALS
        customValue:
          type: number
          value: 0
      - operator: AND
        firstValue: Plex.addDate
        action: BEFORE
        customValue:
          type: custom_days
          value: "730"
      - operator: AND
        firstValue: Radarr.tags
        action: NOT_CONTAINS_PARTIAL
        customValue:
          type: text
          value: save
  - "2":
      - operator: OR
        firstValue: Radarr.tags
        action: CONTAINS
        customValue:
          type: text
          value: list-import
      - operator: AND
        firstValue: Plex.viewCount
        action: EQUALS
        customValue:
          type: number
          value: 0
      - operator: AND
        firstValue: Radarr.addDate
        action: BEFORE
        customValue:
          type: custom_days
          value: "730"
      - operator: OR
        firstValue: Plex.addDate
        action: BEFORE
        customValue:
          type: custom_days
          value: "730"
      - operator: AND
        firstValue: Radarr.tags
        action: NOT_CONTAINS_PARTIAL
        customValue:
          type: text
          value: save
  - "3":
      - operator: OR
        firstValue: Radarr.tags
        action: CONTAINS
        customValue:
          type: text
          value: list-import
      - operator: AND
        firstValue: Plex.lastViewedAt
        action: BEFORE
        customValue:
          type: custom_days
          value: "730"
      - operator: AND
        firstValue: Radarr.tags
        action: NOT_CONTAINS_PARTIAL
        customValue:
          type: text
          value: save

Step 6: Scheduling Jobs

Use cron expressions to control when Maintainerr runs:

Job Type Cron Expression Description
Rule Handler 0 3 * * * Identifies media for deletion
Collection Handler 0 4 * * * Deletes stale/unwatched movies

πŸ•’ All jobs run overnight to avoid peak usage hours.

Step 7: Backup and Restore Procedures

Regular Backups:

  • Backup /opt/data and /var/log volumes weekly.
  • Include maintainerr.db and config.yaml if present.

Restoration Process:

  1. Start a new container with the same volume mounts.
  2. Copy backup files into the new container’s data directory: &&& sudo cp /share/PathToOldContainer/maintainerr/data/config.yaml /share/PathToNewContainer/maintainerr/data/config.yaml
    sudo cp /share/PathToOldContainer/maintainerr/data/maintainerr.db /share/PathToNewContainer/maintainerr/data/maintainerr.db &&&
  3. Restart the container and verify rule integrity.

Step 8: Troubleshooting

  • Dry-run first: Always test rules before enabling deletion.
  • Logs: Check /var/log for rule matches and errors.
  • Permissions: Ensure UID/GID match host user or container will crash-loop.
  • Support: Maintainerr GitHub
⚠️ **GitHub.com Fallback** ⚠️