Wise-Wren

Wise-Wren

Docker app from Ferdinand99's Repository

Overview

Wise Wren keeps the Docker containers on your servers up to date, without surprises. One small Rust binary with SQLite. It finds what runs on each server (containers, Unraid template containers, Compose stacks and script-updated stacks), checks the registries for new versions on your schedule and tells you through ~40 notification services (ntfy, email, Discord and more). It updates only what you approve, now or at a time you choose, or what you explicitly allow inside an automatic window. Every update: the new image pulled first, a snapshot of the data, a health check after, and an automatic rollback if it fails. With Vigilant Vole 0.9.0 or later, updates open maintenance windows and use your monitors as part of the health check. This is the server (web UI, API, database). Each Docker host also needs the Wise Wren Agent template; add the server under Servers in Wren first to get its token. Also: a REST API with OpenAPI, MCP tools, users with roles and two-factor sign-in, 26 languages. Setup: open the WebUI after the first start and create the admin account. Set WW_PUBLIC_URL to the address the agents use. Snapshots are rollback points, not backups: keep your own backups. Everything lives in /data (appdata).

Wise Wren

Keeps your Docker containers up to date, without surprises.

License: MIT Website

Status: early release (Docker images only). Wren lists what runs on each server (containers, Unraid template containers, Compose stacks and script-updated stacks), checks for new versions and updates what you approve, now or at a time you choose, with a snapshot, a health check and an automatic rollback. Automatic updates inside a window, the Vigilant Vole integration (maintenance windows and monitor-based health checks), ~40 notification channels, a REST API with OpenAPI and MCP tools, in 26 languages. It is tested on Unraid; other Linux Docker hosts are best-effort, btrfs subvolume snapshots are untested on real pools and ZFS uses plain copies. The translations are unreviewed drafts. Installers and static binaries come later. The design is in docs/design.md; to build and run it, see docs/development.md.

Wise Wren ("Wren") keeps the Docker containers on your servers up to date. It checks for new versions on a schedule you choose, tells you about them, and updates only what you approve, or what you have explicitly allowed it to update on its own.

