Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
ba0b451
fix: update plugin URL to point to the dev branch
mstrhakr May 31, 2026
34009ee
fix: correct version and package details in plugin metadata
mstrhakr May 31, 2026
5644e4b
feat: show docker.versions changelogs in the update dialog
thetic Jun 1, 2026
61289f8
test: add unit tests for getSavedUpdateStatus docker.versions detection
thetic Jun 1, 2026
3736859
docs: document docker.versions changelog integration in user guide
thetic Jun 1, 2026
1e26d68
feat: return to update dialog when changelog is dismissed
thetic Jun 1, 2026
6aba01d
fix: discard stale Nchan buffer and concurrent changelog messages
thetic Jun 1, 2026
e5ce524
fix: whitelist changelog message types, filter scaffolding noise
thetic Jun 1, 2026
ec6d67e
refactor: delegate changelog display to docker.versions' showChangeLog()
thetic Jun 4, 2026
83f6624
fix: plug poll interval leak and skip dialog reopen when warnings dis…
thetic Jun 4, 2026
e246ff8
Potential fix for pull request finding
thetic Jun 4, 2026
a35982e
Merge pull request #116 from thetic/docker-versions-changelog
mstrhakr Jun 5, 2026
e2fbe93
fix(profiles): unify action profile picker and enforce profile preced…
mstrhakr Jun 7, 2026
17d5fa0
fix(composeSortable): improve drag-and-drop behavior by detaching non…
mstrhakr Jun 7, 2026
a42c490
fix(composeSortable): enhance details row detachment logic during dra…
mstrhakr Jun 8, 2026
b95c557
fix(update): update button now triggers update action instead of alwa…
mstrhakr Jun 9, 2026
492e6cf
feat(container): add persistent container cache and icon resolution l…
mstrhakr Jun 9, 2026
0ebfc01
feat: add progressive stack list loading
mstrhakr Jun 9, 2026
ed8019c
fix(changelog): conditionally load changelog script if available so i…
mstrhakr Jun 9, 2026
0cf655b
fix(compose): optimize cache invalidation logic based on stack/contai…
mstrhakr Jun 9, 2026
0d51c4a
fix(docker.versions): conditionally load external styles for Docker v…
mstrhakr Jun 9, 2026
e6faf7d
chore: remove test compose setup
mstrhakr Jun 11, 2026
a0a573f
fix(sync-plugin-url): enhance branch detection and pluginURL synchron…
mstrhakr Jun 11, 2026
4acb364
chore: sync pluginURL+README for dev branch [skip ci]
github-actions[bot] Jun 11, 2026
339100d
fix(Exec.php): improve dockerVersionsInstalled check to verify actual…
mstrhakr Jun 11, 2026
363c97a
fix(composeLoadlist): bind autostart change handler early for dynamic…
mstrhakr Jun 11, 2026
292111a
fix(ExecActionsTest): improve testGetSavedUpdateStatusDockerVersionsN…
mstrhakr Jun 11, 2026
0522b1b
chore: update changelog for v2026.06.11.1517 [skip ci]
github-actions[bot] Jun 11, 2026
36f6cb9
Release v2026.06.11.1517 [skip ci]
github-actions[bot] Jun 11, 2026
7551d4b
fix(Exec.php): update dockerVersionsInstalled check to verify plugin …
mstrhakr Jun 11, 2026
d2cdb7f
fix(deploy.sh, test.sh): update file permissions to make scripts exec…
mstrhakr Jun 11, 2026
f14bc73
chore: update changelog for v2026.06.11.1526 [skip ci]
github-actions[bot] Jun 11, 2026
864ad19
Release v2026.06.11.1526 [skip ci]
github-actions[bot] Jun 11, 2026
6c392f9
fix(cache): add endpoint to retrieve persistent container cache and u…
mstrhakr Jun 12, 2026
4dbbccf
feat: add 'Remove Orphans by Default' option and integrate into compo…
mstrhakr Jun 12, 2026
fb0a9c8
Add support for additional compose files per stack
Joly0 Jun 12, 2026
8549baa
Fix dropdown z-index on docker page when clicking on stack icon
Joly0 Jun 12, 2026
9cb712f
Merge branch 'dev' into feature/additional-compose-files
mstrhakr Jun 14, 2026
0ca6ac9
refactor: update echoComposeCommand and echoComposeCommandMultiple to…
mstrhakr Jun 14, 2026
4dcccd0
fix: delay stack refresh after prompt to ensure proper UI feedback
mstrhakr Jun 14, 2026
1a09e52
feat(tests): add tests for pruning auto-managed and legacy labels onl…
mstrhakr Jun 14, 2026
4974c0b
fix: add support for removeOrphans flag in performComposeAction
mstrhakr Jun 14, 2026
c3f68e7
fix: add support for --remove-orphans flag in compose command
mstrhakr Jun 14, 2026
5bd1628
fix: enhance logging for stack management and settings handling
mstrhakr Jun 14, 2026
20e8303
chore: update changelog for v2026.06.14.1451 [skip ci]
github-actions[bot] Jun 14, 2026
b77c486
Release v2026.06.14.1451 [skip ci]
github-actions[bot] Jun 14, 2026
48b45d4
Merge branch 'dev' into feature/additional-compose-files
mstrhakr Jun 14, 2026
68d10e1
Merge pull request #121 from Joly0/feature/additional-compose-files
mstrhakr Jun 14, 2026
dd8fa0e
chore: update changelog for v2026.06.14.1530 [skip ci]
github-actions[bot] Jun 14, 2026
cff9e04
Merge pull request #122 from Joly0/Fix-dropdown-z-index
mstrhakr Jun 14, 2026
5c69ed6
Release v2026.06.14.1530 [skip ci]
github-actions[bot] Jun 14, 2026
eb6ec74
chore: update changelog for v2026.06.14.1531 [skip ci]
github-actions[bot] Jun 14, 2026
1122126
Release v2026.06.14.1531 [skip ci]
github-actions[bot] Jun 14, 2026
894b6d8
feat: Add column visibility customization for stack and service tables
mstrhakr Jun 14, 2026
3decd34
feat: Implement snapshot loading for compose metrics and enhance data…
mstrhakr Jun 14, 2026
b9226c1
feat: promote col customizer and remove basic/advanced toggle
mstrhakr Jun 15, 2026
b41d4f3
feat: add expand/collapse all functionality for compose stacks
mstrhakr Jun 15, 2026
eb3e6df
feat: enhance stack toggle functionality with batching and user inten…
mstrhakr Jun 15, 2026
bfc0b16
feat: refactor column customization UI with transfer lists and respon…
mstrhakr Jun 15, 2026
085daba
chore: update changelog for v2026.06.15.1000 [skip ci]
github-actions[bot] Jun 15, 2026
f15a815
Release v2026.06.15.1000 [skip ci]
github-actions[bot] Jun 15, 2026
445ebb5
feat: add custom interval settings for compose stats and enhance ncha…
mstrhakr Jun 16, 2026
19fc301
perf: implement parallel project loading with request queuing and pro…
mstrhakr Jun 16, 2026
1dee86c
perf(compose): debounce composeListRefreshed during progressive row load
mstrhakr Jun 16, 2026
d523501
perf(compose): avoid full-table applyListView during progressive row …
mstrhakr Jun 16, 2026
2fbb618
perf(compose): throttle dockerload cache paints during websocket bursts
mstrhakr Jun 16, 2026
a109007
fix(composeStats): enhance memory value parsing and sanitize docker s…
mstrhakr Jun 16, 2026
07cfea0
feat(compose): add health status column and related functionality to …
mstrhakr Jun 18, 2026
c52ac0f
feat(compose): implement stack row striping synchronization for impro…
mstrhakr Jun 18, 2026
8561a42
feat(compose): enhance column customization with reorder functionalit…
mstrhakr Jun 18, 2026
0eb6d6a
chore: update changelog for v2026.06.18.1637 [skip ci]
github-actions[bot] Jun 18, 2026
8fbe44b
Release v2026.06.18.1637 [skip ci]
github-actions[bot] Jun 18, 2026
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
58 changes: 47 additions & 11 deletions .github/workflows/sync-plugin-url.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@
# This prevents issues when merging between dev and main where the
# pluginURL would reference the wrong branch for update checks.
#
# Triggers only on PR merges to main or dev (the only time the
# pluginURL branch reference can be wrong is after a cross-branch merge)
# Triggers on push and merged PRs to main/dev to self-heal branch links.

