[Script] TrueNAS SCALE App Auto Updater — handles stopped Apps

I created a small Bash script to automate TrueNAS SCALE App updates during a maintenance window.

I originally developed it for my own TrueNAS system. One issue I encountered was that an App in the STOPPED state cannot be upgraded directly.

The script handles this by temporarily starting the stopped App, performing the upgrade, and then restoring it to its original STOPPED state.

Features

  • Detects Apps with upgrade_available == true

  • Updates Apps one at a time

  • RUNNING App → upgrade → remains RUNNING

  • STOPPED App → start → upgrade → STOPPED

  • Restores the original App state

  • Skips unexpected App states

  • Configurable update deadline

  • Detailed log

  • Optional email report using the TrueNAS configured SMTP settings

  • Designed to run from a TrueNAS Cron Job

Example

For a stopped App:

STOPPED

↓

START

↓

UPGRADE

↓

STOP

↓

STOPPED

I tested it on my TrueNAS SCALE system with Apps including elastic-search and photoprism. Both were successfully upgraded and restored to STOPPED.

The email report generated by the script looks like this:

TrueNAS App Update Report

Started: 2026-08-17 23:12:38

Finished: 2026-08-17 23:19:32

SUCCESSFUL UPDATES:

SUCCESS: elastic-search 1.4.15 → 1.4.17

SUCCESS: photoprism 1.4.9 → 1.4.10

FAILED / ABORTED:

None

RESTORED STOPPED APPS:

elastic-search restored to STOPPED

photoprism restored to STOPPED

The normal TrueNAS reboot remains scheduled for 03:00.

GitHub

TrueNAS SCALE App Auto Updater

https://github.com/nvivekd70/truenas-app-auto-updater

The GitHub repository contains the script, documentation, and MIT license.

Important

This is a community script and is not an official TrueNAS tool.

Please review and test the script in your own environment before using it for production workloads. TrueNAS SCALE versions and App behavior can change, so feedback from users running different releases would be very welcome.

If anyone tests it on another TrueNAS SCALE release, please share your experience, particularly with different App states and upgrade scenarios.

Just wanted to come and say thank you for making this.

This has taken a lot of annoyances out of my updating process, with a slower NAS system.

Been wanting to upgrade my NAS with a complete overhaul for about 1.5-2 years now but computer prices have been a super bummer for me personally.

This script has stopped my NAS from having complete docker.service meltdowns and from me having to do the manual start/upgrade/stops manually.

Well done @nvivekd70 on creating something very simple, but of complete value to I assume many others.

First off, thanks for making the App Auto-updater for TrueNAS; It’s been very useful for me. I have a test system running TN v27 and notice that the email produced by the script appears differently from that my v25 production system. The line formatting is gone and all of the output appears in one string. Looking into it, I find that this only happens with my Microsoft 365’s Classic Outlook client. If I look at the same email on my Android phone using Outlook or on a RoundCube web client, the email looks good.

Trying web searches to see how I could fix this, I couldn’t locate a way to fix Outlook’s behavior. I have modified my copy of your script which lets the emails look good on any client I’ve tried. Below is the send_report function from the script with three changed lines. I hope this is useful for you.

send_report() {
local subject="$1"
local html="$2"
local payload

if [ -z "$MAIL_TO" ]; then
    log "MAIL_TO is empty; email report not sent."
    return 0
fi

# Build valid JSON with jq rather than manually escaping JSON.
payload=$("$JQ" -n \
    --arg subject "$subject" \
    --arg html "<pre>$html</pre>" \
    --arg to "$MAIL_TO" \
    '{subject:$subject, html:$html, to:[$to]}')

if ! "$MIDCLT" call mail.send "$payload" >> "$LOG_FILE" 2>&1; then
    log "WARNING: mail.send failed."
    return 1
fi

return 0

}