Conversation
Bumps the bundled Nextcloud image from 33.0.8 to 34.0.3, crossing the major from the 33 series to 34. The 33 line has not moved since 33.0.8, so 34.0.3 is the only upstream release available. nextcloud:34.0.3-apache is published for amd64 and arm64. Postgres and Valkey track floating majors and are unchanged; Nextcloud 34's system requirements still list PostgreSQL 17 as supported. Nextcloud 34 adds appstore, files_lock and office to core/shipped.json's defaultEnabled, and appstore to alwaysEnabled. The preserved-defaults list in the Disable Non-default Apps action is a hand-maintained mirror of that file, so all three are added. appstore in particular is load-bearing: occ app:disable exits non-zero on an alwaysEnabled app and the action runs under execFail, so without it the action would throw. UPDATING.md documented only a patch bump. It now records the four extra checks a major needs, which is what this bump had to do by hand. Release notes describe the Nextcloud 34 feature set rather than the 34.0.1-34.0.3 point fixes: every one of those was backported to the 33 line too, so a user arriving from 33.0.8 already has them. Does not merge as-is. An install still on 32.0.11:0 is offered this update, migrates through the version graph, and then fails init on the one-major-at-a-time guard. See the PR description.
This was referenced Aug 21, 2026
Closed
The 34 release notes point users at Disable Non-default Apps, and a major upgrade is the event that leaves an app disabled but on disk. Both paths were built for the quieter case. Disable Non-default Apps ran every occ app:disable concurrently under execFail, so the first non-zero exit rejected Promise.all and withTemp destroyed the subcontainer under the still-running siblings — and the "these were disabled" report was never returned. occ app:disable runs the app's own uninstall repair steps, so a fataling app is both the likeliest one to fail and the reason the action was run. Disables now run one at a time through exec, and the result reports what was disabled and what was not. Reading the enabled-app list moved into readEnabledApps, which tolerates a PHP notice ahead of occ's JSON and a missing `enabled` key rather than dying with a bare SyntaxError or TypeError. talk-turn decided Talk was usable from the presence of custom_apps/spreed. occ registers an app's command namespace only while the app is enabled, and occ upgrade disables any app without a release for the new major, so after a major upgrade the check passed while talk:turn:add did not exist: allOk stayed false, the signature was never recorded, and the relay silently stopped being applied while every chain build retried. It now reads the enabled set. hasNextcloudApp keeps its presence semantics for the App Commands prechecks, which must work with the service stopped. The one-major-at-a-time guard named the problem but not the remedy. The Marketplace version list still offers the intermediate releases, so the message and the release notes now spell out the two-step update. Closes #127 Closes #128
Nextcloud's default trashbin_retention_obligation is `auto`: keep a deleted file at least 30 days, then remove it only as disk space is needed. On a server with room to spare nothing ever triggers that second condition, so trash accumulates for the life of the instance with no way to bound it from StartOS. Adds it to the Configure action as a preset list writing `auto, <days>` for 7 through 365, plus the Nextcloud default and `disabled`. Only the maximum is offered — Nextcloud's `D1, D2` form also sets a guaranteed minimum, which would hold files past the cap the user picked. Also corrects the Nextcloud 34 release note for the new Office section. The shipped `office` app is a document overview page, not an editor, and it opens files in whatever office suite is configured — of which this package bundles none. Closes #63
MattDHill
approved these changes
Aug 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps the bundled Nextcloud image from 33.0.8 to 34.0.3, releasing as StartOS version 34.0.3:0, and hardens the two recovery paths that a major upgrade drives traffic to.
The 33 line has not moved since 33.0.8 (33.0.8 is the newest
33.x.y-apachetag on Docker Hub), so 34.0.3 is the only upstream release available. This is a major bump, 33 → 34.The 32.x cohort
An install still on
32.0.11:0is offered this update, and it cannot succeed. Measured, not inferred:32.0.11:0is still inotherVersionson both the beta and production registries, and is inother[]atstartos/versions/index.ts:8for exactly that reason. It is where a StartOS 0.3.5.x carry-over lands.VersionGraphfrom the installed SDK against this branch:canMigrateFromis>=32.0.11:0 && <=34.0.3:0, and32.0.11:0satisfies it. StartOS accepts the hop and the Updates page offers it.$OC_VersionCanBeUpgradedFrominv34.0.3/version.phpis{33.0, 34.0}. Nextcloud genuinely refuses 32 → 34.startos/init/bootstrapNextcloud.ts:165therefore throws:image[0]is 34,installed[0] + 1is 33.The user downloads the update, StartOS snapshots the volumes, init fails, and the whole thing rolls back. Data is safe — the guard is doing its job.
The remedy is a two-step update, and it exists in the product today. The Marketplace listing renders a version picker over
best+otherVersions(shared-libs/ts-modules/marketplace/src/components/preview.component.tsversions$→about.component.ts→MarketplaceVersionsComponent), andMarketplaceControlsComponentrenders Update for whichever version is selected once it is newer than the installed one.33.0.8:3stays indexed — it is the newest:Nof its(flavor, upstream)group, so pruning never touches it. So a 32.x user picks 33.0.8:3 from the version list, updates, and then updates again to 34.0.3:0.Nothing pointed them there, so this branch does:
Why the version graph is left alone
Raising the floor is possible — a
33.0.5:0anchor withup: IMPOSSIBLE(33.0.5:0 being the oldest 33.x release) yields>=33.0.5:0 && <=34.0.3:0, with every 33.x revision still reachable andv33.0.8_2'smigrateFrom035xstill running for all of them. Verified by executing the graph. Droppingv_32_0_11_0on its own does the opposite, widening the range to<=34.0.3:0, because the floor is set by the lowest vertex whoseupisIMPOSSIBLE.It would be the right change if the registry published
canMigrateFrom. It does not:PackageVersionInfo::from_s9pksetssource_version: None, // TODO(shared-libs/crates/start-core/src/registry/package/index.rs:155), and the live production response for this package confirms it —"sourceVersion": null. That leaves inert both the registry's ownsource_versionfilter (registry/package/get.rs:180) andupdates-refinement.service.ts, the UI machinery built to refetch a reachable version whenbestis not one. So the 32.x user would still be offered 34.0.3:0, and the failure would move from this package's clear domain message toservice_map.rs's unsatisfiabletarget_range(prev_can_migrate_to ∧ next_can_migrate_from)→uninit target range … is unsatisfiable — no version can satisfy it (host contract violation).A worse message for the same outcome. Revisit once the registry publishes
sourceVersion— at that point the floor makes StartOS route the 32.x cohort to 33.0.8:3 by itself.Why 34 is worth taking now
Five earlier 34.x PRs (#110, #111, #112, #113, #114, #123) were closed. Two things named in #123 as reasons to wait have since resolved:
lib/private/Preview/IMagickSupport.phpatv34.0.3is byte-identical tov33.0.8— PDF, SVG, TIFF, HEIC and PSD previews are back, via the magic-byte-checking re-enable (server#62620).33.0.8:3is now the registry'sbest, so the ordinary cohort is one major below 34.The bump
nextcloud.Dockerfile—NEXTCLOUD_VERSION33.0.8 → 34.0.3, per UPDATING.md. The upstreamnextcloud/docker33→34 apache Dockerfile diff is onlyphp:8.4-apache-trixie→php:8.5-apache-trixieplus the version and tarball-URL lines; same Debian trixie base, so theffmpeglayer and thea2enconf startos-proxy-keepalivelayer are unaffected, andentrypoint.shis byte-identical.nextcloud:34.0.3-apacheresolves on Docker Hub foramd64andarm64(pushed 2026-08-17).startos/actions/maintenance/disableUnstableApps.ts— addsappstore,files_lockandoffice. That is exactlycore/shipped.json'sdefaultEnableddelta betweenv33.0.8andv34.0.3(nothing removed).appstoreis load-bearing: 34 also adds it toalwaysEnabled, andAppManager::disableAppthrows on an always-enabled app soDisable.phpsetsexitCode = 2.startos/versions/current.ts— version and release notes, five locales.UPDATING.md— the Nextcloud section documented only a patch bump. It now records the four checks a major needs.package-lock.json— refreshes thefilebrowser-startos#nextpin (c35ff45→ed12408). One line;package.jsonunchanged.@start9labs/start-sdkis already at 2.0.9 (npm latest), so there is no SDK bump.Every
occcommand the package invokes was diffed betweenv33.0.8andv34.0.3: only#[\Override]attributes,declare(strict_types=1), and an unrelated new--no-passwordoption onuser:resetpassword.occ statusstill emitsinstalledandneedsDbUpgrade;core/register_command.phpgains two background-job commands and removes none. Every keystartos/fileModels/config.php.tsmodels is still inv34.0.3'sconfig.sample.php— the key-set diff is additions only, plus a removal ofmount_file, which the package does not model.The hardening
Both are pre-existing, and both are worst exactly on the instances this release sends to them.
Disable Non-default Appsno longer aborts on the first failure (closes #127). It fanned everyocc app:disableout underPromise.all+execFail, so one non-zero exit rejected the lot andwithTemp'sfinally { destroy() }tore the subcontainer down under the still-running siblings — and thedisabledAppsreport was never returned, leaving a bareExitError.occ app:disableruns the app's own uninstall repair steps, so a fataling app is simultaneously the likeliest one to fail and the reason the action was run at all. Disables now run one at a time throughexec, and the result reports what was disabled and, separately, what was not.Reading the enabled-app list moved into
readEnabledAppsinutils.ts, which slices from the first{(a PHP startup or deprecation notice on stdout ahead of occ's JSON otherwise givesSyntaxError: Unexpected token 'P') and tolerates a missingenabledkey instead ofObject.keys(undefined).Note the concurrency hazard here is the timeout and the teardown, not lost writes:
AppManager::disableAppwrites enablement tooc_appconfigin Postgres, not toconfig.php.talk-turnnow checks that Talk is enabled, not merely present (closes #128). It decided Talk was usable from the presence ofcustom_apps/spreed.OC\Console\Application::loadCommandsiteratesgetEnabledApps(), andUpdater::checkAppsRequirementscallsdisableApp($app, true)on every app without a release for the new major while leaving its files in place — so after a major upgrade the check passed whiletalk:turn:adddid not exist.allOkstayed false,talkTurnConfiguredwas never recorded, and the relay silently stopped being applied while every chain build retried. Of the 457 apps with a Nextcloud 33 release, 63 have no 34 release.hasNextcloudAppkeeps its presence semantics for the three App Commands prechecks: those areallowedStatuses: 'any', so they must work with Postgres down, and their failure mode is an explicit failed-task notification rather than a silent retry.Version file
current.tsis edited in place.33.0.8:3carriesup: async () => {}, so there is no migration to strand and no reason to spin it intoother[]. Confirmed by executing the graph before and after:v33.0.8_2.ts'sclearTask+migrateFrom035xstill runs for32.0.11:0,33.0.5:0,33.0.7:0,33.0.8:0and33.0.8:1, and is still correctly skipped for:2and:3.34.0.3:0is unpublished (registrybestis33.0.8:3).Release notes
They describe Nextcloud 34's feature set, not the 34.0.1–34.0.3 point fixes — every fix in those point releases was backported to the 33 line as well, so a user arriving from
33.0.8:3already has them. Verified pairwise against the upstream release bodies:server#63020(34.0.3)server#63019(33.0.8)server#62924(34.0.3)server#62923(33.0.8)server#62620(34.0.3)server#62619(33.0.8)server#61182(34.0.1)server#61183(33.0.6)server#62130(34.0.2)server#62129(33.0.7)The recovery-path bullet names the Disable Non-default Apps action, and each locale quotes that action's own dictionary entry verbatim (
startos/i18n/dictionaries/translations.tskey 28) rather than a fresh translation.Issues filed while reviewing, and their outcome
service/mod.rs:810) and restore installs from that exact file (backup/restore.rs:219-225), so the restored code and the restored database always agree. The recover dialog also refuses a package that is already installed. There is no path by which a 32.x backup lands on a package shipping Nextcloud 34.versionRangecannot follow the#quantumflavor) — closed, already handled.filebrowser-quantum-startosdeclares.satisfies('2.63.23:0')for exactly this, and StartOS checks a dependency's aliases as well as its version (dep-error.service.ts:129-130).^2.62.2:1is satisfied by2.63.23:0, so the dependency resolves after a flavor switch. Quantum also chowns itsdatavolume to1000:1000, which is what the idmap mount inmain.tsrequires.Left as-is
core/shipped.json. Across v32.0.11, v33.0.8 and v34.0.3 the 58-entry literal is exactlyshippedApps∪{calendar, contacts}with no drift, andocc app:list --shipped=true --output=jsonwould collapse it to one exec. Worth doing, but not under a major bump — getting it wrong fails silently on the recovery action itself.files_lockis now preserved, and it is also an app-store app on 33. A user who installed it from the store carries a 33-era copy; after this upgrade it is exactly the kind of app that can break the UI, and the recovery action will now skip it. Excluding it would instead disable an app Nextcloud 34 ships enabled by default.Not verified
No
make, no s9pk pack, no VM install, and specifically no 33 → 34 upgrade exercised end to end. This crosses a major and runs a database schema change; it wants a real upgrade run before it goes out.npm run checkandnpx prettier --checkare green.Full upstream changelogs: 34.0.0 · 34.0.1 · 34.0.2 · 34.0.3
Merge with a merge commit — do not squash.
nextis long-lived: a merge commit leaves it a true ancestor ofmaster, so it fast-forwards cleanly afterwards.