name: Sync Plugin URL

on:
push:
branches: [main, dev]
pull_request:
types: [closed]
branches: [main, dev]
workflow_dispatch:

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
Expand All @@ -26,32 +28,66 @@ jobs:
permissions:
contents: write
runs-on: ubuntu-latest
# Only run if the PR was actually merged (not just closed)
if: github.event.pull_request.merged == true
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged == true)

steps:
- name: Resolve target branch
id: target
run: |
if [[ "${GITHUB_EVENT_NAME}" == "push" ]]; then
TARGET_BRANCH="${GITHUB_REF_NAME}"
elif [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then
TARGET_BRANCH="${{ github.event.pull_request.base.ref }}"
else
TARGET_BRANCH="${GITHUB_REF_NAME}"
fi

case "$TARGET_BRANCH" in
main|dev)
echo "target_branch=$TARGET_BRANCH" >> "$GITHUB_OUTPUT"
;;
*)
echo "Unsupported branch '$TARGET_BRANCH'; skipping."
echo "target_branch=" >> "$GITHUB_OUTPUT"
;;
esac

- name: Checkout repository
if: steps.target.outputs.target_branch != ''
uses: actions/checkout@v6
with:
ref: ${{ steps.target.outputs.target_branch }}
token: ${{ secrets.GITHUB_TOKEN }}

