Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions ct/maintainerr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: tumeden
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/Maintainerr/Maintainerr

APP="Maintainerr"
var_tags="${var_tags:-media}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-18}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"

header_info "$APP"
variables
color
catch_errors

function build_maintainerr() {
NODE_VERSION="24" setup_nodejs
msg_info "Preparing Build Runtime"
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
$STD corepack enable
if [[ -f /opt/maintainerr/package.json ]]; then
if command -v jq >/dev/null 2>&1; then
yarn_spec=$(jq -r '.packageManager // empty' /opt/maintainerr/package.json 2>/dev/null || true)
if [[ -n "$yarn_spec" && "$yarn_spec" == yarn@* ]]; then
yarn_ver="${yarn_spec#yarn@}"
yarn_ver="${yarn_ver%%+*}"
$STD corepack prepare "yarn@${yarn_ver}" --activate || true
fi
fi
fi
msg_ok "Prepared Build Runtime"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is far from out standards, please take a look at the docs folder on ProxmoxVE and also when using ai, use the AI.md in docs folder of ProxmoxVED folder.


msg_info "Building Maintainerr (Patience)"
cd /opt/maintainerr || { msg_error "Failed to change to /opt/maintainerr"; return 1; }
cat <<'EOF' >/opt/maintainerr/apps/ui/.env
VITE_BASE_PATH=/__PATH_PREFIX__
EOF
export NODE_OPTIONS="--max-old-space-size=4096"
$STD yarn install --immutable --network-timeout 99999999
$STD yarn turbo build
$STD yarn workspaces focus --all --production
mkdir -p /opt/maintainerr/apps/server/dist/ui
cp -a /opt/maintainerr/apps/ui/dist/. /opt/maintainerr/apps/server/dist/ui/
ln -sfnT /opt/maintainerr /opt/app
msg_ok "Built Maintainerr"
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't need to be a function, move it down to the update_script block


function update_script() {
header_info
check_container_storage
check_container_resources

if [[ ! -d /opt/maintainerr ]]; then
msg_error "No ${APP} Installation Found!"
exit 1
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.

if check_for_gh_release "maintainerr" "Maintainerr/Maintainerr"; then
msg_info "Stopping Service"
systemctl stop maintainerr
msg_ok "Stopped Service"

CLEAN_INSTALL=1 fetch_and_deploy_gh_release "maintainerr" "Maintainerr/Maintainerr" "tarball" "latest" "/opt/maintainerr"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "maintainerr" "Maintainerr/Maintainerr" "tarball" "latest" "/opt/maintainerr"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "maintainerr" "Maintainerr/Maintainerr" "tarball"

build_maintainerr

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
build_maintainerr


msg_info "Starting Service"
systemctl daemon-reload

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
systemctl daemon-reload

systemctl start maintainerr
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}

start
build_container
description

msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:6246${CL}"
44 changes: 44 additions & 0 deletions frontend/public/json/maintainerr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "Maintainerr",
"slug": "maintainerr",
"categories": [
13
],
"date_created": "2026-03-06",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 6246,
"documentation": "https://docs.maintainerr.info/latest/Installation/",
"website": "https://maintainerr.info/",
"logo": "https://raw.githubusercontent.com/Maintainerr/Maintainerr/main/apps/ui/public/logo_black.svg",
"config_path": "/etc/maintainerr/maintainerr.conf",
"description": "Maintainerr is a tool that automatically cleans up media libraries on servers like Plex or Jellyfin. It analyzes your library and related apps (such as Sonarr, Radarr, Seerr, or Tautulli) to find movies or TV shows that are unwatched, old, or no longer wanted",
"install_methods": [
{
"type": "default",
"script": "ct/maintainerr.sh",
"resources": {
"cpu": 4,
"ram": 4096,
"hdd": 18,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Initial install and updates build from source and may take several minutes.",
"type": "warning"
},
{
"text": "Data is persisted in /opt/data.",
"type": "info"
}
]
}
128 changes: 128 additions & 0 deletions install/maintainerr-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#!/usr/bin/env bash

# Copyright (c) 2021-2026 community-scripts ORG
# Author: tumeden
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/Maintainerr/Maintainerr

source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os

msg_info "Installing Dependencies"
$STD apt-get install -y \
build-essential \
python3
msg_ok "Installed Dependencies"

fetch_and_deploy_gh_release "maintainerr" "Maintainerr/Maintainerr" "tarball" "latest" "/opt/maintainerr"

NODE_VERSION="24" setup_nodejs
msg_info "Preparing Build Runtime"
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
$STD corepack enable
if [[ -f /opt/maintainerr/package.json ]]; then
if command -v jq >/dev/null 2>&1; then
yarn_spec=$(jq -r '.packageManager // empty' /opt/maintainerr/package.json 2>/dev/null || true)
if [[ -n "$yarn_spec" && "$yarn_spec" == yarn@* ]]; then
yarn_ver="${yarn_spec#yarn@}"
yarn_ver="${yarn_ver%%+*}"
$STD corepack prepare "yarn@${yarn_ver}" --activate || true
fi
fi
fi
mkdir -p /opt/data/logs /etc/maintainerr
ln -sfnT /opt/maintainerr /opt/app
msg_ok "Prepared Build Runtime"

msg_info "Building Maintainerr (Patience)"
cd /opt/maintainerr || { msg_error "Failed to change to /opt/maintainerr"; exit 1; }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cd /opt/maintainerr || { msg_error "Failed to change to /opt/maintainerr"; exit 1; }
cd /opt/maintainerr

cat <<'EOF' >/opt/maintainerr/apps/ui/.env

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cat <<'EOF' >/opt/maintainerr/apps/ui/.env
cat <<EOF >/opt/maintainerr/apps/ui/.env

VITE_BASE_PATH=/__PATH_PREFIX__
EOF
export NODE_OPTIONS="--max-old-space-size=4096"
$STD yarn install --immutable --network-timeout 99999999
$STD yarn turbo build
$STD yarn workspaces focus --all --production
mkdir -p /opt/maintainerr/apps/server/dist/ui
cp -a /opt/maintainerr/apps/ui/dist/. /opt/maintainerr/apps/server/dist/ui/
msg_ok "Built Maintainerr"

msg_info "Creating Start Script"
cat <<'EOF' >/opt/maintainerr/start.sh
#!/usr/bin/env bash
set -euo pipefail

BASE_PATH_REPLACE="${BASE_PATH:-}"
UI_DIST_DIR="/opt/maintainerr/apps/server/dist/ui"
BASE_PATH_MARKER="/opt/maintainerr/.base-path-applied"

if [[ ! -d "$UI_DIST_DIR" ]]; then
echo "Missing UI build directory: $UI_DIST_DIR" >&2
exit 1
fi

if grep -R -q -- '/__PATH_PREFIX__' "$UI_DIST_DIR"; then
ESCAPED_BASE_PATH="${BASE_PATH_REPLACE//\\/\\\\}"
ESCAPED_BASE_PATH="${ESCAPED_BASE_PATH//&/\\&}"
if ! find "$UI_DIST_DIR" -type f -not -path '*/node_modules/*' -print0 | xargs -0 sed -i "s,/__PATH_PREFIX__,$ESCAPED_BASE_PATH,g"; then
echo "Failed to rewrite UI base paths under $UI_DIST_DIR" >&2
exit 1
fi
printf '%s' "$BASE_PATH_REPLACE" >"$BASE_PATH_MARKER"
elif [[ -f "$BASE_PATH_MARKER" ]]; then
APPLIED_BASE_PATH="$(cat "$BASE_PATH_MARKER")"
if [[ "$APPLIED_BASE_PATH" != "$BASE_PATH_REPLACE" ]]; then
echo "BASE_PATH changed from '$APPLIED_BASE_PATH' to '$BASE_PATH_REPLACE', but UI assets were already rewritten. Rebuild Maintainerr to apply a new BASE_PATH." >&2
exit 1
fi
else
# Compatibility path for installs created before marker tracking existed.
printf '%s' "$BASE_PATH_REPLACE" >"$BASE_PATH_MARKER"
fi

exec npm run --prefix /opt/maintainerr/apps/server start

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

EOF
Comment thread
coderabbitai[bot] marked this conversation as resolved.
chmod +x /opt/maintainerr/start.sh
msg_ok "Created Start Script"

msg_info "Configuring Maintainerr"
cat <<'EOF' >/etc/maintainerr/maintainerr.conf

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cat <<'EOF' >/etc/maintainerr/maintainerr.conf
cat <<EOF >/etc/maintainerr/maintainerr.conf

UI_PORT=6246
UI_HOSTNAME=0.0.0.0
VERSION_TAG=stable
DEBUG=false
BASE_PATH=
EOF
msg_ok "Configured Maintainerr"

msg_info "Creating Service"
cat <<'EOF' >/etc/systemd/system/maintainerr.service

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cat <<'EOF' >/etc/systemd/system/maintainerr.service
cat <<EOF >/etc/systemd/system/maintainerr.service

[Unit]
Description=Maintainerr Service
Wants=network-online.target
After=network-online.target

[Service]
EnvironmentFile=/etc/maintainerr/maintainerr.conf
Environment=NODE_ENV=production
Type=simple
Restart=on-failure
RestartSec=5
WorkingDirectory=/opt/maintainerr
ExecStart=/opt/maintainerr/start.sh

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
systemctl daemon-reload

systemctl enable -q --now maintainerr
msg_ok "Created Service"

motd_ssh
customize
cleanup_lxc