Releases: heyvaldemar/modernuo-docker
Release list
v1.3.5
Changed
-
MODERNUO_REFmoves from0.15.6.178to0.15.6.198. The one upstream
release in between; its notes name spawner and network changes and nothing
about saves, persistence or configuration, and the deployment verification
exercises a world save on the new build before this ships. The save
layout this template documents for 0.15.6.178 is unchanged. -
The freshness check has its own workflow, Pin Freshness. It ran inside Deployment Verification, whose badge is the one at the top of this README. Across the fleet, nine red runs in ten were a pin one version behind - which the fleet's triage moves within the day - and a reader cannot tell that from a stack that does not boot. The badge now says whether the stack boots. The job itself is unchanged.
v1.3.4
Security
alpine:3.22was rebuilt upstream; the pin moved fromsha256:365499d9dccb…tosha256:5291449c3df7…. Same version, same tag, a rebuilt base image — the usual shape of a security fix in a base layer.
Upgrading
git pull (or ./update.sh), then docker compose up -d. Containers on a refreshed image are recreated; data volumes and .env are untouched. This release was cut by fleet triage after the deploy job booted the stack on the refreshed images.
Full history in CHANGELOG.md.
v1.3.3
Security
alpine:3.22was rebuilt upstream; the pin moved fromsha256:14358309a308…tosha256:365499d9dccb…. Same version, same tag, a rebuilt base image — the usual shape of a security fix in a base layer.
Upgrading
git pull (or ./update.sh), then docker compose up -d. Containers on a refreshed image are recreated; data volumes and .env are untouched. This release was cut by fleet triage after the deploy job booted the stack on the refreshed images.
Full history in CHANGELOG.md.
v1.3.2
On 1.3.1, every world save failed. This fixes it, migrates your world, and rescues one that got stranded.
What broke
ModernUO 0.15.6.178 publishes a save by renaming: it writes Saves.next, sets Saves aside, then renames the staged directory into place. Release 1.3.1 moved this template onto that version and kept ./data mounted at /app/Saves. A mount point cannot be renamed.
Measured on a live shard forty seconds after the upgrade: the set-aside fell back to moving the contents out file by file, which emptied the host directory, and the rename into place failed because the mount point still existed. Every save failed from then on, once a minute. The only complete copy of the world sat in /app/Saves.next inside the container's writable layer, which the next docker compose up discards.
The container stayed healthy. The port stayed open. The player count stayed normal. Nothing on the host said a word.
What changes
The mount is the parent now, ./data:/app/World, and world.savePath is World/Saves. Your world lives at ./data/Saves/.
An init service runs before the shard on every start. It moves a world found at the root of ./data into Saves/, rewrites world.savePath in config/modernuo.json, writes a minimal configuration on a fresh deployment, refuses if both layouts hold a world, and changes nothing on a second run.
The health check asked one question, is the process up, and a server that cannot write its world down answers yes. It now also requires the save on disk to be newer than MODERNUO_SAVE_MAX_AGE minutes, twenty by default.
tools/world-stats.sh misread the save index from version 5 on, reporting 148836781 items and no types for a world of 174 thousand. Unknown versions are refused rather than guessed.
If you ran 1.3.1
Before you pull, check whether a save is stranded in the running container:
docker exec modernuo test -d /app/Saves.next && echo "a staged save is stranded in the container"./update.sh copies it out to data/Saves/ itself before recreating anything. By hand:
mkdir -p data/Saves && docker cp modernuo:/app/Saves.next/. data/Saves/Proven without a shard
A full shard cannot boot in CI, so the save cycle is not observed there. Everything the fix rests on is: a mount point cannot be renamed and a directory inside one can; the init step on every layout it can meet; the health check against fresh, stale and absent saves and no process; the index reader on v4, v5 and a version it must refuse. Nineteen assertions, negative cases included.
Upgrading: ./update.sh. The migration is automatic; the rescue above runs first if it is needed.
v1.3.1
ModernUO 0.15.6.178.
The freshness check reported this lag every day and fleet triage could not apply it, correctly reporting it as needing a person. This repository pins a git ref and builds ModernUO from source rather than pulling a published image, so there is no digest to swap and nothing for the automatic path to rewrite.
The proof that the new ref is good is the same proof as for any other release here: the build and boot in CI, which ran before this went out.
Upgrading: ./update.sh, or set MODERNUO_REF=0.15.6.178 in .env and rebuild.
v1.3.0
Added
update.sh: move between release tags on purpose. It updates to the latest release (a combination this repository's CI has booted and smoke-tested), refuses to cross a major version unattended, refuses to run over local changes, and names any new required variable before anything has moved.--dry-runsays what would happen.- A Trivy scan of the image this repository builds. There is no upstream
image to pin a digest to — the shard is compiled here — so the scan builds
what the repository actually ships and looks at that, rather than at somebody
else's work.
Upgrading
git pull (or ./update.sh). Nothing running changes: this release adds or extends the update script and touches no image pin.
Full history in CHANGELOG.md.
v1.2.0
Fixed
- The health check could not go red.
pgrep -f ModernUOmatches the command
line of the shell running it, so it is satisfied by its own text and returns
success on a container with nothing running at all. Measured against the
runtime base image: unbracketed it is green on an empty container, bracketed
it is red.[M]odernUOis the same pattern and does not match itself. - And the obvious alternative could never go green. ModernUO is a .NET
application, so the onlycommin the container isdotnet: a check for
ModernUOin/proc/*/commreturns 1 every time, including on a perfectly
healthy shard.
Added
- A pinned default revision.
MODERNUO_REFdefaulted tomain, immediately
under a comment warning thatmainquietly changes what you get between two
builds of the same file. It now defaults to the 0.15.6.145 release, and the
image tag follows it, so a running container says which shard code it is. - Resource limits. The number matters more here than in most places: .NET's
garbage collector expands to fill whatever it is offered, so the ceiling is
what tells it when to stop. A shard measured over months peaked at 8.7 GB with
4.4 GB resident under a 12 GB limit; 4 GB is the shipped starting point. - A stop grace period, and a warning next to it. ModernUO does not save on
shutdown — measured, 639 saves before a stop and 639 after — so a restart
discards everything newer than the last autosave. The grace period does not
fix that; only a short autosave interval does. It is there so an in-flight
save is not cut in half. tty: false, deliberately. A TTY switches ModernUO to coloured output and
the escape codes land between the fields of every log line, so anything
reading those logs — a fail2ban filter, a login-attempt watcher, a grep —
silently matches nothing.- Four end-to-end assertions proving the health check both can and cannot
fire, run in CI.
v1.1.0 — ModernUO 0.15.6.145
ModernUO bumped 0.15.6.119 → 0.15.6.145, flagged by the weekly release-drift check. CI rebuilt the image from the new release and verified the binary boots with its native dependencies before this shipped.
Upgrading: git pull && docker compose build && docker compose up -d. Saves in ./data and configuration in ./config are untouched; back up ./data first as always before moving the shard to a new build.
v1.0.0 — verified build-and-boot pipeline
First tagged release. CI now proves on every push that the image builds from the pinned ModernUO release and that the published binary actually starts under the runtime image — reaching the client-data stage, which is exactly where a broken runtime dies when the native libdeflate/libargon2 fix is missing. The UO client files are proprietary and deliberately not in this repository, so a full shard cannot boot in CI; everything up to that line is verified.
A weekly job compares the pinned MODERNUO_REF against the latest upstream release — the CI twin of the bundled uowatch.
Upgrading: git pull && docker compose build && docker compose up -d. Your saves in ./data and configuration in ./config are untouched.