- name: Check and fix pluginURL branch + README badge
if: steps.target.outputs.target_branch != ''
id: check
run: |
BRANCH="${GITHUB_REF_NAME}"
BRANCH="${{ steps.target.outputs.target_branch }}"
PLG_FILE="compose.manager.plg"
README_FILE="source/compose.manager/README.md"
NEEDS_COMMIT=false

# Ensure pluginURL uses the current branch
CURRENT_URL_BRANCH=$(grep -oP '<!ENTITY pluginURL.*github;/\K[^/]+' "$PLG_FILE" || echo "unknown")
CURRENT_URL_BRANCH=$(sed -n 's#^<!ENTITY pluginURL "https://raw.githubusercontent.com/&github;/\([^/]*\)/&name;\.plg">$#\1#p' "$PLG_FILE")
if [[ -z "$CURRENT_URL_BRANCH" ]]; then
echo "Failed to parse pluginURL entity in $PLG_FILE"
exit 1
fi

echo "Current branch: $BRANCH"
echo "PLG pluginURL branch: $CURRENT_URL_BRANCH"

if [[ "$CURRENT_URL_BRANCH" != "$BRANCH" ]]; then
echo "Branch mismatch - fixing pluginURL..."
# Scope to pluginURL line only — avoids corrupting packageURL
sed -i "/pluginURL/s|/&github;/[^/]*/|/\&github;/${BRANCH}/|" "$PLG_FILE"
sed -i -E "s#^<!ENTITY pluginURL \"https://raw.githubusercontent.com/&github;/[^/]*/&name;\\.plg\">#<!ENTITY pluginURL \"https://raw.githubusercontent.com/&github;/${BRANCH}/&name;.plg\">#" "$PLG_FILE"

EXPECTED_LINE="<!ENTITY pluginURL \"https://raw.githubusercontent.com/&github;/${BRANCH}/&name;.plg\">"
if ! grep -Fxq "$EXPECTED_LINE" "$PLG_FILE"; then
echo "pluginURL rewrite verification failed"
exit 1
fi

NEEDS_COMMIT=true
else
echo "pluginURL already correct"
Expand Down Expand Up @@ -81,12 +117,12 @@ jobs:
echo "needs_commit=$NEEDS_COMMIT" >> $GITHUB_OUTPUT

- name: Commit fix
if: steps.check.outputs.needs_commit == 'true'
if: steps.target.outputs.target_branch != '' && steps.check.outputs.needs_commit == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