Today, keeping a home server current often means a manual check every day. Unraid's update button covers containers made from its templates, but not Compose stacks or apps that update with a vendor's own script. Other tools either only notify (Diun, What's Up Docker) or update blindly (Watchtower). None of them pause your monitoring, take a snapshot first, check health afterwards and roll back.

What it does

  • Notify, approve or automatic. Each server has a default mode and each target can override it. Approve is the default: one click updates now, or at a time you choose.
  • Scheduled updates. Approve during the day, update tonight. A scheduled update shows as planned maintenance in Vigilant Vole ahead of time.
  • Safe updates, every time. Each run goes through the same steps:
    1. preflight: the new image is pulled before anything stops;
    2. a maintenance window opens in Vigilant Vole;
    3. the target stops gracefully;
    4. a snapshot of its data is taken;
    5. the update runs;
    6. a health check: the containers are healthy and the linked monitors stay up;
    7. on failure, an automatic rollback of the image or Compose files and the data;
    8. the window closes and you get the result.
  • Notifications through the same ~40 channels as Vigilant Vole, from ntfy on your phone to email and Discord. One per new version, with a digest option.
  • One Wren, several servers, through a small agent on each.

Three kinds of targets

Kind Example New version means
Containers, including Unraid template containers nextcloud The image in the registry has changed
Docker Compose stacks immich Any of the stack's images has changed
Script-updated stacks Fluxer, updated with the vendor's installer A source such as GitHub releases reports a newer version

Wren never changes anything you haven't allowed

With automatic updates off, which is the default for every server and target, Wren updates nothing on its own. Automatic updates only run inside a window you set, and any container or stack can be excluded. An approval is for one version: if a newer one appears before it runs, Wren asks again. Scripts are defined on each server, and Wren can only ask for them by name, so it can never become a remote shell.

Install

Wren is a server (the web UI, once) plus a small agent on every Docker host it looks after. Start the server:

mkdir wise-wren && cd wise-wren
curl -fsSLO https://raw.githubusercontent.com/Ferdinand99/Wise-Wren/main/docker-compose.yml
docker compose up -d

Open http://<host>:3003/setup to create the first admin, set the address agents use under Settings → General (or WW_PUBLIC_URL), then Servers → Add server: Wren shows the agent's token once, with the docker run line for that host. On Unraid, install Wise Wren and Wise Wren Agent from Community Applications (templates). Images are on GHCR for amd64 and arm64: ghcr.io/ferdinand99/wise-wren and ghcr.io/ferdinand99/wise-wren-agent, :<version> or :latest.

The agent has the Docker socket, which is root on its host. Read the guides before the first update:

Planned for v1

Updates Around them
Containers, Unraid templates, Compose stacks, script stacks Docker Hub, GHCR, Quay and any OCI registry; GitHub releases
Notify, approve or automatic, per server and per target Release notes with each update, when Wren can find them
Scheduled updates and automatic windows with exclusions Vigilant Vole maintenance windows and monitor-based health checks
Snapshot before, health check after, automatic rollback Notifications to ~40 channels
A history of every run, step by step REST API and MCP tools for everything the web UI can do

Most of the table is in the early releases; static binaries, a Linux installer and wider testing on other Linux hosts come before v1.0. Not in v1: the iOS app (planned later), updating Unraid OS, plugins, VMs, LXC or Kubernetes, building images from source, and offsite backups (Wren's snapshots are short-lived rollback points, not backups). See docs/design.md for the full scope and the phases.

Wren is part of Hedgerow, a family of small self-hosted apps, with Vigilant Vole, Nimble Newt and Keen Kestrel. Like its siblings, it is one Rust binary with SQLite in the family's design, plus a small agent for each server.

License

MIT

Requirements

Early release (v0.1). Each server Wren looks after needs the Wise Wren Agent container.

Related apps

Details

Repository
ghcr.io/ferdinand99/wise-wren:latest
Last Updated2026-10-26
First Seen2026-10-26

Runtime arguments

Web UI
http://[IP]:[PORT:3003]/
Network
bridge
Shell
sh
Privileged
false

Template configuration

WebUI portPorttcp

Web interface, REST API, MCP and the agents' endpoint.

Target
3003
Default
3003
Value
3003
DataPathrw

wren.sqlite, the session key (which also seals registry passwords and the Vigilant Vole token) and pre-migration backups. Ownership is set to PUID:PGID on every start.

Target
/data
Default
/mnt/user/appdata/wise-wren
Value
/mnt/user/appdata/wise-wren
WW_PUBLIC_URLVariable

The address agents and people use, e.g. http://192.168.1.10:3003 or https://wren.example.com. Used in the agents' docker run lines and notification links. Without it, each request's own address is used.

WW_TRUST_PROXYVariable

Set to 1 when Wren is reached through a reverse proxy or tunnel (SWAG, Nginx Proxy Manager, Traefik, Pangolin) that sets X-Forwarded-* headers.

Default
0
Value
0
WW_SETUP_TOKENVariable

Optional. When set, the first-run /setup page only opens with ?token=VALUE, so nobody else can create the admin account.

WW_ALLOW_PRIVATE_VERSION_URLSVariable

Set to 1 to let script stacks' url version sources reach private and local addresses (a version file on your LAN). Leave it at 0 unless you need it.

Default
0
Value
0
PUIDVariable

User id the app runs as (Unraid: 99 = nobody).

Default
99
Value
99
PGIDVariable

Group id the app runs as (Unraid: 100 = users).

Default
100
Value
100
TZVariable

Time zone for log timestamps (pages use Settings, General, time zone).

Default
Europe/Oslo
Value
Europe/Oslo
RUST_LOGVariable

Log level filter.

Default
info
Value
info