git add compose.manager.plg source/compose.manager/README.md
git commit -m "chore: sync pluginURL+README for ${GITHUB_REF_NAME} branch [skip ci]"
git pull --rebase origin "${GITHUB_REF_NAME}"
git commit -m "chore: sync pluginURL+README for ${{ steps.target.outputs.target_branch }} branch [skip ci]"
git pull --rebase origin "${{ steps.target.outputs.target_branch }}"
git push
23 changes: 16 additions & 7 deletions compose.manager.plg
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
<!DOCTYPE PLUGIN [
<!ENTITY name "compose.manager">
<!ENTITY author "mstrhakr">
<!ENTITY version "2026.06.06">
<!ENTITY version "2026.06.18.1637">
<!ENTITY launch "Settings/&name;.settings">
<!ENTITY packageVER "&version;">
<!ENTITY packageMD5 "8cf5a8e4f40a712f63ca06fb0c7aee5c">
<!ENTITY pkgBUILD "0513">
<!ENTITY packageMD5 "c555ac177f88ba7bfca46b205eb9136a">
<!ENTITY pkgBUILD "1637">
<!ENTITY packageName "&name;-&packageVER;-noarch-&pkgBUILD;">
<!ENTITY packagefile "&packageName;.txz">
<!ENTITY github "mstrhakr/compose_plugin">
<!ENTITY pluginURL "https://raw.githubusercontent.com/&github;/main/&name;.plg">
<!ENTITY pluginURL "https://raw.githubusercontent.com/&github;/dev/&name;.plg">
<!ENTITY packageURL "https://github.com/&github;/releases/download/v&version;/&packagefile;">
<!ENTITY pluginsPATH "/boot/config/plugins">
<!ENTITY pluginLOC "&pluginsPATH;/&name;">
Expand All @@ -36,9 +36,18 @@
>

<CHANGES>
###2026.06.06
- Bug Fixes: update container cache loading to use PHP endpoint and improve data parsing; [Bug]: [error] 12159#12159: *38373 open() "/usr/local/emhttp/plugins/compose.manager/containers.cache.json" failed (2: No such file or directory) while sending to client Fixes mstrhakr/compose_plugin#117
- [View all changes](https://github.com/mstrhakr/compose_plugin/compare/v2026.05.31...v2026.06.06)
###2026.06.18.1637
- Features (compose): enhance column customization with reorder functionality and UI updates
- Features (compose): implement stack row striping synchronization for improved UI consistency
- Features (compose): add health status column and related functionality to stack and container views
- Features: add custom interval settings for compose stats and enhance nchan publisher
- Bug Fixes (composeStats): enhance memory value parsing and sanitize docker stats fields
- Performance (compose): throttle dockerload cache paints during websocket bursts
- Performance (compose): avoid full-table applyListView during progressive row inserts
- Performance (compose): debounce composeListRefreshed during progressive row load
- Performance: implement parallel project loading with request queuing and progress tracking
- [PR #120](https://github.com/mstrhakr/compose_plugin/pull/120)
- [beta release diff](https://github.com/mstrhakr/compose_plugin/compare/v2026.06.06...v2026.06.18.1637)
</CHANGES>

<!-- The 'pre-install' script. -->
Expand Down
Empty file modified deploy.sh
100644 → 100755
Empty file.
10 changes: 10 additions & 0 deletions docs/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ Each stack supports the following actions:
| **Edit Stack** | Open the stack editor |
| **Remove Stack** | Delete the stack configuration |

### Checking for Updates

Use **Check Updates** on a stack to query the registry for newer image versions. Results are cached until the next manual or scheduled check (see [Update Checking settings](configuration.md#update-checking)).

When updates are available, clicking **Update Stack** opens a confirmation dialog listing each container alongside its current and incoming image digest. Containers that are already up to date are dimmed.

#### Changelogs

If the [docker.versions](https://github.com/phyzical/docker.versions) Unraid plugin is installed, a **Changelog** link appears below the digest for each container with a pending update. Clicking it opens the release notes for that image in a modal. No configuration is required — Compose Manager detects docker.versions automatically.

## Autostart

Enable autostart to have stacks start automatically when the Unraid array starts.
Expand Down
2 changes: 1 addition & 1 deletion source/compose.manager/Compose.page
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Title="Docker Compose"
Tag="fa-cubes"
Code="f1b3"
Lock="true"
Nchan="docker_load"
Nchan="compose_info"
Cond="$var['fsState'] == 'Started' && exec('/etc/rc.d/rc.docker status | grep -v \"not\"') && exec(\"grep '^SHOW_COMPOSE_IN_HEADER_MENU=' /boot/config/plugins/compose.manager/compose.manager.cfg 2>/dev/null | grep 'true'\")"
---
<link type="text/css" rel="stylesheet" href="<?php autov('/webGui/styles/jquery.switchbutton.css'); ?>">
Expand Down
2 changes: 1 addition & 1 deletion source/compose.manager/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
**Compose Manager Plus**
**Compose Manager Plus (Beta)**

A plugin for unRAID that installs Docker Compose and adds a management interface to the web UI.
2 changes: 1 addition & 1 deletion source/compose.manager/compose.manager.page
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Title="Compose"
Type="php"
Menu="Docker:2"
Lock="true"
Nchan="docker_load"
Nchan="compose_info"
Cond="$var['fsState'] == 'Started' && exec('/etc/rc.d/rc.docker status | grep -v \"not\"') && (!file_exists('/boot/config/plugins/compose.manager/compose.manager.cfg') ? true : exec(\"grep '^SHOW_COMPOSE_IN_HEADER_MENU=' /boot/config/plugins/compose.manager/compose.manager.cfg 2>/dev/null | grep -v 'true'\"))"
---
<?php
Expand Down
33 changes: 33 additions & 0 deletions source/compose.manager/compose.manager.settings.page
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,12 @@ $acePath = file_exists('/usr/local/emhttp/plugins/dynamix/javascript/ace/ace.js'
$('#AUTO_CHECK_UPDATES_DAYS').prop('disabled', !autoCheckEnabled);
}

function toggleComposeStatsCustomInterval() {
var mode = ($('#COMPOSE_STATS_RATE_MODE').val() || 'live').toLowerCase();
var isCustom = mode === 'custom';
$('#COMPOSE_STATS_CUSTOM_INTERVAL_MS').prop('disabled', !isCustom);
}

$(function() {
// Keep the initial states to determine if a safety confirmation is needed on save
var origDisableActionWarnings = $('#DISABLE_ACTION_WARNINGS').is(':checked');
Expand Down Expand Up @@ -980,6 +986,10 @@ $acePath = file_exists('/usr/local/emhttp/plugins/dynamix/javascript/ace/ace.js'
toggleExpandByDefault();
$('#STACKS_DEFAULT_EXPANDED').change(toggleExpandByDefault);

// Enable custom interval only when the custom preset is selected.
toggleComposeStatsCustomInterval();
$('#COMPOSE_STATS_RATE_MODE').on('change', toggleComposeStatsCustomInterval);

// Apply compose on top on load and on change
toggleComposeOnTop();
$('#SHOW_COMPOSE_IN_HEADER_MENU').change(toggleComposeOnTop);
Expand Down Expand Up @@ -2123,6 +2133,29 @@ $acePath = file_exists('/usr/local/emhttp/plugins/dynamix/javascript/ace/ace.js'
</dd>
</dl>

<dl>
<dt style="cursor: help;" onclick="toggleHelp(this)">_(Live Stats Update Rate)_:</dt>
<dd>
<label>
<select name="COMPOSE_STATS_RATE_MODE" id="COMPOSE_STATS_RATE_MODE" style="min-width:180px;">
<?php $statsRateMode = strtolower(trim((string)($cfg['COMPOSE_STATS_RATE_MODE'] ?? 'live'))); ?>
<option value="live" <?= $statsRateMode === 'live' ? 'selected' : '' ?>>_(Live (max updates))_</option>
<option value="medium" <?= $statsRateMode === 'medium' ? 'selected' : '' ?>>_(Medium (~2s))_</option>
<option value="slow" <?= $statsRateMode === 'slow' ? 'selected' : '' ?>>_(Slow (~5s))_</option>
<option value="custom" <?= $statsRateMode === 'custom' ? 'selected' : '' ?>>_(Custom)_</option>
</select>
</label>
<label style="margin-left:12px;">
_(Custom interval)_:
<input type="number" name="COMPOSE_STATS_CUSTOM_INTERVAL_MS" id="COMPOSE_STATS_CUSTOM_INTERVAL_MS" min="100" max="10000" step="50" value="<?= intval($cfg['COMPOSE_STATS_CUSTOM_INTERVAL_MS'] ?? '1000') ?>" style="width:90px;"> _(ms)_
</label>
<blockquote class="inline_help">
Controls how often Compose live metrics are published.<br>
Live publishes each stream update, Medium uses ~2 seconds, Slow uses ~5 seconds, and Custom uses the interval in milliseconds.
</blockquote>
</dd>
</dl>

<?php if (!$option_patch_ui): ?>
<dl>
<dt style="cursor: help;" onclick="toggleHelp(this)">_(Patch Docker Page)_:</dt>
Expand Down
3 changes: 3 additions & 0 deletions source/compose.manager/default.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ AUTOSTART_TIMEOUT="300"
AUTOSTART_WAIT_FOR_DOCKER="false"
AUTOSTART_DOCKER_WAIT_TIMEOUT="120"
RUN_IN_BACKGROUND_DEFAULT="false"
REMOVE_ORPHANS_DEFAULT="false"
DISABLE_ACTION_WARNINGS="false"
NEW_STACK_USE_DEFAULT_COMPOSE_FILES="false"
NEW_STACK_OVERRIDE_MANAGEMENT_AUTOMATIC="true"
Expand All @@ -26,3 +27,5 @@ BACKUP_SCHEDULE_TIME="03:00"
BACKUP_SCHEDULE_DAY="1"
STACKS_DEFAULT_EXPANDED="false"
ONLY_EXPAND_RUNNING_STACKS="false"
COMPOSE_STATS_RATE_MODE="live"
COMPOSE_STATS_CUSTOM_INTERVAL_MS="1000"
Loading